[lxc-devel] [lxd/master] Transition to golang.org/x/sys/{unix, windows}

monstermunchkin on Github lxc-bot at linuxcontainers.org
Mon Jun 3 19:22:42 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 319 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190603/c096edd0/attachment-0001.bin>
-------------- next part --------------
From 20b12ae6850da8650656358a201c6948a9c7c430 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 3 Jun 2019 16:56:28 +0200
Subject: [PATCH 1/5] lxc-to-lxd: Transition to golang.org/x/sys

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxc-to-lxd/utils.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxc-to-lxd/utils.go b/lxc-to-lxd/utils.go
index 6dcae9feec..2fc01926ec 100644
--- a/lxc-to-lxd/utils.go
+++ b/lxc-to-lxd/utils.go
@@ -5,9 +5,9 @@ import (
 	"encoding/pem"
 	"fmt"
 	"strings"
-	"syscall"
 
 	"golang.org/x/crypto/ssh/terminal"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/migration"
@@ -172,13 +172,13 @@ func setupSource(path string, mounts []string) error {
 		target := fmt.Sprintf("%s/%s", path, strings.TrimPrefix(mount, prefix))
 
 		// Mount the path
-		err := syscall.Mount(mount, target, "none", syscall.MS_BIND, "")
+		err := unix.Mount(mount, target, "none", unix.MS_BIND, "")
 		if err != nil {
 			return fmt.Errorf("Failed to mount %s: %v", mount, err)
 		}
 
 		// Make it read-only
-		err = syscall.Mount("", target, "none", syscall.MS_BIND|syscall.MS_RDONLY|syscall.MS_REMOUNT, "")
+		err = unix.Mount("", target, "none", unix.MS_BIND|unix.MS_RDONLY|unix.MS_REMOUNT, "")
 		if err != nil {
 			return fmt.Errorf("Failed to make %s read-only: %v", mount, err)
 		}

From d4363f590b42187021374a6666fa9b1d2d773077 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 3 Jun 2019 19:47:42 +0200
Subject: [PATCH 2/5] lxc: Transition to golang.org/x/sys

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxc/config.go          |   8 +--
 lxc/config_metadata.go |   4 +-
 lxc/config_template.go |   4 +-
 lxc/console_unix.go    |   4 +-
 lxc/exec.go            |  33 ++---------
 lxc/exec_unix.go       | 131 +++++++++++++++++++++++------------------
 lxc/exec_windows.go    |  35 ++++++++---
 lxc/file.go            |   3 +-
 lxc/image.go           |   3 +-
 lxc/main_aliases.go    |   5 +-
 lxc/network.go         |   5 +-
 lxc/profile.go         |   5 +-
 lxc/project.go         |   5 +-
 lxc/storage.go         |   5 +-
 lxc/storage_volume.go  |   5 +-
 lxc/utils_unix.go      |  28 +++++++++
 lxc/utils_windows.go   |  30 ++++++++++
 17 files changed, 189 insertions(+), 124 deletions(-)
 create mode 100644 lxc/utils_unix.go
 create mode 100644 lxc/utils_windows.go

diff --git a/lxc/config.go b/lxc/config.go
index 47c860caa4..0693b1799b 100644
--- a/lxc/config.go
+++ b/lxc/config.go
@@ -5,10 +5,10 @@ import (
 	"io/ioutil"
 	"os"
 	"strings"
-	"syscall"
 	"time"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 	"gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd/client"
@@ -152,7 +152,7 @@ func (c *cmdConfigEdit) Run(cmd *cobra.Command, args []string) error {
 		}
 
 		// If stdin isn't a terminal, read text from it
-		if !termios.IsTerminal(int(syscall.Stdin)) {
+		if !termios.IsTerminal(int(unix.Stdin)) {
 			contents, err := ioutil.ReadAll(os.Stdin)
 			if err != nil {
 				return err
@@ -298,7 +298,7 @@ func (c *cmdConfigEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(int(unix.Stdin)) {
 		contents, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return err
@@ -500,7 +500,7 @@ func (c *cmdConfigSet) Run(cmd *cobra.Command, args []string) error {
 		key := args[len(args)-2]
 		value := args[len(args)-1]
 
-		if !termios.IsTerminal(int(syscall.Stdin)) && value == "-" {
+		if !termios.IsTerminal(int(unix.Stdin)) && value == "-" {
 			buf, err := ioutil.ReadAll(os.Stdin)
 			if err != nil {
 				return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
diff --git a/lxc/config_metadata.go b/lxc/config_metadata.go
index 1ab558ba91..c59a740721 100644
--- a/lxc/config_metadata.go
+++ b/lxc/config_metadata.go
@@ -4,9 +4,9 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
-	"syscall"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 	"gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd/shared"
@@ -103,7 +103,7 @@ func (c *cmdConfigMetadataEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Edit the metadata
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(int(unix.Stdin)) {
 		metadata := api.ImageMetadata{}
 		content, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
diff --git a/lxc/config_template.go b/lxc/config_template.go
index cc52f90e26..a5a627f99c 100644
--- a/lxc/config_template.go
+++ b/lxc/config_template.go
@@ -6,10 +6,10 @@ import (
 	"io/ioutil"
 	"os"
 	"sort"
-	"syscall"
 
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
 	cli "github.com/lxc/lxd/shared/cmd"
@@ -177,7 +177,7 @@ func (c *cmdConfigTemplateEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Edit container file template
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(int(unix.Stdin)) {
 		return resource.server.UpdateContainerTemplateFile(resource.name, args[1], os.Stdin)
 	}
 
diff --git a/lxc/console_unix.go b/lxc/console_unix.go
index ad9a3272fa..c7516a64ab 100644
--- a/lxc/console_unix.go
+++ b/lxc/console_unix.go
@@ -6,9 +6,9 @@ import (
 	"io"
 	"os"
 	"os/signal"
-	"syscall"
 
 	"github.com/gorilla/websocket"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared/logger"
 )
@@ -19,7 +19,7 @@ func (c *cmdConsole) getStdout() io.WriteCloser {
 
 func (c *cmdConsole) controlSocketHandler(control *websocket.Conn) {
 	ch := make(chan os.Signal, 10)
-	signal.Notify(ch, syscall.SIGWINCH)
+	signal.Notify(ch, unix.SIGWINCH)
 
 	for {
 		sig := <-ch
diff --git a/lxc/exec.go b/lxc/exec.go
index b0b87ad26f..db041b921f 100644
--- a/lxc/exec.go
+++ b/lxc/exec.go
@@ -9,7 +9,6 @@ import (
 	"os"
 	"strconv"
 	"strings"
-	"syscall"
 
 	"github.com/gorilla/websocket"
 	"github.com/spf13/cobra"
@@ -59,7 +58,7 @@ Mode defaults to non-interactive, interactive mode is selected if both stdin AND
 }
 
 func (c *cmdExec) sendTermSize(control *websocket.Conn) error {
-	width, height, err := termios.GetSize(int(syscall.Stdout))
+	width, height, err := termios.GetSize(getStdoutFd())
 	if err != nil {
 		return err
 	}
@@ -87,28 +86,6 @@ func (c *cmdExec) sendTermSize(control *websocket.Conn) error {
 	return err
 }
 
-func (c *cmdExec) forwardSignal(control *websocket.Conn, sig syscall.Signal) error {
-	logger.Debugf("Forwarding signal: %s", sig)
-
-	w, err := control.NextWriter(websocket.TextMessage)
-	if err != nil {
-		return err
-	}
-
-	msg := api.ContainerExecControl{}
-	msg.Command = "signal"
-	msg.Signal = int(sig)
-
-	buf, err := json.Marshal(msg)
-	if err != nil {
-		return err
-	}
-	_, err = w.Write(buf)
-
-	w.Close()
-	return err
-}
-
 func (c *cmdExec) Run(cmd *cobra.Command, args []string) error {
 	conf := c.global.conf
 
@@ -154,8 +131,8 @@ func (c *cmdExec) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Configure the terminal
-	stdinFd := int(syscall.Stdin)
-	stdoutFd := int(syscall.Stdout)
+	stdinFd := getStdinFd()
+	stdoutFd := getStdoutFd()
 
 	stdinTerminal := termios.IsTerminal(stdinFd)
 	stdoutTerminal := termios.IsTerminal(stdoutFd)
@@ -192,7 +169,7 @@ func (c *cmdExec) Run(cmd *cobra.Command, args []string) error {
 	// Grab current terminal dimensions
 	var width, height int
 	if stdoutTerminal {
-		width, height, err = termios.GetSize(int(syscall.Stdout))
+		width, height, err = termios.GetSize(getStdoutFd())
 		if err != nil {
 			return err
 		}
@@ -204,7 +181,7 @@ func (c *cmdExec) Run(cmd *cobra.Command, args []string) error {
 		stdin = ioutil.NopCloser(bytes.NewReader(nil))
 	}
 
-	stdout := c.getStdout()
+	stdout := getStdout()
 
 	// Prepare the command
 	req := api.ContainerExecPost{
diff --git a/lxc/exec_unix.go b/lxc/exec_unix.go
index 0c93028974..47ebc690f6 100644
--- a/lxc/exec_unix.go
+++ b/lxc/exec_unix.go
@@ -3,20 +3,17 @@
 package main
 
 import (
-	"io"
+	"encoding/json"
 	"os"
 	"os/signal"
-	"syscall"
 
 	"github.com/gorilla/websocket"
+	"golang.org/x/sys/unix"
 
+	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
 )
 
-func (c *cmdExec) getStdout() io.WriteCloser {
-	return os.Stdout
-}
-
 func (c *cmdExec) getTERM() (string, bool) {
 	return os.LookupEnv("TERM")
 }
@@ -24,19 +21,19 @@ func (c *cmdExec) getTERM() (string, bool) {
 func (c *cmdExec) controlSocketHandler(control *websocket.Conn) {
 	ch := make(chan os.Signal, 10)
 	signal.Notify(ch,
-		syscall.SIGWINCH,
-		syscall.SIGTERM,
-		syscall.SIGHUP,
-		syscall.SIGINT,
-		syscall.SIGQUIT,
-		syscall.SIGABRT,
-		syscall.SIGTSTP,
-		syscall.SIGTTIN,
-		syscall.SIGTTOU,
-		syscall.SIGUSR1,
-		syscall.SIGUSR2,
-		syscall.SIGSEGV,
-		syscall.SIGCONT)
+		unix.SIGWINCH,
+		unix.SIGTERM,
+		unix.SIGHUP,
+		unix.SIGINT,
+		unix.SIGQUIT,
+		unix.SIGABRT,
+		unix.SIGTSTP,
+		unix.SIGTTIN,
+		unix.SIGTTOU,
+		unix.SIGUSR1,
+		unix.SIGUSR2,
+		unix.SIGSEGV,
+		unix.SIGCONT)
 
 	closeMsg := websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
 	defer control.WriteMessage(websocket.CloseMessage, closeMsg)
@@ -44,95 +41,95 @@ func (c *cmdExec) controlSocketHandler(control *websocket.Conn) {
 	for {
 		sig := <-ch
 		switch sig {
-		case syscall.SIGWINCH:
+		case unix.SIGWINCH:
 			logger.Debugf("Received '%s signal', updating window geometry.", sig)
 			err := c.sendTermSize(control)
 			if err != nil {
 				logger.Debugf("error setting term size %s", err)
 				return
 			}
-		case syscall.SIGTERM:
+		case unix.SIGTERM:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGTERM)
+			err := c.forwardSignal(control, unix.SIGTERM)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTERM)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGTERM)
 				return
 			}
-		case syscall.SIGHUP:
+		case unix.SIGHUP:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGHUP)
+			err := c.forwardSignal(control, unix.SIGHUP)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGHUP)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGHUP)
 				return
 			}
-		case syscall.SIGINT:
+		case unix.SIGINT:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGINT)
+			err := c.forwardSignal(control, unix.SIGINT)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGINT)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGINT)
 				return
 			}
-		case syscall.SIGQUIT:
+		case unix.SIGQUIT:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGQUIT)
+			err := c.forwardSignal(control, unix.SIGQUIT)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGQUIT)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGQUIT)
 				return
 			}
-		case syscall.SIGABRT:
+		case unix.SIGABRT:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGABRT)
+			err := c.forwardSignal(control, unix.SIGABRT)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGABRT)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGABRT)
 				return
 			}
-		case syscall.SIGTSTP:
+		case unix.SIGTSTP:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGTSTP)
+			err := c.forwardSignal(control, unix.SIGTSTP)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTSTP)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGTSTP)
 				return
 			}
-		case syscall.SIGTTIN:
+		case unix.SIGTTIN:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGTTIN)
+			err := c.forwardSignal(control, unix.SIGTTIN)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTTIN)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGTTIN)
 				return
 			}
-		case syscall.SIGTTOU:
+		case unix.SIGTTOU:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGTTOU)
+			err := c.forwardSignal(control, unix.SIGTTOU)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTTOU)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGTTOU)
 				return
 			}
-		case syscall.SIGUSR1:
+		case unix.SIGUSR1:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGUSR1)
+			err := c.forwardSignal(control, unix.SIGUSR1)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGUSR1)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGUSR1)
 				return
 			}
-		case syscall.SIGUSR2:
+		case unix.SIGUSR2:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGUSR2)
+			err := c.forwardSignal(control, unix.SIGUSR2)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGUSR2)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGUSR2)
 				return
 			}
-		case syscall.SIGSEGV:
+		case unix.SIGSEGV:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGSEGV)
+			err := c.forwardSignal(control, unix.SIGSEGV)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGSEGV)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGSEGV)
 				return
 			}
-		case syscall.SIGCONT:
+		case unix.SIGCONT:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGCONT)
+			err := c.forwardSignal(control, unix.SIGCONT)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGCONT)
+				logger.Debugf("Failed to forward signal '%s'.", unix.SIGCONT)
 				return
 			}
 		default:
@@ -140,3 +137,25 @@ func (c *cmdExec) controlSocketHandler(control *websocket.Conn) {
 		}
 	}
 }
