The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7827
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === From what I've tested and understand, the `ExecInstance` function can be called with a boolean `Interactive` flag. * When the flag is on : * `stderr` and `stdout` are both merged to a `stdout` reader (so there is no way to know the source) * unix signals can be sent to the process * When the flag is off : * `stderr` and `stdout` are kept separated using two distinct readers * unix signals are received, but not executed So since, I would like to keep `stderr` and `stdout` separated AND the ability to send signals to the running process, I've added some code to handle the signals in the non-interactive case.
From dfdef9e7c3dd17b1d48c85ae6eba35186f84056b Mon Sep 17 00:00:00 2001 From: Pierre Gleize <gleize.pie...@gmail.com> Date: Fri, 28 Aug 2020 11:29:17 -0700 Subject: [PATCH] Handle signals in non-interactive sessions. --- lxd/instance_exec.go | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/lxd/instance_exec.go b/lxd/instance_exec.go index da59162df3..a1959a14b7 100644 --- a/lxd/instance_exec.go +++ b/lxd/instance_exec.go @@ -336,6 +336,72 @@ func (s *execWs) Do(op *operations.Operation) error { } }(i) } + wgEOF.Add(1) + go func() { + defer wgEOF.Done() + + logger.Debug("Non-Interactive child process handler started") + defer logger.Debug("Non-Interactive child process handler finished") + + select { + case <-s.controlConnected: + break + case <-controlExit: + return + } + + for { + s.connsLock.Lock() + conn := s.conns[-1] + s.connsLock.Unlock() + + mt, r, err := conn.NextReader() + if mt == websocket.CloseMessage { + break + } + + if err != nil { + logger.Debug("Got error getting next reader", log.Ctx{"err": err}) + er, ok := err.(*websocket.CloseError) + if !ok { + break + } + + if er.Code != websocket.CloseAbnormalClosure { + break + } + + // If an abnormal closure occurred, kill the attached child. + err := cmd.Signal(unix.SIGKILL) + if err != nil { + logger.Debug("Failed to send SIGKILL signal", log.Ctx{"err": err}) + } else { + logger.Debug("Sent SIGKILL signal") + } + return + } + + buf, err := ioutil.ReadAll(r) + if err != nil { + logger.Debug("Failed to read message", log.Ctx{"err": err}) + break + } + + command := api.InstanceExecControl{} + + if err := json.Unmarshal(buf, &command); err != nil { + logger.Debug("Failed to unmarshal control socket command", log.Ctx{"err": err}) + continue + } + if command.Command == "signal" { + err := cmd.Signal(unix.Signal(command.Signal)) + if err != nil { + logger.Debug("Failed forwarding signal", log.Ctx{"err": err, "signal": command.Signal}) + continue + } + } + } + }() } exitCode, err := cmd.Wait()
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel