[lxc-devel] [lxd/master] Add the ability to send unix signal to a non-interactive exec session.

gleize on Github lxc-bot at linuxcontainers.org
Fri Aug 28 22:12:41 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 933 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200828/04d7bdae/attachment.bin>
-------------- next part --------------
From dfdef9e7c3dd17b1d48c85ae6eba35186f84056b Mon Sep 17 00:00:00 2001
From: Pierre Gleize <gleize.pierre at 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()


More information about the lxc-devel mailing list