+
+func (c *cmdExec) forwardSignal(control *websocket.Conn, sig unix.Signal) error {
+	logger.Debugf("Forwarding signal: %s", sig)
+
+	w, err := control.NextWriter(websocket.TextMessage)
+	if err != nil {
+		return err
+	}
+
+	msg := api.ContainerExecControl{}
+	msg.Command = "signal"
+	msg.Signal = int(sig)
+
+	buf, err := json.Marshal(msg)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(buf)
+
+	w.Close()
+	return err
+}
diff --git a/lxc/exec_windows.go b/lxc/exec_windows.go
index 9dd67cea54..0e405b5f31 100644
--- a/lxc/exec_windows.go
+++ b/lxc/exec_windows.go
@@ -3,14 +3,15 @@
 package main
 
 import (
+	"encoding/json"
 	"io"
 	"os"
 	"os/signal"
-	"syscall"
 
 	"github.com/gorilla/websocket"
-	"github.com/mattn/go-colorable"
+	"golang.org/x/sys/windows"
 
+	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -25,10 +26,6 @@ func (wwc *WrappedWriteCloser) Write(p []byte) (int, error) {
 	return wwc.wrapper.Write(p)
 }
 
-func (c *cmdExec) getStdout() io.WriteCloser {
-	return &WrappedWriteCloser{os.Stdout, colorable.NewColorableStdout()}
-}
-
 func (c *cmdExec) getTERM() (string, bool) {
 	return "dumb", true
 }
@@ -45,9 +42,9 @@ func (c *cmdExec) controlSocketHandler(control *websocket.Conn) {
 		switch sig {
 		case os.Interrupt:
 			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
-			err := c.forwardSignal(control, syscall.SIGINT)
+			err := c.forwardSignal(control, windows.SIGINT)
 			if err != nil {
-				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGINT)
+				logger.Debugf("Failed to forward signal '%s'.", windows.SIGINT)
 				return
 			}
 		default:
@@ -55,3 +52,25 @@ func (c *cmdExec) controlSocketHandler(control *websocket.Conn) {
 		}
 	}
 }
