[lxc-devel] [lxd/master] lxd-agent: Fixes bug when agent not seen as started if LXD restarted

tomponline on Github lxc-bot at linuxcontainers.org
Mon Jan 20 12:57:49 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 483 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200120/a87b4b2a/attachment.bin>
-------------- next part --------------
From 641045749556335c355fc385c7f0a47f5ca7f1fc Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jan 2020 12:56:39 +0000
Subject: [PATCH] lxd-agent: Fixes bug when agent not seen as started if LXD
 restarted

Periodically repopulates STARTED status into vserial ringbuffer so LXD can restablish agent status after LXD restarts.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd-agent/main_agent.go | 62 +++++++++++++++++++++++++++++++----------
 1 file changed, 48 insertions(+), 14 deletions(-)

diff --git a/lxd-agent/main_agent.go b/lxd-agent/main_agent.go
index b93abf837e..3a6aaf9fa9 100644
--- a/lxd-agent/main_agent.go
+++ b/lxd-agent/main_agent.go
@@ -1,9 +1,12 @@
 package main
 
 import (
+	"context"
+	"fmt"
 	"os"
 	"os/signal"
 	"path/filepath"
+	"time"
 
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
@@ -97,25 +100,56 @@ func (c *cmdAgent) Run(cmd *cobra.Command, args []string) error {
 	// Prepare the HTTP server.
 	httpServer := restServer(tlsConfig, cert, c.global.flagLogDebug, d)
 
-	// Serial notification.
+	// Create a cancellation context.
+	ctx, cancelFunc := context.WithCancel(context.Background())
+
+	// Start status notifier in background.
+	go c.startStatusNotifier(ctx)
+
+	// Cancel context when SIGTEM is received.
+	chSignal := make(chan os.Signal, 1)
+	signal.Notify(chSignal, unix.SIGTERM)
+	go func() {
+		<-chSignal
+		cancelFunc()
+		os.Exit(0)
+	}()
+
+	// Start the server.
+	return httpServer.ServeTLS(networkTLSListener(l, tlsConfig), "agent.crt", "agent.key")
+}
+
+// startStatusNotifier sends status of agent to vserial ring buffer every 10s or when context is done.
+func (c *cmdAgent) startStatusNotifier(ctx context.Context) {
+	ticker := time.NewTicker(time.Duration(time.Second) * 10)
+	defer ticker.Stop()
+
+	// Write initial started status.
+	c.writeStatus("STARTED")
+
+	for {
+		select {
+		case <-ticker.C:
+			// Re-populate status periodically in case LXD restarts.
+			c.writeStatus("STARTED")
+		case <-ctx.Done():
+			// Indicate we are stopping to LXD.
+			c.writeStatus("STOPPED")
+			return
+		}
+	}
+}
+
+// writeStatus writes a status code to the vserial ring buffer used to detect agent status on host.
+func (c *cmdAgent) writeStatus(status string) error {
 	if shared.PathExists("/dev/virtio-ports/org.linuxcontainers.lxd") {
 		vSerial, err := os.OpenFile("/dev/virtio-ports/org.linuxcontainers.lxd", os.O_RDWR, 0600)
 		if err != nil {
 			return err
 		}
-		defer vSerial.Close()
-
-		vSerial.Write([]byte("STARTED\n"))
-
-		chSignal := make(chan os.Signal, 1)
-		signal.Notify(chSignal, unix.SIGTERM)
-		go func() {
-			<-chSignal
-			vSerial.Write([]byte("STOPPED\n"))
-			os.Exit(0)
-		}()
+		vSerial.Write([]byte(fmt.Sprintf("%s\n", status)))
+		vSerial.Close()
 	}
 
-	// Start the server.
-	return httpServer.ServeTLS(networkTLSListener(l, tlsConfig), "agent.crt", "agent.key")
+	return nil
 }


More information about the lxc-devel mailing list