MCPcopy Create free account
hub / github.com/containerd/cgroups / fallbackKill

Method fallbackKill

cgroup2/manager.go:444–498  ·  view source on GitHub ↗

fallbackKill is a slower fallback to the more modern (kernels 5.14+) approach of writing to the cgroup.kill file. This is heavily pulled from runc's same approach (in signalAllProcesses), with the only differences being this is just tailored to the API exposed in this library, and we don't need to c

()

Source from the content-addressed store, hash-verified

442//
443// https://github.com/opencontainers/runc/blob/8da0a0b5675764feaaaaad466f6567a9983fcd08/libcontainer/init_linux.go#L523-L529
444func (c *Manager) fallbackKill() error {
445 logger := log.G(context.TODO()).WithFields(log.Fields{"path": c.path})
446
447 if err := c.Freeze(); err != nil {
448 logger.WithError(err).Warn("freezing cgroup2.manager")
449 }
450 pids, err := c.Procs(true)
451 if err != nil {
452 if err := c.Thaw(); err != nil {
453 logger.WithError(err).Warn("thawing cgroup2.manager")
454 }
455 return err
456 }
457 var procs []*os.Process
458 for _, pid := range pids {
459 p, err := os.FindProcess(int(pid))
460 if err != nil {
461 logger.WithFields(log.Fields{"error": err, "pid": int(pid)}).Warnf("finding process")
462 continue
463 }
464 procs = append(procs, p)
465 if err := p.Signal(unix.SIGKILL); err != nil {
466 logger.WithFields(log.Fields{"error": err, "pid": int(pid)}).Warnf("signaling process")
467 }
468 }
469 if err := c.Thaw(); err != nil {
470 logger.WithError(err).Warn("thawing cgroup2.manager")
471 }
472
473 subreaper, err := getSubreaper()
474 if err != nil {
475 // The error here means that PR_GET_CHILD_SUBREAPER is not
476 // supported because this code might run on a kernel older
477 // than 3.4. We don't want to throw an error in that case,
478 // and we simplify things, considering there is no subreaper
479 // set.
480 subreaper = 0
481 }
482
483 for _, p := range procs {
484 // In case a subreaper has been setup, this code must not
485 // wait for the process. Otherwise, we cannot be sure the
486 // current process will be reaped by the subreaper, while
487 // the subreaper might be waiting for this process in order
488 // to retrieve its exit code.
489 if subreaper == 0 {
490 if _, err := p.Wait(); err != nil {
491 if !errors.Is(err, unix.ECHILD) {
492 logger.WithFields(log.Fields{"error": err, "pid": p.Pid}).Warn("waiting on process")
493 }
494 }
495 }
496 }
497 return nil
498}
499
500func (c *Manager) Delete() error {
501 // Kernel prevents cgroups with running process from being removed,

Callers 1

KillMethod · 0.95

Calls 4

FreezeMethod · 0.95
ProcsMethod · 0.95
ThawMethod · 0.95
getSubreaperFunction · 0.85

Tested by

no test coverage detected