Create kernel.SendExternalSignalProcessGroup and use it in boot/loader.go

This will send a signal to all processes (ThreadGroups) in a ProcessGroup.

PiperOrigin-RevId: 555679773
This commit is contained in:
Nicolas Lacasse
2023-08-10 15:37:22 -07:00
committed by gVisor bot
parent a6c3a61c29
commit 2f93ddbe62
2 changed files with 25 additions and 11 deletions
+22
View File
@@ -1213,6 +1213,7 @@ func (k *Kernel) SendExternalSignal(info *linux.SignalInfo, context string) {
}
// SendExternalSignalThreadGroup injects a signal into an specific ThreadGroup.
//
// This function doesn't skip signals like SendExternalSignal does.
func (k *Kernel) SendExternalSignalThreadGroup(tg *ThreadGroup, info *linux.SignalInfo) error {
k.extMu.Lock()
@@ -1220,6 +1221,27 @@ func (k *Kernel) SendExternalSignalThreadGroup(tg *ThreadGroup, info *linux.Sign
return tg.SendSignal(info)
}
// SendExternalSignalProcessGroup sends a signal to all ThreadGroups in the
// given process group.
//
// This function doesn't skip signals like SendExternalSignal does.
func (k *Kernel) SendExternalSignalProcessGroup(pg *ProcessGroup, info *linux.SignalInfo) error {
k.extMu.Lock()
defer k.extMu.Unlock()
// If anything goes wrong, we'll return the error, but still try our
// best to deliver to other processes in the group.
var firstErr error
for _, tg := range k.TaskSet().Root.ThreadGroups() {
if tg.ProcessGroup() != pg {
continue
}
if err := tg.SendSignal(info); err != nil && firstErr == nil {
firstErr = err
}
}
return firstErr
}
// SendContainerSignal sends the given signal to all processes inside the
// namespace that match the given container ID.
func (k *Kernel) SendContainerSignal(cid string, info *linux.SignalInfo) error {
+3 -11
View File
@@ -1414,23 +1414,15 @@ func (l *Loader) signalForegrondProcessGroup(cid string, tgid kernel.ThreadID, s
return fmt.Errorf("no TTY attached")
}
pg := tty.ForegroundProcessGroup()
si := &linux.SignalInfo{Signo: signo}
if pg == nil {
// No foreground process group has been set. Signal the
// original thread group.
log.Warningf("No foreground process group for container %q and PID %d. Sending signal directly to PID %d.", cid, tgid, tgid)
return l.k.SendExternalSignalThreadGroup(tg, &linux.SignalInfo{Signo: signo})
return l.k.SendExternalSignalThreadGroup(tg, si)
}
// Send the signal to all processes in the process group.
var lastErr error
for _, tg := range l.k.TaskSet().Root.ThreadGroups() {
if tg.ProcessGroup() != pg {
continue
}
if err := l.k.SendExternalSignalThreadGroup(tg, &linux.SignalInfo{Signo: signo}); err != nil {
lastErr = err
}
}
return lastErr
return l.k.SendExternalSignalProcessGroup(pg, si)
}
// signalAllProcesses that belong to specified container. It's a noop if the