+
+func (c *cmdExec) forwardSignal(control *websocket.Conn, sig windows.Signal) error {
+	logger.Debugf("Forwarding signal: %s", sig)
+
+	w, err := control.NextWriter(websocket.TextMessage)
+	if err != nil {
+		return err
+	}
+
+	msg := api.ContainerExecControl{}
+	msg.Command = "signal"
+	msg.Signal = int(sig)
+
+	buf, err := json.Marshal(msg)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(buf)
+
+	w.Close()
+	return err
+}
diff --git a/lxc/file.go b/lxc/file.go
index b81869f482..16f670fbd3 100644
--- a/lxc/file.go
+++ b/lxc/file.go
@@ -10,7 +10,6 @@ import (
 	"path/filepath"
 	"strconv"
 	"strings"
-	"syscall"
 
 	"github.com/spf13/cobra"
 
@@ -139,7 +138,7 @@ func (c *cmdFileEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(getStdinFd()) {
 		return c.filePush.Run(cmd, append([]string{os.Stdin.Name()}, args[0]))
 	}
 
diff --git a/lxc/image.go b/lxc/image.go
index 8671a4fa52..b123afd034 100644
--- a/lxc/image.go
+++ b/lxc/image.go
@@ -11,7 +11,6 @@ import (
 	"regexp"
 	"sort"
 	"strings"
-	"syscall"
 
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
@@ -363,7 +362,7 @@ func (c *cmdImageEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(getStdinFd()) {
 		contents, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return err
diff --git a/lxc/main_aliases.go b/lxc/main_aliases.go
index e0810438b9..dc35a3140e 100644
--- a/lxc/main_aliases.go
+++ b/lxc/main_aliases.go
@@ -8,7 +8,6 @@ import (
 	"path"
 	"path/filepath"
 	"strings"
-	"syscall"
 
 	"github.com/lxc/lxd/lxc/config"
 	"github.com/lxc/lxd/shared"
@@ -127,8 +126,8 @@ func execIfAliases() error {
 	}
 
 	// Re-exec
-	environ := syscall.Environ()
+	environ := getEnviron()
 	environ = append(environ, "LXC_ALIASES=1")
-	ret := syscall.Exec(path, newArgs, environ)
+	ret := doExec(path, newArgs, environ)
 	return fmt.Errorf(i18n.G("Processing aliases failed: %s"), ret)
 }
diff --git a/lxc/network.go b/lxc/network.go
index 63dfeb8e8f..4111346962 100644
--- a/lxc/network.go
+++ b/lxc/network.go
@@ -8,7 +8,6 @@ import (
 	"os"
 	"sort"
 	"strings"
-	"syscall"
 
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
@@ -593,7 +592,7 @@ func (c *cmdNetworkEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(getStdinFd()) {
 		contents, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return err
@@ -1097,7 +1096,7 @@ func (c *cmdNetworkSet) Run(cmd *cobra.Command, args []string) error {
 	key := args[1]
 	value := args[2]
 
-	if !termios.IsTerminal(int(syscall.Stdin)) && value == "-" {
+	if !termios.IsTerminal(getStdinFd()) && value == "-" {
 		buf, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
diff --git a/lxc/profile.go b/lxc/profile.go
index d214d32fcf..26526bcb9b 100644
--- a/lxc/profile.go
+++ b/lxc/profile.go
@@ -8,7 +8,6 @@ import (
 	"os"
 	"sort"
 	"strings"
-	"syscall"
 
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
@@ -456,7 +455,7 @@ func (c *cmdProfileEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(getStdinFd()) {
 		contents, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return err
@@ -832,7 +831,7 @@ func (c *cmdProfileSet) Run(cmd *cobra.Command, args []string) error {
 	key := args[1]
 	value := args[2]
 
-	if !termios.IsTerminal(int(syscall.Stdin)) && value == "-" {
+	if !termios.IsTerminal(getStdinFd()) && value == "-" {
 		buf, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
diff --git a/lxc/project.go b/lxc/project.go
index 641305ce10..645778be5e 100644
--- a/lxc/project.go
+++ b/lxc/project.go
@@ -6,7 +6,6 @@ import (
 	"os"
 	"sort"
 	"strings"
-	"syscall"
 
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
@@ -260,7 +259,7 @@ func (c *cmdProjectEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(getStdinFd()) {
 		contents, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return err
@@ -555,7 +554,7 @@ func (c *cmdProjectSet) Run(cmd *cobra.Command, args []string) error {
 	key := args[1]
 	value := args[2]
 
-	if !termios.IsTerminal(int(syscall.Stdin)) && value == "-" {
+	if !termios.IsTerminal(getStdinFd()) && value == "-" {
 		buf, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
diff --git a/lxc/storage.go b/lxc/storage.go
index e28e13e2e8..0dc7e42a30 100644
--- a/lxc/storage.go
+++ b/lxc/storage.go
@@ -7,7 +7,6 @@ import (
 	"sort"
 	"strconv"
 	"strings"
-	"syscall"
 
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
@@ -258,7 +257,7 @@ func (c *cmdStorageEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(getStdinFd()) {
 		contents, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return err
@@ -626,7 +625,7 @@ func (c *cmdStorageSet) Run(cmd *cobra.Command, args []string) error {
 
 	// Read the value
 	value := args[2]
-	if !termios.IsTerminal(int(syscall.Stdin)) && value == "-" {
+	if !termios.IsTerminal(getStdinFd()) && value == "-" {
 		buf, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index d609949eb5..6cb1b5eb7d 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -7,7 +7,6 @@ import (
 	"sort"
 	"strconv"
 	"strings"
-	"syscall"
 
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
@@ -836,7 +835,7 @@ func (c *cmdStorageVolumeEdit) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// If stdin isn't a terminal, read text from it
-	if !termios.IsTerminal(int(syscall.Stdin)) {
+	if !termios.IsTerminal(getStdinFd()) {
 		contents, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return err
@@ -1327,7 +1326,7 @@ func (c *cmdStorageVolumeSet) Run(cmd *cobra.Command, args []string) error {
 	key := args[2]
 	value := args[3]
 
-	if !termios.IsTerminal(int(syscall.Stdin)) && value == "-" {
+	if !termios.IsTerminal(getStdinFd()) && value == "-" {
 		buf, err := ioutil.ReadAll(os.Stdin)
 		if err != nil {
 			return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
diff --git a/lxc/utils_unix.go b/lxc/utils_unix.go
new file mode 100644
index 0000000000..be0b59369b
--- /dev/null
+++ b/lxc/utils_unix.go
@@ -0,0 +1,28 @@
+package main
+
+import (
+	"io"
+	"os"
+
+	"golang.org/x/sys/unix"
+)
+
+func getStdout() io.WriteCloser {
+	return os.Stdout
+}
+
+func getStdoutFd() int {
+	return unix.Stdout
+}
+
+func getStdinFd() int {
+	return unix.Stdin
+}
+
+func getEnviron() []string {
+	return unix.Environ()
+}
+
+func doExec(argv0 string, argv []string, envv []string) error {
+	return unix.Exec(argv0, argv, envv)
+}
diff --git a/lxc/utils_windows.go b/lxc/utils_windows.go
new file mode 100644
index 0000000000..1045632dc2
--- /dev/null
+++ b/lxc/utils_windows.go
@@ -0,0 +1,30 @@
+package main
+
+import (
+	"errors"
+	"io"
+	"os"
+
+	"github.com/mattn/go-colorable"
+	"golang.org/x/sys/windows"
+)
+
+func getStdout() io.WriteCloser {
+	return &WrappedWriteCloser{os.Stdout, colorable.NewColorableStdout()}
+}
+
+func getStdoutFd() int {
+	return int(windows.Stdout)
+}
+
+func getStdinFd() int {
+	return int(windows.Stdin)
+}
+
+func getEnviron() []string {
+	return windows.Environ()
+}
+
+func doExec(argv0 string, argv []string, envv []string) error {
+	return errors.New("not supported by windows")
+}

From b3b90cfc2c6c1e992431cbdb04ccd0677d86fe7b Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 3 Jun 2019 20:14:24 +0200
Subject: [PATCH 3/5] lxd-p2c: Transition to golang.org/x/sys

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd-p2c/main_migrate.go | 4 ++--
 lxd-p2c/utils.go        | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/lxd-p2c/main_migrate.go b/lxd-p2c/main_migrate.go
index 239d9e357e..7b005013d9 100644
--- a/lxd-p2c/main_migrate.go
+++ b/lxd-p2c/main_migrate.go
@@ -7,9 +7,9 @@ import (
 	"os/exec"
 	"sort"
 	"strings"
-	"syscall"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxc/utils"
 	"github.com/lxc/lxd/shared/api"
@@ -94,7 +94,7 @@ func (c *cmdMigrate) Run(cmd *cobra.Command, args []string) error {
 
 	// Automatically clean-up the temporary path on exit
 	defer func(path string) {
-		syscall.Unmount(path, syscall.MNT_DETACH)
+		unix.Unmount(path, unix.MNT_DETACH)
 		os.Remove(path)
 	}(path)
 
diff --git a/lxd-p2c/utils.go b/lxd-p2c/utils.go
index 0dc44b2734..3903ad14d5 100644
--- a/lxd-p2c/utils.go
+++ b/lxd-p2c/utils.go
@@ -6,9 +6,9 @@ import (
 	"fmt"
 	"net/url"
 	"strings"
-	"syscall"
 
 	"golang.org/x/crypto/ssh/terminal"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/migration"
@@ -173,13 +173,13 @@ func setupSource(path string, mounts []string) error {
 		target := fmt.Sprintf("%s/%s", path, strings.TrimPrefix(mount, prefix))
 
 		// Mount the path
-		err := syscall.Mount(mount, target, "none", syscall.MS_BIND, "")
+		err := unix.Mount(mount, target, "none", unix.MS_BIND, "")
 		if err != nil {
 			return fmt.Errorf("Failed to mount %s: %v", mount, err)
 		}
 
 		// Make it read-only
-		err = syscall.Mount("", target, "none", syscall.MS_BIND|syscall.MS_RDONLY|syscall.MS_REMOUNT, "")
+		err = unix.Mount("", target, "none", unix.MS_BIND|unix.MS_RDONLY|unix.MS_REMOUNT, "")
 		if err != nil {
 			return fmt.Errorf("Failed to make %s read-only: %v", mount, err)
 		}

From 53490fbd43bb864cee871392758407ba5db12b8a Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 3 Jun 2019 20:30:48 +0200
Subject: [PATCH 4/5] lxd: Transition to golang.org/x/sys

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/container_console.go          |  12 ++--
 lxd/container_exec.go             |   8 +--
 lxd/container_lxc.go              |  34 ++++-----
 lxd/daemon.go                     |  14 ++--
 lxd/devices.go                    | 114 +++++++++++++++---------------
 lxd/devlxd_gc.go                  |   6 +-
 lxd/main_daemon.go                |  12 ++--
 lxd/main_forkexec.go              |   6 +-
 lxd/main_forkproxy.go             |  36 +++++-----
 lxd/main_forkstart.go             |   6 +-
 lxd/main_forkzfs.go               |   8 +--
 lxd/main_init_interactive.go      |   6 +-
 lxd/networks.go                   |   4 +-
 lxd/networks_utils.go             |   9 +--
 lxd/patches.go                    |  30 ++++----
 lxd/proxy_device_utils.go         |   5 +-
 lxd/rsync.go                      |   4 +-
 lxd/storage/quota/projectquota.go |   7 +-
 lxd/storage_btrfs.go              |  22 +++---
 lxd/storage_ceph.go               |  16 ++---
 lxd/storage_ceph_utils.go         |  18 ++---
 lxd/storage_dir.go                |   8 +--
 lxd/storage_lvm_utils.go          |  13 ++--
 lxd/storage_pools_config.go       |   7 +-
 lxd/storage_utils.go              |  55 +++++++-------
 lxd/storage_zfs.go                |   6 +-
 lxd/storage_zfs_utils.go          |  12 ++--
 lxd/util/fs.go                    |   6 +-
 lxd/util/http.go                  |   4 +-
 29 files changed, 246 insertions(+), 242 deletions(-)

diff --git a/lxd/container_console.go b/lxd/container_console.go
index e2741bc8ca..9914f50c4a 100644
--- a/lxd/container_console.go
+++ b/lxd/container_console.go
@@ -9,10 +9,10 @@ import (
 	"os/exec"
 	"strconv"
 	"sync"
-	"syscall"
 
 	"github.com/gorilla/mux"
 	"github.com/gorilla/websocket"
+	"golang.org/x/sys/unix"
 	"gopkg.in/lxc/go-lxc.v2"
 
 	"github.com/lxc/lxd/lxd/cluster"
@@ -148,7 +148,7 @@ func (s *consoleWs) Do(op *operation) error {
 			_, r, err := conn.NextReader()
 			if err != nil {
 				logger.Debugf("Got error getting next reader %s", err)
-				err := syscall.Kill(consolePid, syscall.SIGTERM)
+				err := unix.Kill(consolePid, unix.SIGTERM)
 				if err != nil {
 					logger.Debugf("Failed to send SIGTERM to pid %d", consolePid)
 				} else {
@@ -241,10 +241,10 @@ func (s *consoleWs) Do(op *operation) error {
 
 	exitErr, ok := err.(*exec.ExitError)
 	if ok {
-		status, _ := exitErr.Sys().(syscall.WaitStatus)
+		status, _ := exitErr.Sys().(unix.WaitStatus)
 		// If we received SIGTERM someone told us to detach from the
 		// console.
-		if status.Signaled() && status.Signal() == syscall.SIGTERM {
+		if status.Signaled() && status.Signal() == unix.SIGTERM {
 			return finisher(nil)
 		}
 	}
@@ -388,7 +388,7 @@ func containerConsoleLogGet(d *Daemon, r *http.Request) Response {
 			return SmartError(err)
 		}
 
-		if errno == syscall.ENODATA {
+		if errno == unix.ENODATA {
 			return FileResponse(r, []fileResponseEntry{ent}, nil, false)
 		}
 
@@ -451,7 +451,7 @@ func containerConsoleLogDelete(d *Daemon, r *http.Request) Response {
 			return SmartError(err)
 		}
 
-		if errno == syscall.ENODATA {
+		if errno == unix.ENODATA {
 			return SmartError(nil)
 		}
 
diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index 76159915d5..4c11f60b3a 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -11,10 +11,10 @@ import (
 	"strconv"
 	"strings"
 	"sync"
-	"syscall"
 
 	"github.com/gorilla/mux"
 	"github.com/gorilla/websocket"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/cluster"
 	"github.com/lxc/lxd/lxd/db"
@@ -183,7 +183,7 @@ func (s *execWs) Do(op *operation) error {
 					}
 
 					// If an abnormal closure occurred, kill the attached process.
-					err := syscall.Kill(attachedChildPid, syscall.SIGKILL)
+					err := unix.Kill(attachedChildPid, unix.SIGKILL)
 					if err != nil {
 						logger.Debugf("Failed to send SIGKILL to pid %d", attachedChildPid)
 					} else {
@@ -224,7 +224,7 @@ func (s *execWs) Do(op *operation) error {
 						continue
 					}
 				} else if command.Command == "signal" {
-					if err := syscall.Kill(attachedChildPid, syscall.Signal(command.Signal)); err != nil {
+					if err := unix.Kill(attachedChildPid, unix.Signal(command.Signal)); err != nil {
 						logger.Debugf("Failed forwarding signal '%d' to PID %d", command.Signal, attachedChildPid)
 						continue
 					}
@@ -323,7 +323,7 @@ func (s *execWs) Do(op *operation) error {
 
 	exitErr, ok := err.(*exec.ExitError)
 	if ok {
-		status, ok := exitErr.Sys().(syscall.WaitStatus)
+		status, ok := exitErr.Sys().(unix.WaitStatus)
 		if ok {
 			return finisher(status.ExitStatus(), nil)
 		}
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 0b1185f0a2..d48ca92494 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -18,11 +18,11 @@ import (
 	"strconv"
 	"strings"
 	"sync"
-	"syscall"
 	"time"
 
 	"github.com/flosch/pongo2"
 	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
 	"gopkg.in/lxc/go-lxc.v2"
 	"gopkg.in/yaml.v2"
 
@@ -2622,7 +2622,7 @@ func (c *containerLXC) startCommon() (string, error) {
 	}
 
 	// Unmount any previously mounted shiftfs
-	syscall.Unmount(c.RootfsPath(), syscall.MNT_DETACH)
+	unix.Unmount(c.RootfsPath(), unix.MNT_DETACH)
 
 	return configPath, nil
 }
@@ -4538,7 +4538,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
 				}
 			} else if key == "security.devlxd" {
 				if value == "" || shared.IsTrue(value) {
-					err = c.insertMount(shared.VarPath("devlxd"), "/dev/lxd", "none", syscall.MS_BIND)
+					err = c.insertMount(shared.VarPath("devlxd"), "/dev/lxd", "none", unix.MS_BIND)
 					if err != nil {
 						return err
 					}
@@ -6408,7 +6408,7 @@ func (c *containerLXC) Exec(command []string, env map[string]string, stdin *os.F
 	if err != nil {
 		exitErr, ok := err.(*exec.ExitError)
 		if ok {
-			status, ok := exitErr.Sys().(syscall.WaitStatus)
+			status, ok := exitErr.Sys().(unix.WaitStatus)
 			if ok {
 				return nil, status.ExitStatus(), attachedPid, nil
 			}
@@ -6731,7 +6731,7 @@ func (c *containerLXC) StorageStart() (bool, error) {
 
 	isOurOperation, err := c.StorageStartSensitive()
 	// Remove this as soon as zfs is fixed
-	if c.storage.GetStorageType() == storageTypeZfs && err == syscall.EBUSY {
+	if c.storage.GetStorageType() == storageTypeZfs && err == unix.EBUSY {
 		return isOurOperation, nil
 	}
 
@@ -6819,11 +6819,11 @@ func (c *containerLXC) insertMount(source, target, fstype string, flags int) err
 		defer os.Remove(tmpMount)
 
 		// Mount the filesystem
-		err = syscall.Mount(source, tmpMount, fstype, uintptr(flags), "")
+		err = unix.Mount(source, tmpMount, fstype, uintptr(flags), "")
 		if err != nil {
 			return fmt.Errorf("Failed to setup temporary mount: %s", err)
 		}
-		defer syscall.Unmount(tmpMount, syscall.MNT_DETACH)
+		defer unix.Unmount(tmpMount, unix.MNT_DETACH)
 
 		// Move the mount inside the container
 		mntsrc := filepath.Join("/dev/.lxd-mounts", filepath.Base(tmpMount))
@@ -6945,7 +6945,7 @@ func (c *containerLXC) createUnixDevice(prefix string, m types.Device, defaultMo
 		mode, err = shared.GetPathMode(srcPath)
 		if err != nil {
 			errno, isErrno := shared.GetErrno(err)
-			if !isErrno || errno != syscall.ENOENT {
+			if !isErrno || errno != unix.ENOENT {
 				return nil, fmt.Errorf("Failed to retrieve mode of device %s: %s", m["path"], err)
 			}
 			mode = os.FileMode(0660)
@@ -6953,9 +6953,9 @@ func (c *containerLXC) createUnixDevice(prefix string, m types.Device, defaultMo
 	}
 
 	if m["type"] == "unix-block" {
-		mode |= syscall.S_IFBLK
+		mode |= unix.S_IFBLK
 	} else {
-		mode |= syscall.S_IFCHR
+		mode |= unix.S_IFCHR
 	}
 
 	// Get the device owner
@@ -6995,7 +6995,7 @@ func (c *containerLXC) createUnixDevice(prefix string, m types.Device, defaultMo
 	// Create the new entry
 	if !c.state.OS.RunningInUserNS {
 		encoded_device_number := (minor & 0xff) | (major << 8) | ((minor & ^0xff) << 12)
-		if err := syscall.Mknod(devPath, uint32(mode), encoded_device_number); err != nil {
+		if err := unix.Mknod(devPath, uint32(mode), encoded_device_number); err != nil {
 			return nil, fmt.Errorf("Failed to create device %s for %s: %s", devPath, m["path"], err)
 		}
 
@@ -7050,7 +7050,7 @@ func (c *containerLXC) insertUnixDevice(prefix string, m types.Device, defaultMo
 	tgtPath := paths[1]
 
 	// Bind-mount it into the container
-	err = c.insertMount(devPath, tgtPath, "none", syscall.MS_BIND)
+	err = c.insertMount(devPath, tgtPath, "none", unix.MS_BIND)
 	if err != nil {
 		return fmt.Errorf("Failed to add mount for device: %s", err)
 	}
@@ -7181,7 +7181,7 @@ func (c *containerLXC) removeUnixDevice(prefix string, m types.Device, eject boo
 
 	// Remove the host side
 	if c.state.OS.RunningInUserNS {
-		syscall.Unmount(devPath, syscall.MNT_DETACH)
+		unix.Unmount(devPath, unix.MNT_DETACH)
 	}
 
 	err = os.Remove(devPath)
@@ -8480,9 +8480,9 @@ func (c *containerLXC) insertDiskDevice(name string, m types.Device) error {
 		return nil
 	}
 
-	flags := syscall.MS_BIND
+	flags := unix.MS_BIND
 	if isRecursive {
-		flags |= syscall.MS_REC
+		flags |= unix.MS_REC
 	}
 
 	// Bind-mount it into the container
@@ -8560,7 +8560,7 @@ func (c *containerLXC) removeDiskDevice(name string, m types.Device) error {
 	}
 
 	// Unmount the host side
-	err = syscall.Unmount(devPath, syscall.MNT_DETACH)
+	err = unix.Unmount(devPath, unix.MNT_DETACH)
 	if err != nil {
 		return err
 	}
@@ -8607,7 +8607,7 @@ func (c *containerLXC) removeDiskDevices() error {
 		}
 
 		// Always try to unmount the host side
-		_ = syscall.Unmount(filepath.Join(c.DevicesPath(), f.Name()), syscall.MNT_DETACH)
+		_ = unix.Unmount(filepath.Join(c.DevicesPath(), f.Name()), unix.MNT_DETACH)
 
 		// Remove the entry
 		diskPath := filepath.Join(c.DevicesPath(), f.Name())
diff --git a/lxd/daemon.go b/lxd/daemon.go
index d0bb44eff9..8e2b23bd6f 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -13,7 +13,6 @@ import (
 	"path/filepath"
 	"strings"
 	"sync"
-	"syscall"
 	"time"
 
 	"github.com/CanonicalLtd/candidclient"
@@ -21,6 +20,7 @@ import (
 	"github.com/gorilla/mux"
 	"github.com/pkg/errors"
 	"golang.org/x/net/context"
+	"golang.org/x/sys/unix"
 	"gopkg.in/lxc/go-lxc.v2"
 	"gopkg.in/macaroon-bakery.v2/bakery"
 	"gopkg.in/macaroon-bakery.v2/bakery/checkers"
@@ -474,13 +474,13 @@ func setupSharedMounts() error {
 	}
 
 	// Mount a new tmpfs
-	if err := syscall.Mount("tmpfs", path, "tmpfs", 0, "size=100k,mode=0711"); err != nil {
+	if err := unix.Mount("tmpfs", path, "tmpfs", 0, "size=100k,mode=0711"); err != nil {
 		return err
 	}
 
 	// Mark as MS_SHARED and MS_REC
-	var flags uintptr = syscall.MS_SHARED | syscall.MS_REC
-	if err := syscall.Mount(path, path, "none", flags, ""); err != nil {
+	var flags uintptr = unix.MS_SHARED | unix.MS_REC
+	if err := unix.Mount(path, path, "none", flags, ""); err != nil {
 		return err
 	}
 
@@ -652,7 +652,7 @@ func (d *Daemon) init() error {
 		// Attempt to Mount the devlxd tmpfs
 		devlxd := filepath.Join(d.os.VarDir, "devlxd")
 		if !shared.IsMountPoint(devlxd) {
-			syscall.Mount("tmpfs", devlxd, "tmpfs", 0, "size=100k,mode=0755")
+			unix.Mount("tmpfs", devlxd, "tmpfs", 0, "size=100k,mode=0755")
 		}
 	}
 
@@ -1082,8 +1082,8 @@ func (d *Daemon) Stop() error {
 	if shouldUnmount {
 		logger.Infof("Unmounting temporary filesystems")
 
-		syscall.Unmount(shared.VarPath("devlxd"), syscall.MNT_DETACH)
-		syscall.Unmount(shared.VarPath("shmounts"), syscall.MNT_DETACH)
+		unix.Unmount(shared.VarPath("devlxd"), unix.MNT_DETACH)
+		unix.Unmount(shared.VarPath("shmounts"), unix.MNT_DETACH)
 
 		logger.Infof("Done unmounting temporary filesystems")
 	} else {
diff --git a/lxd/devices.go b/lxd/devices.go
index 8c1cc51e4d..b7490635f9 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -18,10 +18,10 @@ import (
 	"sort"
 	"strconv"
 	"strings"
-	"syscall"
 	"unsafe"
 
 	"github.com/jaypipes/pcidb"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/sys"
@@ -433,8 +433,8 @@ func deviceLoadGpu(all bool) ([]gpuDevice, []nvidiaGpuDevice, error) {
 					minor, err := findNvidiaMinor(tmpGpu.pci)
 					if err == nil {
 						nvidiaPath := "/dev/nvidia" + minor
-						stat := syscall.Stat_t{}
-						err = syscall.Stat(nvidiaPath, &stat)
+						stat := unix.Stat_t{}
+						err = unix.Stat(nvidiaPath, &stat)
 						if err != nil {
 							if os.IsNotExist(err) {
 								continue
@@ -508,8 +508,8 @@ func deviceLoadGpu(all bool) ([]gpuDevice, []nvidiaGpuDevice, error) {
 			}
 
 			nvidiaPath := filepath.Join("/dev", nvidiaEnt.Name())
-			stat := syscall.Stat_t{}
-			err = syscall.Stat(nvidiaPath, &stat)
+			stat := unix.Stat_t{}
+			err = unix.Stat(nvidiaPath, &stat)
 			if err != nil {
 				continue
 			}
@@ -583,21 +583,21 @@ func deviceNetlinkListener() (chan []string, chan []string, chan usbDevice, erro
 	NETLINK_KOBJECT_UEVENT := 15
 	UEVENT_BUFFER_SIZE := 2048
 
-	fd, err := syscall.Socket(
-		syscall.AF_NETLINK, syscall.SOCK_RAW|syscall.SOCK_CLOEXEC,
+	fd, err := unix.Socket(
+		unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC,
 		NETLINK_KOBJECT_UEVENT,
 	)
 	if err != nil {
 		return nil, nil, nil, err
 	}
 
-	nl := syscall.SockaddrNetlink{
-		Family: syscall.AF_NETLINK,
+	nl := unix.SockaddrNetlink{
+		Family: unix.AF_NETLINK,
 		Pid:    uint32(os.Getpid()),
 		Groups: 1,
 	}
 
-	err = syscall.Bind(fd, &nl)
+	err = unix.Bind(fd, &nl)
 	if err != nil {
 		return nil, nil, nil, err
 	}
@@ -609,7 +609,7 @@ func deviceNetlinkListener() (chan []string, chan []string, chan usbDevice, erro
 	go func(chCPU chan []string, chNetwork chan []string, chUSB chan usbDevice) {
 		b := make([]byte, UEVENT_BUFFER_SIZE*2)
 		for {
-			r, err := syscall.Read(fd, b)
+			r, err := unix.Read(fd, b)
 			if err != nil {
 				continue
 			}
@@ -1101,14 +1101,14 @@ func deviceTaskSchedulerTrigger(srcType string, srcName string, srcStatus string
 
 func deviceIsBlockdev(path string) bool {
 	// Get a stat struct from the provided path
-	stat := syscall.Stat_t{}
-	err := syscall.Stat(path, &stat)
+	stat := unix.Stat_t{}
+	err := unix.Stat(path, &stat)
 	if err != nil {
 		return false
 	}
 
 	// Check if it's a block device
-	if stat.Mode&syscall.S_IFMT == syscall.S_IFBLK {
+	if stat.Mode&unix.S_IFMT == unix.S_IFBLK {
 		return true
 	}
 
@@ -1133,17 +1133,17 @@ func deviceModeOct(strmode string) (int, error) {
 
 func deviceGetAttributes(path string) (string, int, int, error) {
 	// Get a stat struct from the provided path
-	stat := syscall.Stat_t{}
-	err := syscall.Stat(path, &stat)
+	stat := unix.Stat_t{}
+	err := unix.Stat(path, &stat)
 	if err != nil {
 		return "", 0, 0, err
 	}
 
 	// Check what kind of file it is
 	dType := ""
-	if stat.Mode&syscall.S_IFMT == syscall.S_IFBLK {
+	if stat.Mode&unix.S_IFMT == unix.S_IFBLK {
 		dType = "b"
-	} else if stat.Mode&syscall.S_IFMT == syscall.S_IFCHR {
+	} else if stat.Mode&unix.S_IFMT == unix.S_IFCHR {
 		dType = "c"
 	} else {
 		return "", 0, 0, fmt.Errorf("Not a device")
@@ -1191,7 +1191,7 @@ func deviceMountDisk(srcPath string, dstPath string, readonly bool, recursive bo
 	// Prepare the mount flags
 	flags := 0
 	if readonly {
-		flags |= syscall.MS_RDONLY
+		flags |= unix.MS_RDONLY
 	}
 
 	// Detect the filesystem
@@ -1202,50 +1202,50 @@ func deviceMountDisk(srcPath string, dstPath string, readonly bool, recursive bo
 			return err
 		}
 	} else {
-		flags |= syscall.MS_BIND
+		flags |= unix.MS_BIND
 		if propagation != "" {
 			switch propagation {
 			case "private":
-				flags |= syscall.MS_PRIVATE
+				flags |= unix.MS_PRIVATE
 			case "shared":
-				flags |= syscall.MS_SHARED
+				flags |= unix.MS_SHARED
 			case "slave":
-				flags |= syscall.MS_SLAVE
+				flags |= unix.MS_SLAVE
 			case "unbindable":
-				flags |= syscall.MS_UNBINDABLE
+				flags |= unix.MS_UNBINDABLE
 			case "rprivate":
-				flags |= syscall.MS_PRIVATE | syscall.MS_REC
+				flags |= unix.MS_PRIVATE | unix.MS_REC
 			case "rshared":
-				flags |= syscall.MS_SHARED | syscall.MS_REC
+				flags |= unix.MS_SHARED | unix.MS_REC
 			case "rslave":
-				flags |= syscall.MS_SLAVE | syscall.MS_REC
+				flags |= unix.MS_SLAVE | unix.MS_REC
 			case "runbindable":
-				flags |= syscall.MS_UNBINDABLE | syscall.MS_REC
+				flags |= unix.MS_UNBINDABLE | unix.MS_REC
 			default:
 				return fmt.Errorf("Invalid propagation mode '%s'", propagation)
 			}
 		}
 
 		if recursive {
-			flags |= syscall.MS_REC
+			flags |= unix.MS_REC
 		}
 	}
 
 	// Mount the filesystem
-	if err = syscall.Mount(srcPath, dstPath, fstype, uintptr(flags), ""); err != nil {
+	if err = unix.Mount(srcPath, dstPath, fstype, uintptr(flags), ""); err != nil {
 		return fmt.Errorf("Unable to mount %s at %s: %s", srcPath, dstPath, err)
 	}
 
 	// Remount bind mounts in readonly mode if requested
-	if readonly == true && flags&syscall.MS_BIND == syscall.MS_BIND {
-		flags = syscall.MS_RDONLY | syscall.MS_BIND | syscall.MS_REMOUNT
-		if err = syscall.Mount("", dstPath, fstype, uintptr(flags), ""); err != nil {
+	if readonly == true && flags&unix.MS_BIND == unix.MS_BIND {
+		flags = unix.MS_RDONLY | unix.MS_BIND | unix.MS_REMOUNT
+		if err = unix.Mount("", dstPath, fstype, uintptr(flags), ""); err != nil {
 			return fmt.Errorf("Unable to mount %s in readonly mode: %s", dstPath, err)
 		}
 	}
 
-	flags = syscall.MS_REC | syscall.MS_SLAVE
-	if err = syscall.Mount("", dstPath, "", uintptr(flags), ""); err != nil {
+	flags = unix.MS_REC | unix.MS_SLAVE
+	if err = unix.Mount("", dstPath, "", uintptr(flags), ""); err != nil {
 		return fmt.Errorf("unable to make mount %s private: %s", dstPath, err)
 	}
 
@@ -1817,7 +1817,7 @@ func deviceInotifyInit(s *state.State) (int, error) {
 		return s.OS.InotifyWatch.Fd, nil
 	}
 
-	inFd, err := syscall.InotifyInit1(syscall.IN_CLOEXEC)
+	inFd, err := unix.InotifyInit1(unix.IN_CLOEXEC)
 	if err != nil {
 		logger.Errorf("Failed to initialize inotify")
 		return -1, err
@@ -1878,11 +1878,11 @@ func deviceInotifyAddTarget(s *state.State, path string) error {
 	}
 
 	mask := uint32(0)
-	mask |= syscall.IN_ONLYDIR
-	mask |= syscall.IN_CREATE
-	mask |= syscall.IN_DELETE
-	mask |= syscall.IN_DELETE_SELF
-	wd, err := syscall.InotifyAddWatch(inFd, path, mask)
+	mask |= unix.IN_ONLYDIR
+	mask |= unix.IN_CREATE
+	mask |= unix.IN_DELETE
+	mask |= unix.IN_DELETE_SELF
+	wd, err := unix.InotifyAddWatch(inFd, path, mask)
 	if err != nil {
 		return err
 	}
@@ -1905,13 +1905,13 @@ func deviceInotifyAddTarget(s *state.State, path string) error {
 
 func deviceInotifyDel(s *state.State) {
 	s.OS.InotifyWatch.Lock()
-	syscall.Close(s.OS.InotifyWatch.Fd)
+	unix.Close(s.OS.InotifyWatch.Fd)
 	s.OS.InotifyWatch.Fd = -1
 	s.OS.InotifyWatch.Unlock()
 }
 
 const LXD_BATCH_IN_EVENTS uint = 100
-const LXD_SINGLE_IN_EVENT_SIZE uint = (syscall.SizeofInotifyEvent + syscall.PathMax)
+const LXD_SINGLE_IN_EVENT_SIZE uint = (unix.SizeofInotifyEvent + unix.PathMax)
 const LXD_BATCH_IN_BUFSIZE uint = LXD_BATCH_IN_EVENTS * LXD_SINGLE_IN_EVENT_SIZE
 
 func deviceInotifyWatcher(s *state.State) (chan sys.InotifyTargetInfo, error) {
@@ -1919,9 +1919,9 @@ func deviceInotifyWatcher(s *state.State) (chan sys.InotifyTargetInfo, error) {
 	go func(target chan sys.InotifyTargetInfo) {
 		for {
 			buf := make([]byte, LXD_BATCH_IN_BUFSIZE)
-			n, errno := syscall.Read(s.OS.InotifyWatch.Fd, buf)
+			n, errno := unix.Read(s.OS.InotifyWatch.Fd, buf)
 			if errno != nil {
-				if errno == syscall.EINTR {
+				if errno == unix.EINTR {
 					continue
 				}
 
@@ -1929,18 +1929,18 @@ func deviceInotifyWatcher(s *state.State) (chan sys.InotifyTargetInfo, error) {
 				return
 			}
 
-			if n < syscall.SizeofInotifyEvent {
+			if n < unix.SizeofInotifyEvent {
 				continue
 			}
 
 			var offset uint32
-			for offset <= uint32(n-syscall.SizeofInotifyEvent) {
+			for offset <= uint32(n-unix.SizeofInotifyEvent) {
 				name := ""
-				event := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
+				event := (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset]))
 
 				nameLen := uint32(event.Len)
 				if nameLen > 0 {
-					bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
+					bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))
 					name = strings.TrimRight(string(bytes[0:nameLen]), "\000")
 				}
 
@@ -1950,7 +1950,7 @@ func deviceInotifyWatcher(s *state.State) (chan sys.InotifyTargetInfo, error) {
 					Wd:   int(event.Wd),
 				}
 
-				offset += (syscall.SizeofInotifyEvent + nameLen)
+				offset += (unix.SizeofInotifyEvent + nameLen)
 			}
 		}
 	}(targetChan)
@@ -1972,7 +1972,7 @@ func deviceInotifyDelWatcher(s *state.State, path string) error {
 		return nil
 	}
 
-	ret, err := syscall.InotifyRmWatch(s.OS.InotifyWatch.Fd, uint32(target.Wd))
+	ret, err := unix.InotifyRmWatch(s.OS.InotifyWatch.Fd, uint32(target.Wd))
 	if ret != 0 {
 		// When a file gets deleted the wd for that file will
 		// automatically be deleted from the inotify instance. So
@@ -1999,14 +1999,14 @@ func createAncestorPaths(cleanPath string) []string {
 }
 
 func deviceInotifyEvent(s *state.State, target *sys.InotifyTargetInfo) {
-	if (target.Mask & syscall.IN_ISDIR) > 0 {
-		if (target.Mask & syscall.IN_CREATE) > 0 {
+	if (target.Mask & unix.IN_ISDIR) > 0 {
+		if (target.Mask & unix.IN_CREATE) > 0 {
 			deviceInotifyDirCreateEvent(s, target)
-		} else if (target.Mask & syscall.IN_DELETE) > 0 {
+		} else if (target.Mask & unix.IN_DELETE) > 0 {
 			deviceInotifyDirDeleteEvent(s, target)
 		}
 		deviceInotifyDirRescan(s)
-	} else if (target.Mask & syscall.IN_DELETE_SELF) > 0 {
+	} else if (target.Mask & unix.IN_DELETE_SELF) > 0 {
 		deviceInotifyDirDeleteEvent(s, target)
 		deviceInotifyDirRescan(s)
 	} else {
@@ -2238,13 +2238,13 @@ func deviceInotifyFileEvent(s *state.State, target *sys.InotifyTargetInfo) {
 				continue
 			}
 
-			if (target.Mask & syscall.IN_CREATE) > 0 {
+			if (target.Mask & unix.IN_CREATE) > 0 {
 				err := c.insertUnixDevice(fmt.Sprintf("unix.%s", name), m, false)
 				if err != nil {
 					logger.Error("Failed to create unix device", log.Ctx{"err": err, "dev": m, "container": c.Name()})
 					continue
 				}
-			} else if (target.Mask & syscall.IN_DELETE) > 0 {
+			} else if (target.Mask & unix.IN_DELETE) > 0 {
 				err := c.removeUnixDevice(fmt.Sprintf("unix.%s", name), m, true)
 				if err != nil {
 					logger.Error("Failed to remove unix device", log.Ctx{"err": err, "dev": m, "container": c.Name()})
diff --git a/lxd/devlxd_gc.go b/lxd/devlxd_gc.go
index cbfd697667..82d600fa75 100644
--- a/lxd/devlxd_gc.go
+++ b/lxd/devlxd_gc.go
@@ -2,12 +2,10 @@
 
 package main
 
-import (
-	"syscall"
-)
+import "golang.org/x/sys/unix"
 
 func getUcred(fd int) (uint32, uint32, int32, error) {
-	cred, err := syscall.GetsockoptUcred(fd, syscall.SOL_SOCKET, syscall.SO_PEERCRED)
+	cred, err := unix.GetsockoptUcred(fd, unix.SOL_SOCKET, unix.SO_PEERCRED)
 	if err != nil {
 		return 0, 0, -1, err
 	}
diff --git a/lxd/main_daemon.go b/lxd/main_daemon.go
index d6b3b1c9ff..cb849149e4 100644
--- a/lxd/main_daemon.go
+++ b/lxd/main_daemon.go
@@ -5,9 +5,9 @@ import (
 	"os"
 	"os/exec"
 	"os/signal"
-	"syscall"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/sys"
 	"github.com/lxc/lxd/shared/logger"
@@ -64,15 +64,15 @@ func (c *cmdDaemon) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	ch := make(chan os.Signal)
-	signal.Notify(ch, syscall.SIGPWR)
-	signal.Notify(ch, syscall.SIGINT)
-	signal.Notify(ch, syscall.SIGQUIT)
-	signal.Notify(ch, syscall.SIGTERM)
+	signal.Notify(ch, unix.SIGPWR)
+	signal.Notify(ch, unix.SIGINT)
+	signal.Notify(ch, unix.SIGQUIT)
+	signal.Notify(ch, unix.SIGTERM)
 
 	s := d.State()
 	select {
 	case sig := <-ch:
-		if sig == syscall.SIGPWR {
+		if sig == unix.SIGPWR {
 			logger.Infof("Received '%s signal', shutting down containers", sig)
 			containersShutdown(s)
 			networkShutdown(s)
diff --git a/lxd/main_forkexec.go b/lxd/main_forkexec.go
index 74d8e8327b..515c782260 100644
--- a/lxd/main_forkexec.go
+++ b/lxd/main_forkexec.go
@@ -5,9 +5,9 @@ import (
 	"fmt"
 	"os"
 	"strings"
-	"syscall"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 	"gopkg.in/lxc/go-lxc.v2"
 )
 
@@ -120,8 +120,8 @@ func (c *cmdForkexec) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Handle exit code
-	var ws syscall.WaitStatus
-	wpid, err := syscall.Wait4(status, &ws, 0, nil)
+	var ws unix.WaitStatus
+	wpid, err := unix.Wait4(status, &ws, 0, nil)
 	if err != nil || wpid != status {
 		return fmt.Errorf("Failed finding process: %q", err)
 	}
diff --git a/lxd/main_forkproxy.go b/lxd/main_forkproxy.go
index 696953068f..4c08d817ee 100644
--- a/lxd/main_forkproxy.go
+++ b/lxd/main_forkproxy.go
@@ -9,11 +9,11 @@ import (
 	"strconv"
 	"strings"
 	"sync"
-	"syscall"
 	"time"
 	"unsafe"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/netutils"
@@ -493,7 +493,7 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	if C.whoami == C.FORKPROXY_CHILD {
-		defer syscall.Close(forkproxyUDSSockFDNum)
+		defer unix.Close(forkproxyUDSSockFDNum)
 
 		if lAddr.connType == "unix" && !lAddr.abstract {
 			err := os.Remove(lAddr.addr[0])
@@ -512,7 +512,7 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 			err = netutils.AbstractUnixSendFd(forkproxyUDSSockFDNum, int(file.Fd()))
 			if err != nil {
 				errno, ok := shared.GetErrno(err)
-				if ok && (errno == syscall.EAGAIN) {
+				if ok && (errno == unix.EAGAIN) {
 					goto sAgain
 				}
 				break
@@ -570,17 +570,17 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 		f, err := netutils.AbstractUnixReceiveFd(forkproxyUDSSockFDNum)
 		if err != nil {
 			errno, ok := shared.GetErrno(err)
-			if ok && (errno == syscall.EAGAIN) {
+			if ok && (errno == unix.EAGAIN) {
 				goto rAgain
 			}
 
 			fmt.Printf("Failed to receive fd from listener process: %v\n", err)
-			syscall.Close(forkproxyUDSSockFDNum)
+			unix.Close(forkproxyUDSSockFDNum)
 			return err
 		}
 		files = append(files, f)
 	}
-	syscall.Close(forkproxyUDSSockFDNum)
+	unix.Close(forkproxyUDSSockFDNum)
 
 	var listenerMap map[int]*lStruct
 
@@ -633,7 +633,7 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 
 	// Handle SIGTERM which is sent when the proxy is to be removed
 	sigs := make(chan os.Signal, 1)
-	signal.Notify(sigs, syscall.SIGTERM)
+	signal.Notify(sigs, unix.SIGTERM)
 
 	if lAddr.connType == "unix" && !lAddr.abstract {
 		defer os.Remove(lAddr.addr[0])
@@ -645,7 +645,7 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Wait for SIGTERM and close the listener in order to exit the loop below
-	self := syscall.Getpid()
+	self := unix.Getpid()
 	go func() {
 		<-sigs
 
@@ -653,7 +653,7 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 			C.epoll_ctl(epFd, C.EPOLL_CTL_DEL, C.int(f.Fd()), nil)
 			f.Close()
 		}
-		syscall.Close(int(epFd))
+		unix.Close(int(epFd))
 
 		if !isUDPListener {
 			for _, l := range listenerMap {
@@ -662,9 +662,9 @@ func (c *cmdForkproxy) Run(cmd *cobra.Command, args []string) error {
 			}
 		}
 
-		syscall.Kill(self, syscall.SIGKILL)
+		unix.Kill(self, unix.SIGKILL)
 	}()
-	defer syscall.Kill(self, syscall.SIGTERM)
+	defer unix.Kill(self, unix.SIGTERM)
 
 	for _, f := range files {
 		var ev C.struct_epoll_event
@@ -767,7 +767,7 @@ func proxyCopy(dst net.Conn, src net.Conn) error {
 
 		// keep retrying on EAGAIN
 		errno, ok := shared.GetErrno(er)
-		if ok && (errno == syscall.EAGAIN) {
+		if ok && (errno == unix.EAGAIN) {
 			goto rAgain
 		}
 
@@ -803,7 +803,7 @@ func proxyCopy(dst net.Conn, src net.Conn) error {
 
 			// keep retrying on EAGAIN
 			errno, ok := shared.GetErrno(ew)
-			if ok && (errno == syscall.EAGAIN) {
+			if ok && (errno == unix.EAGAIN) {
 				goto wAgain
 
 			}
@@ -876,7 +876,7 @@ func unixRelayer(src *net.UnixConn, dst *net.UnixConn, ch chan bool) {
 		sData, sOob, _, _, err := src.ReadMsgUnix(dataBuf, oobBuf)
 		if err != nil {
 			errno, ok := shared.GetErrno(err)
-			if ok && errno == syscall.EAGAIN {
+			if ok && errno == unix.EAGAIN {
 				goto readAgain
 			}
 			fmt.Printf("Disconnected during read: %v\n", err)
@@ -886,7 +886,7 @@ func unixRelayer(src *net.UnixConn, dst *net.UnixConn, ch chan bool) {
 
 		var fds []int
 		if sOob > 0 {
-			entries, err := syscall.ParseSocketControlMessage(oobBuf[:sOob])
+			entries, err := unix.ParseSocketControlMessage(oobBuf[:sOob])
 			if err != nil {
 				fmt.Printf("Failed to parse control message: %v\n", err)
 				ch <- true
@@ -894,7 +894,7 @@ func unixRelayer(src *net.UnixConn, dst *net.UnixConn, ch chan bool) {
 			}
 
 			for _, msg := range entries {
-				fds, err = syscall.ParseUnixRights(&msg)
+				fds, err = unix.ParseUnixRights(&msg)
 				if err != nil {
 					fmt.Printf("Failed to get fd list for control message: %v\n", err)
 					ch <- true
@@ -908,7 +908,7 @@ func unixRelayer(src *net.UnixConn, dst *net.UnixConn, ch chan bool) {
 		tData, tOob, err := dst.WriteMsgUnix(dataBuf[:sData], oobBuf[:sOob], nil)
 		if err != nil {
 			errno, ok := shared.GetErrno(err)
-			if ok && errno == syscall.EAGAIN {
+			if ok && errno == unix.EAGAIN {
 				goto writeAgain
 			}
 			fmt.Printf("Disconnected during write: %v\n", err)
@@ -925,7 +925,7 @@ func unixRelayer(src *net.UnixConn, dst *net.UnixConn, ch chan bool) {
 		// Close those fds we received
 		if fds != nil {
 			for _, fd := range fds {
-				err := syscall.Close(fd)
+				err := unix.Close(fd)
 				if err != nil {
 					fmt.Printf("Failed to close fd %d: %v\n", fd, err)
 					ch <- true
diff --git a/lxd/main_forkstart.go b/lxd/main_forkstart.go
index 98ab7a96ff..dbaf87197a 100644
--- a/lxd/main_forkstart.go
+++ b/lxd/main_forkstart.go
@@ -3,9 +3,9 @@ package main
 import (
 	"fmt"
 	"os"
-	"syscall"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 	"gopkg.in/lxc/go-lxc.v2"
 
 	"github.com/lxc/lxd/shared"
@@ -80,8 +80,8 @@ func (c *cmdForkstart) Run(cmd *cobra.Command, args []string) error {
 
 	logFile, err := os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE|os.O_SYNC, 0644)
 	if err == nil {
-		syscall.Dup3(int(logFile.Fd()), 1, 0)
-		syscall.Dup3(int(logFile.Fd()), 2, 0)
+		unix.Dup3(int(logFile.Fd()), 1, 0)
+		unix.Dup3(int(logFile.Fd()), 2, 0)
 	}
 
 	return d.Start()
diff --git a/lxd/main_forkzfs.go b/lxd/main_forkzfs.go
index 14cae00788..9927259e24 100644
--- a/lxd/main_forkzfs.go
+++ b/lxd/main_forkzfs.go
@@ -7,9 +7,9 @@ import (
 	"os/exec"
 	"path/filepath"
 	"strings"
-	"syscall"
 
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
 )
@@ -52,13 +52,13 @@ func (c *cmdForkZFS) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	// Unshare a clean mount namespace
-	err := syscall.Unshare(syscall.CLONE_NEWNS)
+	err := unix.Unshare(unix.CLONE_NEWNS)
 	if err != nil {
 		return err
 	}
 
 	// Mark mount tree as private
-	err = syscall.Mount("none", "/", "", syscall.MS_REC|syscall.MS_PRIVATE, "")
+	err = unix.Mount("none", "/", "", unix.MS_REC|unix.MS_PRIVATE, "")
 	if err != nil {
 		return err
 	}
@@ -91,7 +91,7 @@ func (c *cmdForkZFS) Run(cmd *cobra.Command, args []string) error {
 			continue
 		}
 
-		syscall.Unmount(rows[4], syscall.MNT_DETACH)
+		unix.Unmount(rows[4], unix.MNT_DETACH)
 	}
 
 	// Run the ZFS command
diff --git a/lxd/main_init_interactive.go b/lxd/main_init_interactive.go
index 0c179ef833..af4e14ee6b 100644
--- a/lxd/main_init_interactive.go
+++ b/lxd/main_init_interactive.go
@@ -9,10 +9,10 @@ import (
 	"os/exec"
 	"strconv"
 	"strings"
-	"syscall"
 
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
+	"golang.org/x/sys/unix"
 	"gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd/client"
@@ -513,8 +513,8 @@ func (c *cmdInit) askStoragePool(config *cmdInitData, d lxd.ContainerServer, poo
 
 				pool.Config["source"] = cli.AskString("Path to the existing block device: ", "", deviceExists)
 			} else {
-				st := syscall.Statfs_t{}
-				err := syscall.Statfs(shared.VarPath(), &st)
+				st := unix.Statfs_t{}
+				err := unix.Statfs(shared.VarPath(), &st)
 				if err != nil {
 					return errors.Wrapf(err, "Couldn't statfs %s", shared.VarPath())
 				}
diff --git a/lxd/networks.go b/lxd/networks.go
index 5ce5bfda11..cfe80df9ed 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -12,12 +12,12 @@ import (
 	"strconv"
 	"strings"
 	"sync"
-	"syscall"
 	"time"
 
 	"github.com/gorilla/mux"
 	log "github.com/lxc/lxd/shared/log15"
 	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
 
 	lxd "github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/cluster"
@@ -2117,7 +2117,7 @@ func (n *network) spawnForkDNS(listenAddress string) error {
 	pidPath := shared.VarPath("networks", n.name, "forkdns.pid")
 	err = ioutil.WriteFile(pidPath, []byte(fmt.Sprintf("%d\n", cmd.Process.Pid)), 0600)
 	if err != nil {
-		syscall.Kill(cmd.Process.Pid, syscall.SIGKILL)
+		unix.Kill(cmd.Process.Pid, unix.SIGKILL)
 		logger.Errorf("Failed to start forkdns for network '%s': %v", n.name, err)
 		return err
 	}
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 277151802d..76d978ee1b 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -18,9 +18,10 @@ import (
 	"strconv"
 	"strings"
 	"sync"
-	"syscall"
 	"time"
 
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
@@ -769,7 +770,7 @@ func networkKillForkDNS(name string) error {
 	}
 
 	// Actually kill the process
-	err = syscall.Kill(pidInt, syscall.SIGKILL)
+	err = unix.Kill(pidInt, unix.SIGKILL)
 	if err != nil {
 		return err
 	}
@@ -844,7 +845,7 @@ func networkKillDnsmasq(name string, reload bool) error {
 
 	// Actually kill the process
 	if reload {
-		err = syscall.Kill(pidInt, syscall.SIGHUP)
+		err = unix.Kill(pidInt, unix.SIGHUP)
 		if err != nil {
 			return err
 		}
@@ -852,7 +853,7 @@ func networkKillDnsmasq(name string, reload bool) error {
 		return nil
 	}
 
-	err = syscall.Kill(pidInt, syscall.SIGKILL)
+	err = unix.Kill(pidInt, unix.SIGKILL)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/patches.go b/lxd/patches.go
index 54bd9eaad5..57d2af47c4 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -7,20 +7,20 @@ import (
 	"os"
 	"path/filepath"
 	"strings"
-	"syscall"
 	"time"
 
 	"github.com/boltdb/bolt"
 	"github.com/hashicorp/raft"
 	"github.com/hashicorp/raft-boltdb"
+	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/lxd/cluster"
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/db/query"
 	"github.com/lxc/lxd/shared"
-	"github.com/lxc/lxd/shared/logger"
-	"github.com/pkg/errors"
-
 	log "github.com/lxc/lxd/shared/log15"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 /* Patches are one-time actions that are sometimes needed to update
@@ -1190,7 +1190,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		// Unmount the logical volume.
 		oldContainerMntPoint := shared.VarPath("containers", ct)
 		if shared.IsMountPoint(oldContainerMntPoint) {
-			err := tryUnmount(oldContainerMntPoint, syscall.MNT_DETACH)
+			err := tryUnmount(oldContainerMntPoint, unix.MNT_DETACH)
 			if err != nil {
 				logger.Errorf("Failed to unmount LVM logical volume \"%s\": %s", oldContainerMntPoint, err)
 				return err
@@ -1365,7 +1365,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				if shared.PathExists(oldLvDevPath) {
 					// Unmount the logical volume.
 					if shared.IsMountPoint(oldSnapshotMntPoint) {
-						err := tryUnmount(oldSnapshotMntPoint, syscall.MNT_DETACH)
+						err := tryUnmount(oldSnapshotMntPoint, unix.MNT_DETACH)
 						if err != nil {
 							logger.Errorf("Failed to unmount LVM logical volume \"%s\": %s", oldSnapshotMntPoint, err)
 							return err
@@ -1516,7 +1516,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		// Unmount the logical volume.
 		oldImageMntPoint := shared.VarPath("images", img+".lv")
 		if shared.IsMountPoint(oldImageMntPoint) {
-			err := tryUnmount(oldImageMntPoint, syscall.MNT_DETACH)
+			err := tryUnmount(oldImageMntPoint, unix.MNT_DETACH)
 			if err != nil {
 				return err
 			}
@@ -1716,7 +1716,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			_, err := shared.TryRunCommand("zfs", "unmount", "-f", ctDataset)
 			if err != nil {
 				logger.Warnf("Failed to unmount ZFS filesystem via zfs unmount, trying lazy umount (MNT_DETACH)...")
-				err := tryUnmount(oldContainerMntPoint, syscall.MNT_DETACH)
+				err := tryUnmount(oldContainerMntPoint, unix.MNT_DETACH)
 				if err != nil {
 					failedUpgradeEntities = append(failedUpgradeEntities, fmt.Sprintf("containers/%s: Failed to umount zfs filesystem.", ct))
 					continue
@@ -1864,7 +1864,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			_, err := shared.TryRunCommand("zfs", "unmount", "-f", imageDataset)
 			if err != nil {
 				logger.Warnf("Failed to unmount ZFS filesystem via zfs unmount, trying lazy umount (MNT_DETACH)...")
-				err := tryUnmount(oldImageMntPoint, syscall.MNT_DETACH)
+				err := tryUnmount(oldImageMntPoint, unix.MNT_DETACH)
 				if err != nil {
 					logger.Warnf("Failed to unmount ZFS filesystem: %s", err)
 				}
@@ -2751,9 +2751,9 @@ func patchStorageApiDirBindMount(name string, d *Daemon) error {
 		}
 
 		mountSource := cleanSource
-		mountFlags := syscall.MS_BIND
+		mountFlags := unix.MS_BIND
 
-		err = syscall.Mount(mountSource, poolMntPoint, "", uintptr(mountFlags), "")
+		err = unix.Mount(mountSource, poolMntPoint, "", uintptr(mountFlags), "")
 		if err != nil {
 			logger.Errorf(`Failed to mount DIR storage pool "%s" onto "%s": %s`, mountSource, poolMntPoint, err)
 			return err
@@ -2871,7 +2871,7 @@ func patchDevicesNewNamingScheme(name string, d *Daemon) error {
 
 		if !c.IsRunning() {
 			for wipe := range hasDeviceEntry {
-				syscall.Unmount(wipe, syscall.MNT_DETACH)
+				unix.Unmount(wipe, unix.MNT_DETACH)
 				err := os.Remove(wipe)
 				if err != nil {
 					logger.Errorf("Failed to remove device \"%s\": %s", wipe, err)
@@ -2910,7 +2910,7 @@ func patchDevicesNewNamingScheme(name string, d *Daemon) error {
 				// Try to unmount disk devices otherwise we get
 				// EBUSY when we try to rename block devices.
 				// But don't error out.
-				syscall.Unmount(devPathLegacy, syscall.MNT_DETACH)
+				unix.Unmount(devPathLegacy, unix.MNT_DETACH)
 
 				// Switch device to new device naming scheme.
 				devPathNew := filepath.Join(devicesPath, fmt.Sprintf("disk.%s.%s", strings.Replace(name, "/", "-", -1), hyphenatedDevName))
@@ -2966,7 +2966,7 @@ func patchDevicesNewNamingScheme(name string, d *Daemon) error {
 
 			// This device is not associated with a device entry, so
 			// wipe it.
-			syscall.Unmount(k, syscall.MNT_DETACH)
+			unix.Unmount(k, unix.MNT_DETACH)
 			err := os.Remove(k)
 			if err != nil {
 				logger.Errorf("Failed to remove device \"%s\": %s", k, err)
@@ -3531,7 +3531,7 @@ func patchUpdateFromV30(d *Daemon) error {
 			return err
 		}
 
-		if int(info.Sys().(*syscall.Stat_t).Uid) == 0 {
+		if int(info.Sys().(*unix.Stat_t).Uid) == 0 {
 			err := os.Chmod(shared.VarPath("containers", entry.Name()), 0700)
 			if err != nil {
 				return err
diff --git a/lxd/proxy_device_utils.go b/lxd/proxy_device_utils.go
index b4b2ba16dd..f8d9508b96 100644
--- a/lxd/proxy_device_utils.go
+++ b/lxd/proxy_device_utils.go
@@ -7,7 +7,8 @@ import (
 	"os"
 	"strconv"
 	"strings"
-	"syscall"
+
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
 )
@@ -126,7 +127,7 @@ func killProxyProc(pidPath string) error {
 	}
 
 	// Actually kill the process
-	err = syscall.Kill(pidInt, syscall.SIGKILL)
+	err = unix.Kill(pidInt, unix.SIGKILL)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/rsync.go b/lxd/rsync.go
index e4af344557..c348f5ea6a 100644
--- a/lxd/rsync.go
+++ b/lxd/rsync.go
@@ -7,11 +7,11 @@ import (
 	"net"
 	"os"
 	"os/exec"
-	"syscall"
 	"time"
 
 	"github.com/gorilla/websocket"
 	"github.com/pborman/uuid"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
@@ -51,7 +51,7 @@ func rsyncLocalCopy(source string, dest string, bwlimit string) (string, error)
 		if ok {
 			exitError, ok := runError.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 24 {
 					return msg, nil
 				}
diff --git a/lxd/storage/quota/projectquota.go b/lxd/storage/quota/projectquota.go
index e7e44946ae..e6efdc3237 100644
--- a/lxd/storage/quota/projectquota.go
+++ b/lxd/storage/quota/projectquota.go
@@ -5,9 +5,10 @@ import (
 	"fmt"
 	"os"
 	"strings"
-	"syscall"
 	"unsafe"
 
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/shared"
 )
 
@@ -157,8 +158,8 @@ var errNoDevice = fmt.Errorf("Couldn't find backing device for mountpoint")
 
 func devForPath(path string) (string, error) {
 	// Get major/minor
-	var stat syscall.Stat_t
-	err := syscall.Lstat(path, &stat)
+	var stat unix.Stat_t
+	err := unix.Lstat(path, &stat)
 	if err != nil {
 		return "", err
 	}
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index fc1bc2347f..2ce3bca3ad 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -11,10 +11,10 @@ import (
 	"sort"
 	"strconv"
 	"strings"
-	"syscall"
 
 	"github.com/gorilla/websocket"
 	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/migration"
@@ -236,7 +236,7 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		// cannot call StoragePoolMount() since it will try to do the
 		// reverse operation. So instead we shamelessly mount using the
 		// block device path at the time of pool creation.
-		err1 = syscall.Mount(source, poolMntPoint, "btrfs", mountFlags, mountOptions)
+		err1 = unix.Mount(source, poolMntPoint, "btrfs", mountFlags, mountOptions)
 	} else {
 		_, err1 = s.StoragePoolMount()
 	}
@@ -403,7 +403,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 		}
 	}
 
-	if shared.IsMountPoint(poolMntPoint) && (s.remount&syscall.MS_REMOUNT) == 0 {
+	if shared.IsMountPoint(poolMntPoint) && (s.remount&unix.MS_REMOUNT) == 0 {
 		return false, nil
 	}
 
@@ -429,7 +429,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 			defer loopF.Close()
 		} else if !isBlockDev && cleanSource != poolMntPoint {
 			mountSource = source
-			mountFlags |= syscall.MS_BIND
+			mountFlags |= unix.MS_BIND
 		} else if !isBlockDev && cleanSource == poolMntPoint && s.s.OS.BackingFS == "btrfs" {
 			return false, nil
 		}
@@ -453,7 +453,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 	}
 
 	mountFlags |= s.remount
-	err := syscall.Mount(mountSource, poolMntPoint, "btrfs", mountFlags, mountOptions)
+	err := unix.Mount(mountSource, poolMntPoint, "btrfs", mountFlags, mountOptions)
 	if err != nil {
 		logger.Errorf("Failed to mount BTRFS storage pool \"%s\" onto \"%s\" with mountoptions \"%s\": %s", mountSource, poolMntPoint, mountOptions, err)
 		return false, err
@@ -495,7 +495,7 @@ func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 	defer removeLockFromMap()
 
 	if shared.IsMountPoint(poolMntPoint) {
-		err := syscall.Unmount(poolMntPoint, 0)
+		err := unix.Unmount(poolMntPoint, 0)
 		if err != nil {
 			return false, err
 		}
@@ -525,7 +525,7 @@ func (s *storageBtrfs) StoragePoolUpdate(writable *api.StoragePoolPut,
 
 	if shared.StringInSlice("btrfs.mount_options", changedConfig) {
 		s.setBtrfsMountOptions(writable.Config["btrfs.mount_options"])
-		s.remount |= syscall.MS_REMOUNT
+		s.remount |= unix.MS_REMOUNT
 		_, err := s.StoragePoolMount()
 		if err != nil {
 			return err
@@ -2348,8 +2348,8 @@ func (s *storageBtrfs) btrfsPoolVolumesSnapshot(source string, dest string, read
 // isBtrfsSubVolume returns true if the given Path is a btrfs subvolume else
 // false.
 func isBtrfsSubVolume(subvolPath string) bool {
-	fs := syscall.Stat_t{}
-	err := syscall.Lstat(subvolPath, &fs)
+	fs := unix.Stat_t{}
+	err := unix.Lstat(subvolPath, &fs)
 	if err != nil {
 		return false
 	}
@@ -2372,9 +2372,9 @@ func isBtrfsFilesystem(path string) bool {
 }
 
 func isOnBtrfs(path string) bool {
-	fs := syscall.Statfs_t{}
+	fs := unix.Statfs_t{}
 
-	err := syscall.Statfs(path, &fs)
+	err := unix.Statfs(path, &fs)
 	if err != nil {
 		return false
 	}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index f90c9ba304..e104492bcf 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -8,10 +8,10 @@ import (
 	"io/ioutil"
 	"os"
 	"strings"
-	"syscall"
 
 	"github.com/gorilla/websocket"
 	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/state"
@@ -458,7 +458,7 @@ func (s *storageCeph) StoragePoolVolumeDelete() error {
 
 	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	if shared.IsMountPoint(volumeMntPoint) {
-		err := tryUnmount(volumeMntPoint, syscall.MNT_DETACH)
+		err := tryUnmount(volumeMntPoint, unix.MNT_DETACH)
 		if err != nil {
 			logger.Errorf(`Failed to unmount RBD storage volume "%s" on storage pool "%s": %s`, s.volume.Name, s.pool.Name, err)
 		}
@@ -594,7 +594,7 @@ func (s *storageCeph) StoragePoolVolumeUmount() (bool, error) {
 	var customerr error
 	ourUmount := false
 	if shared.IsMountPoint(volumeMntPoint) {
-		customerr = tryUnmount(volumeMntPoint, syscall.MNT_DETACH)
+		customerr = tryUnmount(volumeMntPoint, unix.MNT_DETACH)
 		ourUmount = true
 	}
 
@@ -1091,7 +1091,7 @@ func (s *storageCeph) doCrossPoolContainerCopy(target container, source containe
 			// been committed to disk. If we don't then the rbd snapshot of
 			// the underlying filesystem can be inconsistent or - worst case
 			// - empty.
-			syscall.Sync()
+			unix.Sync()
 
 			msg, fsFreezeErr := shared.TryRunCommand("fsfreeze", "--freeze", destContainerMntPoint)
 			logger.Debugf("Trying to freeze the filesystem: %s: %s", msg, fsFreezeErr)
@@ -1629,7 +1629,7 @@ func (s *storageCeph) ContainerSnapshotCreate(snapshotContainer container, sourc
 		// been committed to disk. If we don't then the rbd snapshot of
 		// the underlying filesystem can be inconsistent or - worst case
 		// - empty.
-		syscall.Sync()
+		unix.Sync()
 
 		msg, fsFreezeErr := shared.TryRunCommand("fsfreeze", "--freeze", containerMntPoint)
 		logger.Debugf("Trying to freeze the filesystem: %s: %s", msg, fsFreezeErr)
@@ -1883,7 +1883,7 @@ func (s *storageCeph) ContainerSnapshotStop(c container) (bool, error) {
 	}
 
 	// Unmount
-	err := tryUnmount(containerMntPoint, syscall.MNT_DETACH)
+	err := tryUnmount(containerMntPoint, unix.MNT_DETACH)
 	if err != nil {
 		logger.Errorf("Failed to unmount %s: %s", containerMntPoint, err)
 		return false, err
@@ -2016,7 +2016,7 @@ func (s *storageCeph) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, t
 		// been committed to disk. If we don't then the rbd snapshot of
 		// the underlying filesystem can be inconsistent or - worst case
 		// - empty.
-		syscall.Sync()
+		unix.Sync()
 
 		msg, fsFreezeErr := shared.TryRunCommand("fsfreeze", "--freeze", containerMntPoint)
 		logger.Debugf("Trying to freeze the filesystem: %s: %s", msg, fsFreezeErr)
@@ -2750,7 +2750,7 @@ func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 		// been committed to disk. If we don't then the rbd snapshot of
 		// the underlying filesystem can be inconsistent or - worst case
 		// - empty.
-		syscall.Sync()
+		unix.Sync()
 
 		msg, fsFreezeErr := shared.TryRunCommand("fsfreeze", "--freeze", sourcePath)
 		logger.Debugf("Trying to freeze the filesystem: %s: %s", msg, fsFreezeErr)
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 4f6889af9b..607c459e92 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -8,14 +8,14 @@ import (
 	"os/exec"
 	"strconv"
 	"strings"
-	"syscall"
+
+	"github.com/pborman/uuid"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
-
-	"github.com/pborman/uuid"
 )
 
 // cephOSDPoolExists checks whether a given OSD pool exists.
@@ -179,7 +179,7 @@ again:
 		if ok {
 			exitError, ok := runError.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 22 {
 					// EINVAL (already unmapped)
 					return nil
@@ -217,7 +217,7 @@ again:
 		if ok {
 			exitError, ok := runError.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 22 {
 					// EINVAL (already unmapped)
 					return nil
@@ -293,7 +293,7 @@ func cephRBDSnapshotProtect(clusterName string, poolName string,
 		if ok {
 			exitError, ok := runError.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 16 {
 					// EBUSY (snapshot already protected)
 					return nil
@@ -326,7 +326,7 @@ func cephRBDSnapshotUnprotect(clusterName string, poolName string,
 		if ok {
 			exitError, ok := runError.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 22 {
 					// EBUSY (snapshot already unprotected)
 					return nil
@@ -1594,7 +1594,7 @@ func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup, s
 		// been committed to disk. If we don't then the rbd snapshot of
 		// the underlying filesystem can be inconsistent or - worst case
 		// - empty.
-		syscall.Sync()
+		unix.Sync()
 
 		// create snapshot
 		err := cephRBDSnapshotCreate(s.ClusterName, s.OSDPoolName, sourceContainerOnlyName, storagePoolVolumeTypeNameContainer, snapshotName, s.UserName)
@@ -1654,7 +1654,7 @@ func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup, s
 		return err
 	}
 	logger.Debugf("Mounted RBD device %s onto %s", RBDDevPath, tmpContainerMntPoint)
-	defer tryUnmount(tmpContainerMntPoint, syscall.MNT_DETACH)
+	defer tryUnmount(tmpContainerMntPoint, unix.MNT_DETACH)
 
 	// Figure out the target name
 	targetName := sourceContainerName
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index b7635fd007..9763f6395d 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -7,10 +7,10 @@ import (
 	"os"
 	"path/filepath"
 	"strings"
-	"syscall"
 
 	"github.com/gorilla/websocket"
 	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/state"
@@ -208,13 +208,13 @@ func (s *storageDir) StoragePoolMount() (bool, error) {
 	defer removeLockFromMap()
 
 	mountSource := cleanSource
-	mountFlags := syscall.MS_BIND
+	mountFlags := unix.MS_BIND
 
 	if shared.IsMountPoint(poolMntPoint) {
 		return false, nil
 	}
 
-	err := syscall.Mount(mountSource, poolMntPoint, "", uintptr(mountFlags), "")
+	err := unix.Mount(mountSource, poolMntPoint, "", uintptr(mountFlags), "")
 	if err != nil {
 		logger.Errorf(`Failed to mount DIR storage pool "%s" onto "%s": %s`, mountSource, poolMntPoint, err)
 		return false, err
@@ -268,7 +268,7 @@ func (s *storageDir) StoragePoolUmount() (bool, error) {
 		return false, nil
 	}
 
-	err := syscall.Unmount(poolMntPoint, 0)
+	err := unix.Unmount(poolMntPoint, 0)
 	if err != nil {
 		return false, err
 	}
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index 0776ab2c4f..f5471aceca 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -6,7 +6,9 @@ import (
 	"os/exec"
 	"strconv"
 	"strings"
-	"syscall"
+
+	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/state"
@@ -14,7 +16,6 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
-	"github.com/pkg/errors"
 )
 
 func (s *storageLvm) lvExtend(lvPath string, lvSize int64, fsType string, fsMntPoint string, volumeType int, data interface{}) error {
@@ -615,7 +616,7 @@ func storagePVExists(pvName string) (bool, error) {
 		if ok {
 			exitError, ok := runErr.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 5 {
 					// physical volume not found
 					return false, nil
@@ -635,7 +636,7 @@ func storageVGExists(vgName string) (bool, error) {
 		if ok {
 			exitError, ok := runErr.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 5 {
 					// volume group not found
 					return false, nil
@@ -656,7 +657,7 @@ func storageLVExists(lvName string) (bool, error) {
 		if ok {
 			exitError, ok := runErr.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 5 {
 					// logical volume not found
 					return false, nil
@@ -695,7 +696,7 @@ func storageLVMThinpoolExists(vgName string, poolName string) (bool, error) {
 		if ok {
 			exitError, ok := runErr.Err.(*exec.ExitError)
 			if ok {
-				waitStatus := exitError.Sys().(syscall.WaitStatus)
+				waitStatus := exitError.Sys().(unix.WaitStatus)
 				if waitStatus.ExitStatus() == 5 {
 					// pool LV was not found
 					return false, nil
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index 228b2abb45..088352db33 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -4,7 +4,8 @@ import (
 	"fmt"
 	"strconv"
 	"strings"
-	"syscall"
+
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
 )
@@ -200,8 +201,8 @@ func storagePoolFillDefault(name string, driver string, config map[string]string
 		}
 	} else {
 		if config["size"] == "" {
-			st := syscall.Statfs_t{}
-			err := syscall.Statfs(shared.VarPath(), &st)
+			st := unix.Statfs_t{}
+			err := unix.Statfs(shared.VarPath(), &st)
 			if err != nil {
 				return fmt.Errorf("Couldn't statfs %s: %s", shared.VarPath(), err)
 			}
diff --git a/lxd/storage_utils.go b/lxd/storage_utils.go
index 23f0450c19..108d4ccbd5 100644
--- a/lxd/storage_utils.go
+++ b/lxd/storage_utils.go
@@ -4,9 +4,10 @@ import (
 	"fmt"
 	"os"
 	"strings"
-	"syscall"
 	"time"
 
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -26,32 +27,32 @@ type mountOptions struct {
 }
 
 var MountOptions = map[string]mountOptions{
-	"async":         {false, syscall.MS_SYNCHRONOUS},
-	"atime":         {false, syscall.MS_NOATIME},
-	"bind":          {true, syscall.MS_BIND},
+	"async":         {false, unix.MS_SYNCHRONOUS},
+	"atime":         {false, unix.MS_NOATIME},
+	"bind":          {true, unix.MS_BIND},
 	"defaults":      {true, 0},
-	"dev":           {false, syscall.MS_NODEV},
-	"diratime":      {false, syscall.MS_NODIRATIME},
-	"dirsync":       {true, syscall.MS_DIRSYNC},
-	"exec":          {false, syscall.MS_NOEXEC},
+	"dev":           {false, unix.MS_NODEV},
+	"diratime":      {false, unix.MS_NODIRATIME},
+	"dirsync":       {true, unix.MS_DIRSYNC},
+	"exec":          {false, unix.MS_NOEXEC},
 	"lazytime":      {true, MS_LAZYTIME},
-	"mand":          {true, syscall.MS_MANDLOCK},
-	"noatime":       {true, syscall.MS_NOATIME},
-	"nodev":         {true, syscall.MS_NODEV},
-	"nodiratime":    {true, syscall.MS_NODIRATIME},
-	"noexec":        {true, syscall.MS_NOEXEC},
-	"nomand":        {false, syscall.MS_MANDLOCK},
-	"norelatime":    {false, syscall.MS_RELATIME},
-	"nostrictatime": {false, syscall.MS_STRICTATIME},
-	"nosuid":        {true, syscall.MS_NOSUID},
-	"rbind":         {true, syscall.MS_BIND | syscall.MS_REC},
-	"relatime":      {true, syscall.MS_RELATIME},
-	"remount":       {true, syscall.MS_REMOUNT},
-	"ro":            {true, syscall.MS_RDONLY},
-	"rw":            {false, syscall.MS_RDONLY},
-	"strictatime":   {true, syscall.MS_STRICTATIME},
-	"suid":          {false, syscall.MS_NOSUID},
-	"sync":          {true, syscall.MS_SYNCHRONOUS},
+	"mand":          {true, unix.MS_MANDLOCK},
+	"noatime":       {true, unix.MS_NOATIME},
+	"nodev":         {true, unix.MS_NODEV},
+	"nodiratime":    {true, unix.MS_NODIRATIME},
+	"noexec":        {true, unix.MS_NOEXEC},
+	"nomand":        {false, unix.MS_MANDLOCK},
+	"norelatime":    {false, unix.MS_RELATIME},
+	"nostrictatime": {false, unix.MS_STRICTATIME},
+	"nosuid":        {true, unix.MS_NOSUID},
+	"rbind":         {true, unix.MS_BIND | unix.MS_REC},
+	"relatime":      {true, unix.MS_RELATIME},
+	"remount":       {true, unix.MS_REMOUNT},
+	"ro":            {true, unix.MS_RDONLY},
+	"rw":            {false, unix.MS_RDONLY},
+	"strictatime":   {true, unix.MS_STRICTATIME},
+	"suid":          {false, unix.MS_NOSUID},
+	"sync":          {true, unix.MS_SYNCHRONOUS},
 }
 
 func lxdResolveMountoptions(options string) (uintptr, string) {
@@ -84,7 +85,7 @@ func tryMount(src string, dst string, fs string, flags uintptr, options string)
 	var err error
 
 	for i := 0; i < 20; i++ {
-		err = syscall.Mount(src, dst, fs, flags, options)
+		err = unix.Mount(src, dst, fs, flags, options)
 		if err == nil {
 			break
 		}
@@ -103,7 +104,7 @@ func tryUnmount(path string, flags int) error {
 	var err error
 
 	for i := 0; i < 20; i++ {
-		err = syscall.Unmount(path, flags)
+		err = unix.Unmount(path, flags)
 		if err == nil {
 			break
 		}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index dc849f0f80..d69cfd9be1 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -9,10 +9,10 @@ import (
 	"path/filepath"
 	"strconv"
 	"strings"
-	"syscall"
 
 	"github.com/gorilla/websocket"
 	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/state"
@@ -1587,8 +1587,8 @@ func (s *storageZfs) ContainerGetUsage(container container) (int64, error) {
 	// Shortcut for refquota
 	mountpoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	if property == "referenced" && shared.IsMountPoint(mountpoint) {
-		var stat syscall.Statfs_t
-		err := syscall.Statfs(mountpoint, &stat)
+		var stat unix.Statfs_t
+		err := unix.Statfs(mountpoint, &stat)
 		if err != nil {
 			return -1, err
 		}
diff --git a/lxd/storage_zfs_utils.go b/lxd/storage_zfs_utils.go
index a5f0eaaef6..33bc9f717f 100644
--- a/lxd/storage_zfs_utils.go
+++ b/lxd/storage_zfs_utils.go
@@ -7,13 +7,13 @@ import (
 	"os/exec"
 	"path/filepath"
 	"strings"
-	"syscall"
 	"time"
 
+	"github.com/pborman/uuid"
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
-
-	"github.com/pborman/uuid"
 )
 
 // zfsIsEnabled returns whether zfs backend is supported.
@@ -251,7 +251,7 @@ func zfsPoolVolumeDestroy(pool string, path string) error {
 	}
 
 	if mountpoint != "none" && shared.IsMountPoint(mountpoint) {
-		err := syscall.Unmount(mountpoint, syscall.MNT_DETACH)
+		err := unix.Unmount(mountpoint, unix.MNT_DETACH)
 		if err != nil {
 			logger.Errorf("umount failed: %s", err)
 			return err
@@ -517,7 +517,7 @@ func zfsUmount(poolName string, path string, mountpoint string) error {
 		fmt.Sprintf("%s/%s", poolName, path))
 	if err != nil {
 		logger.Warnf("Failed to unmount ZFS filesystem via zfs unmount: %s. Trying lazy umount (MNT_DETACH)...", output)
-		err := tryUnmount(mountpoint, syscall.MNT_DETACH)
+		err := tryUnmount(mountpoint, unix.MNT_DETACH)
 		if err != nil {
 			logger.Warnf("Failed to unmount ZFS filesystem via lazy umount (MNT_DETACH)...")
 			return err
@@ -682,7 +682,7 @@ func (s *storageZfs) doContainerMount(project, name string, privileged bool) (bo
 		zfsMountOptions := fmt.Sprintf("rw,zfsutil,mntpoint=%s", containerPoolVolumeMntPoint)
 		mounterr := tryMount(source, containerPoolVolumeMntPoint, "zfs", 0, zfsMountOptions)
 		if mounterr != nil {
-			if mounterr != syscall.EBUSY {
+			if mounterr != unix.EBUSY {
 				logger.Errorf("Failed to mount ZFS dataset \"%s\" onto \"%s\": %v", source, containerPoolVolumeMntPoint, mounterr)
 				return false, mounterr
 			}
diff --git a/lxd/util/fs.go b/lxd/util/fs.go
index a09da3fa77..2b1ddf2488 100644
--- a/lxd/util/fs.go
+++ b/lxd/util/fs.go
@@ -1,7 +1,7 @@
 package util
 
 import (
-	"syscall"
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared/logger"
 )
@@ -17,9 +17,9 @@ const (
 
 // FilesystemDetect returns the filesystem on which the passed-in path sits.
 func FilesystemDetect(path string) (string, error) {
-	fs := syscall.Statfs_t{}
+	fs := unix.Statfs_t{}
 
-	err := syscall.Statfs(path, &fs)
+	err := unix.Statfs(path, &fs)
 	if err != nil {
 		return "", err
 	}
diff --git a/lxd/util/http.go b/lxd/util/http.go
index 30d5103bb6..e1660c9b86 100644
--- a/lxd/util/http.go
+++ b/lxd/util/http.go
@@ -14,10 +14,10 @@ import (
 	"os"
 	"strconv"
 	"strings"
-	"syscall"
 	"time"
 
 	"golang.org/x/net/context"
+	"golang.org/x/sys/unix"
 
 	log "github.com/lxc/lxd/shared/log15"
 
@@ -249,7 +249,7 @@ func GetListeners(start int) []net.Listener {
 	listeners := []net.Listener{}
 
 	for i := start; i < start+fds; i++ {
-		syscall.CloseOnExec(i)
+		unix.CloseOnExec(i)
 
 		file := os.NewFile(uintptr(i), fmt.Sprintf("inherited-fd%d", i))
 		listener, err := net.FileListener(file)

From a5fa3d830b3da5d29943bc67e3ce506111019dab Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 3 Jun 2019 21:08:03 +0200
Subject: [PATCH 5/5] shared: Transition to golang.org/x/sys

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 shared/archive_linux.go                  |  7 +++--
 shared/eagain/{file.go => file_unix.go}  |  7 +++--
 shared/idmap/shift_linux.go              |  5 ++--
 shared/log15/term/terminal_darwin.go     |  6 ++--
 shared/log15/term/terminal_freebsd.go    |  6 ++--
 shared/log15/term/terminal_linux.go      |  6 ++--
 shared/log15/term/terminal_notwindows.go |  5 ++--
 shared/log15/term/terminal_openbsd.go    |  6 ++--
 shared/log15/term/terminal_windows.go    | 15 ++++------
 shared/network_windows.go                |  3 +-
 shared/termios/termios_unix.go           | 13 +++++----
 shared/util_linux.go                     | 35 ++++++++++++------------
 shared/util_linux_cgo.go                 | 13 +++++----
 shared/util_linux_test.go                | 11 ++++----
 shared/util_unix.go                      |  7 +++--
 15 files changed, 73 insertions(+), 72 deletions(-)
 rename shared/eagain/{file.go => file_unix.go} (85%)

diff --git a/shared/archive_linux.go b/shared/archive_linux.go
index 5c6aec830d..1e659d63ba 100644
--- a/shared/archive_linux.go
+++ b/shared/archive_linux.go
@@ -6,7 +6,8 @@ import (
 	"io"
 	"os"
 	"strings"
-	"syscall"
+
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
@@ -120,9 +121,9 @@ func Unpack(file string, path string, blockBackend bool, runningInUserns bool, t
 	err = RunCommandWithFds(reader, nil, command, args...)
 	if err != nil {
 		// Check if we ran out of space
-		fs := syscall.Statfs_t{}
+		fs := unix.Statfs_t{}
 
-		err1 := syscall.Statfs(path, &fs)
+		err1 := unix.Statfs(path, &fs)
 		if err1 != nil {
 			return err1
 		}
diff --git a/shared/eagain/file.go b/shared/eagain/file_unix.go
similarity index 85%
rename from shared/eagain/file.go
rename to shared/eagain/file_unix.go
index 2739969df8..bd671df906 100644
--- a/shared/eagain/file.go
+++ b/shared/eagain/file_unix.go
@@ -2,7 +2,8 @@ package eagain
 
 import (
 	"io"
-	"syscall"
+
+	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
 )
@@ -22,7 +23,7 @@ again:
 
 	// keep retrying on EAGAIN
 	errno, ok := shared.GetErrno(err)
-	if ok && (errno == syscall.EAGAIN || errno == syscall.EINTR) {
+	if ok && (errno == unix.EAGAIN || errno == unix.EINTR) {
 		goto again
 	}
 
@@ -44,7 +45,7 @@ again:
 
 	// keep retrying on EAGAIN
 	errno, ok := shared.GetErrno(err)
-	if ok && (errno == syscall.EAGAIN || errno == syscall.EINTR) {
+	if ok && (errno == unix.EAGAIN || errno == unix.EINTR) {
 		goto again
 	}
 
diff --git a/shared/idmap/shift_linux.go b/shared/idmap/shift_linux.go
index b3a9b58dab..11a2447955 100644
--- a/shared/idmap/shift_linux.go
+++ b/shared/idmap/shift_linux.go
@@ -8,9 +8,10 @@ import (
 	"io/ioutil"
 	"os"
 	"os/exec"
-	"syscall"
 	"unsafe"
 
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/shared"
 )
 
@@ -319,7 +320,7 @@ func SupportsVFS3Fscaps(prefix string) bool {
 	err = cmd.Run()
 	if err != nil {
 		errno, isErrno := shared.GetErrno(err)
-		if isErrno && (errno == syscall.ERANGE || errno == syscall.EOVERFLOW) {
+		if isErrno && (errno == unix.ERANGE || errno == unix.EOVERFLOW) {
 			return false
 		}
 
diff --git a/shared/log15/term/terminal_darwin.go b/shared/log15/term/terminal_darwin.go
index b05de4cb8c..9dd6fb02bd 100644
--- a/shared/log15/term/terminal_darwin.go
+++ b/shared/log15/term/terminal_darwin.go
@@ -5,8 +5,8 @@
 
 package term
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
-const ioctlReadTermios = syscall.TIOCGETA
+const ioctlReadTermios = unix.TCGETA
 
-type Termios syscall.Termios
+type Termios unix.Termios
diff --git a/shared/log15/term/terminal_freebsd.go b/shared/log15/term/terminal_freebsd.go
index cfaceab337..2365884760 100644
--- a/shared/log15/term/terminal_freebsd.go
+++ b/shared/log15/term/terminal_freebsd.go
@@ -1,10 +1,8 @@
 package term
 
-import (
-	"syscall"
-)
+import "golang.org/x/sys/unix"
 
-const ioctlReadTermios = syscall.TIOCGETA
+const ioctlReadTermios = unix.TCGETA
 
 // Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin.
 type Termios struct {
diff --git a/shared/log15/term/terminal_linux.go b/shared/log15/term/terminal_linux.go
index 5290468d69..c5d6ed0319 100644
--- a/shared/log15/term/terminal_linux.go
+++ b/shared/log15/term/terminal_linux.go
@@ -7,8 +7,8 @@
 
 package term
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
-const ioctlReadTermios = syscall.TCGETS
+const ioctlReadTermios = unix.TCGETS
 
-type Termios syscall.Termios
+type Termios unix.Termios
diff --git a/shared/log15/term/terminal_notwindows.go b/shared/log15/term/terminal_notwindows.go
index 87df7d5b02..56f6992a07 100644
--- a/shared/log15/term/terminal_notwindows.go
+++ b/shared/log15/term/terminal_notwindows.go
@@ -8,13 +8,14 @@
 package term
 
 import (
-	"syscall"
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 // IsTty returns true if the given file descriptor is a terminal.
 func IsTty(fd uintptr) bool {
 	var termios Termios
-	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+	_, _, err := unix.Syscall6(unix.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
 	return err == 0
 }
diff --git a/shared/log15/term/terminal_openbsd.go b/shared/log15/term/terminal_openbsd.go
index f9bb9e1c23..350dac685a 100644
--- a/shared/log15/term/terminal_openbsd.go
+++ b/shared/log15/term/terminal_openbsd.go
@@ -1,7 +1,7 @@
 package term
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
-const ioctlReadTermios = syscall.TIOCGETA
+const ioctlReadTermios = unix.TCGETA
 
-type Termios syscall.Termios
+type Termios unix.Termios
diff --git a/shared/log15/term/terminal_windows.go b/shared/log15/term/terminal_windows.go
index df3c30c158..bbbc111311 100644
--- a/shared/log15/term/terminal_windows.go
+++ b/shared/log15/term/terminal_windows.go
@@ -8,19 +8,14 @@
 package term
 
 import (
-	"syscall"
-	"unsafe"
+	"golang.org/x/sys/windows"
 )
 
-var kernel32 = syscall.NewLazyDLL("kernel32.dll")
-
-var (
-	procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
-)
+var kernel32 = windows.NewLazyDLL("kernel32.dll")
 
 // IsTty returns true if the given file descriptor is a terminal.
 func IsTty(fd uintptr) bool {
-	var st uint32
-	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
-	return r != 0 && e == 0
+	var mode uint32
+	err := windows.GetConsoleMode(fd, &mode)
+	return mode != 0 && err == nil
 }
diff --git a/shared/network_windows.go b/shared/network_windows.go
index 2a8319b871..e07aa27824 100644
--- a/shared/network_windows.go
+++ b/shared/network_windows.go
@@ -6,7 +6,6 @@ import (
 	"crypto/x509"
 	"fmt"
 	"sync"
-	"syscall"
 	"unsafe"
 
 	"golang.org/x/sys/windows"
@@ -38,7 +37,7 @@ func initSystemRoots() {
 	for {
 		cert, err = windows.CertEnumCertificatesInStore(store, cert)
 		if err != nil {
-			if errno, ok := err.(syscall.Errno); ok {
+			if errno, ok := err.(windows.Errno); ok {
 				if errno == CRYPT_E_NOT_FOUND {
 					break
 				}
diff --git a/shared/termios/termios_unix.go b/shared/termios/termios_unix.go
index 153d826909..375893685f 100644
--- a/shared/termios/termios_unix.go
+++ b/shared/termios/termios_unix.go
@@ -3,9 +3,10 @@
 package termios
 
 import (
-	"syscall"
 	"unsafe"
 
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/shared"
 )
 
@@ -15,7 +16,7 @@ import "C"
 
 // State contains the state of a terminal.
 type State struct {
-	Termios syscall.Termios
+	Termios unix.Termios
 }
 
 // IsTerminal returns true if the given file descriptor is a terminal.
@@ -26,11 +27,11 @@ func IsTerminal(fd int) bool {
 
 // GetState returns the current state of a terminal which may be useful to restore the terminal after a signal.
 func GetState(fd int) (*State, error) {
-	termios := syscall.Termios{}
+	termios := unix.Termios{}
 
 	ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(&termios)))
 	if ret != 0 {
-		return nil, err.(syscall.Errno)
+		return nil, err.(unix.Errno)
 	}
 
 	state := State{}
@@ -43,7 +44,7 @@ func GetState(fd int) (*State, error) {
 func GetSize(fd int) (int, int, error) {
 	var dimensions [4]uint16
 
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
+	if _, _, err := unix.Syscall6(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
 		return -1, -1, err
 	}
 
@@ -79,7 +80,7 @@ func MakeRaw(fd int) (*State, error) {
 func Restore(fd int, state *State) error {
 	ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(&state.Termios)))
 	if ret != 0 {
-		return err.(syscall.Errno)
+		return err.(unix.Errno)
 	}
 
 	return nil
diff --git a/shared/util_linux.go b/shared/util_linux.go
index 36cf9fdab1..008fffab22 100644
--- a/shared/util_linux.go
+++ b/shared/util_linux.go
@@ -9,8 +9,9 @@ import (
 	"path/filepath"
 	"reflect"
 	"strings"
-	"syscall"
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 // --- pure Go functions ---
@@ -25,8 +26,8 @@ func Minor(dev uint64) int {
 
 func GetFileStat(p string) (uid int, gid int, major int, minor int,
 	inode uint64, nlink int, err error) {
-	var stat syscall.Stat_t
-	err = syscall.Lstat(p, &stat)
+	var stat unix.Stat_t
+	err = unix.Lstat(p, &stat)
 	if err != nil {
 		return
 	}
@@ -36,7 +37,7 @@ func GetFileStat(p string) (uid int, gid int, major int, minor int,
 	nlink = int(stat.Nlink)
 	major = -1
 	minor = -1
-	if stat.Mode&syscall.S_IFBLK != 0 || stat.Mode&syscall.S_IFCHR != 0 {
+	if stat.Mode&unix.S_IFBLK != 0 || stat.Mode&unix.S_IFCHR != 0 {
 		major = Major(stat.Rdev)
 		minor = Minor(stat.Rdev)
 	}
@@ -107,7 +108,7 @@ func IsMountPoint(name string) bool {
 		return false
 	}
 	// If the directory has the same device as parent, then it's not a mountpoint.
-	return stat.Sys().(*syscall.Stat_t).Dev != rootStat.Sys().(*syscall.Stat_t).Dev
+	return stat.Sys().(*unix.Stat_t).Dev != rootStat.Sys().(*unix.Stat_t).Dev
 }
 
 func SetSize(fd int, width int, height int) (err error) {
@@ -115,7 +116,7 @@ func SetSize(fd int, width int, height int) (err error) {
 	dimensions[0] = uint16(height)
 	dimensions[1] = uint16(width)
 
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
+	if _, _, err := unix.Syscall6(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.TIOCSWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
 		return err
 	}
 	return nil
@@ -127,7 +128,7 @@ func SetSize(fd int, width int, height int) (err error) {
 // associated with the link itself are retrieved.
 func llistxattr(path string, list []byte) (sz int, err error) {
 	var _p0 *byte
-	_p0, err = syscall.BytePtrFromString(path)
+	_p0, err = unix.BytePtrFromString(path)
 	if err != nil {
 		return
 	}
@@ -137,7 +138,7 @@ func llistxattr(path string, list []byte) (sz int, err error) {
 	} else {
 		_p1 = unsafe.Pointer(nil)
 	}
-	r0, _, e1 := syscall.Syscall(syscall.SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(list)))
+	r0, _, e1 := unix.Syscall(unix.SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(list)))
 	sz = int(r0)
 	if e1 != 0 {
 		err = e1
@@ -195,7 +196,7 @@ func GetAllXattr(path string) (xattrs map[string]string, err error) {
 		// second, to actually store the extended attributes in the
 		// buffer. Also, check if the size of the extended attribute
 		// hasn't changed between the two calls.
-		pre, err = syscall.Getxattr(path, xattr, nil)
+		pre, err = unix.Getxattr(path, xattr, nil)
 		if err != nil || pre < 0 {
 			return nil, err
 		}
@@ -203,7 +204,7 @@ func GetAllXattr(path string) (xattrs map[string]string, err error) {
 		dest = make([]byte, pre)
 		post := 0
 		if pre > 0 {
-			post, err = syscall.Getxattr(path, xattr, dest)
+			post, err = unix.Getxattr(path, xattr, dest)
 			if err != nil || post < 0 {
 				return nil, err
 			}
@@ -273,7 +274,7 @@ func GetErrno(err error) (errno error, iserrno bool) {
 		return pathErr.Err, true
 	}
 
-	tmpErrno, ok := err.(syscall.Errno)
+	tmpErrno, ok := err.(unix.Errno)
 	if ok {
 		return tmpErrno, true
 	}
@@ -281,7 +282,7 @@ func GetErrno(err error) (errno error, iserrno bool) {
 	return nil, false
 }
 
-// Utsname returns the same info as syscall.Utsname, as strings
+// Utsname returns the same info as unix.Utsname, as strings
 type Utsname struct {
 	Sysname    string
 	Nodename   string
@@ -301,8 +302,8 @@ func Uname() (*Utsname, error) {
 	 * viz. github issue #206.
 	 */
 
-	uname := syscall.Utsname{}
-	err := syscall.Uname(&uname)
+	uname := unix.Utsname{}
+	err := unix.Uname(&uname)
 	if err != nil {
 		return nil, err
 	}
@@ -345,10 +346,10 @@ func intArrayToString(arr interface{}) string {
 	return s
 }
 
-func Statvfs(path string) (*syscall.Statfs_t, error) {
-	var st syscall.Statfs_t
+func Statvfs(path string) (*unix.Statfs_t, error) {
+	var st unix.Statfs_t
 
-	err := syscall.Statfs(path, &st)
+	err := unix.Statfs(path, &st)
 	if err != nil {
 		return nil, err
 	}
diff --git a/shared/util_linux_cgo.go b/shared/util_linux_cgo.go
index d648a58d66..36e11163c7 100644
--- a/shared/util_linux_cgo.go
+++ b/shared/util_linux_cgo.go
@@ -10,9 +10,10 @@ import (
 	"os"
 	"sync"
 	"sync/atomic"
-	"syscall"
 	"unsafe"
 
+	"golang.org/x/sys/unix"
+
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -154,7 +155,7 @@ func GetPollRevents(fd int, timeout int, flags int) (int, int, error) {
 
 	ret := C.get_poll_revents(C.int(fd), C.int(timeout), C.int(flags), &revents, &saved_errno)
 	if int(ret) < 0 {
-		err = syscall.Errno(saved_errno)
+		err = unix.Errno(saved_errno)
 	}
 
 	return int(ret), int(revents), err
@@ -222,7 +223,7 @@ again:
 	if rv < 0 {
 		// OOM killer will take care of us if we end up doing this too
 		// often.
-		if errno == syscall.ERANGE {
+		if errno == unix.ERANGE {
 			bufSize *= 2
 			tmp := C.realloc(buf, C.size_t(bufSize))
 			if tmp == nil {
@@ -231,7 +232,7 @@ again:
 			buf = tmp
 			goto again
 		}
-		return -1, fmt.Errorf("failed user lookup: %s", syscall.Errno(rv))
+		return -1, fmt.Errorf("failed user lookup: %s", unix.Errno(rv))
 	}
 
 	if result == nil {
@@ -268,7 +269,7 @@ again:
 	if rv != 0 {
 		// OOM killer will take care of us if we end up doing this too
 		// often.
-		if errno == syscall.ERANGE {
+		if errno == unix.ERANGE {
 			bufSize *= 2
 			tmp := C.realloc(buf, C.size_t(bufSize))
 			if tmp == nil {
@@ -279,7 +280,7 @@ again:
 		}
 
 		C.free(buf)
-		return -1, fmt.Errorf("failed group lookup: %s", syscall.Errno(rv))
+		return -1, fmt.Errorf("failed group lookup: %s", unix.Errno(rv))
 	}
 	C.free(buf)
 
diff --git a/shared/util_linux_test.go b/shared/util_linux_test.go
index bd54fae4be..efd073b2e6 100644
--- a/shared/util_linux_test.go
+++ b/shared/util_linux_test.go
@@ -3,8 +3,9 @@ package shared
 import (
 	"io/ioutil"
 	"os"
-	"syscall"
 	"testing"
+
+	"golang.org/x/sys/unix"
 )
 
 func TestGetAllXattr(t *testing.T) {
@@ -32,8 +33,8 @@ func TestGetAllXattr(t *testing.T) {
 	defer os.Remove(xattrDir)
 
 	for k, v := range testxattr {
-		err = syscall.Setxattr(xattrFile.Name(), k, []byte(v), 0)
-		if err == syscall.ENOTSUP {
+		err = unix.Setxattr(xattrFile.Name(), k, []byte(v), 0)
+		if err == unix.ENOTSUP {
 			t.Log(err)
 			return
 		}
@@ -41,8 +42,8 @@ func TestGetAllXattr(t *testing.T) {
 			t.Error(err)
 			return
 		}
-		err = syscall.Setxattr(xattrDir, k, []byte(v), 0)
-		if err == syscall.ENOTSUP {
+		err = unix.Setxattr(xattrDir, k, []byte(v), 0)
+		if err == unix.ENOTSUP {
 			t.Log(err)
 			return
 		}
diff --git a/shared/util_unix.go b/shared/util_unix.go
index f87a109333..5d85ee54d5 100644
--- a/shared/util_unix.go
+++ b/shared/util_unix.go
@@ -4,12 +4,13 @@ package shared
 
 import (
 	"os"
-	"syscall"
+
+	"golang.org/x/sys/unix"
 )
 
 func GetOwnerMode(fInfo os.FileInfo) (os.FileMode, int, int) {
 	mode := fInfo.Mode()
-	uid := int(fInfo.Sys().(*syscall.Stat_t).Uid)
-	gid := int(fInfo.Sys().(*syscall.Stat_t).Gid)
+	uid := int(fInfo.Sys().(*unix.Stat_t).Uid)
+	gid := int(fInfo.Sys().(*unix.Stat_t).Gid)
 	return mode, uid, gid
 }


More information about the lxc-devel mailing list