[lxc-devel] [lxd/master] liblxc: detect version at runtime
brauner on Github
lxc-bot at linuxcontainers.org
Mon Oct 30 14:34:09 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 425 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171030/3405f27e/attachment.bin>
-------------- next part --------------
From d09be5aaddf3173e9c756a68cadfb369c563fcc5 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 30 Oct 2017 15:32:48 +0100
Subject: [PATCH] liblxc: detect version at runtime
This requires us to link against liblxc.
Closes #3934.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/container_lxc.go | 20 +++++++--------
lxd/migrate.go | 2 +-
shared/util_linux.go | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 0efecaf91..880221133 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -109,7 +109,7 @@ func lxcSetConfigItem(c *lxc.Container, key string, value string) error {
return fmt.Errorf("Uninitialized go-lxc struct")
}
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
switch key {
case "lxc.uts.name":
key = "lxc.utsname"
@@ -155,7 +155,7 @@ func lxcSetConfigItem(c *lxc.Container, key string, value string) error {
}
if strings.HasPrefix(key, "lxc.prlimit.") {
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
return fmt.Errorf(`Process limits require libxc >= 2.1`)
}
}
@@ -211,7 +211,7 @@ func lxcValidConfig(rawLxc string) error {
}
networkKeyPrefix := "lxc.net."
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
networkKeyPrefix = "lxc.network."
}
@@ -219,7 +219,7 @@ func lxcValidConfig(rawLxc string) error {
fields := strings.Split(key, ".")
allowedIPKeys := []string{"ipv4.address", "ipv6.address"}
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
allowedIPKeys = []string{"ipv4", "ipv6"}
}
@@ -1340,7 +1340,7 @@ func (c *containerLXC) initLXC() error {
}
networkKeyPrefix := "lxc.net"
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
networkKeyPrefix = "lxc.network"
}
@@ -1452,7 +1452,7 @@ func (c *containerLXC) initLXC() error {
// Deal with a rootfs
if tgtPath == "" {
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
// Set the rootfs backend type if supported (must happen before any other lxc.rootfs)
err := lxcSetConfigItem(cc, "lxc.rootfs.backend", "dir")
if err == nil {
@@ -1464,7 +1464,7 @@ func (c *containerLXC) initLXC() error {
}
// Set the rootfs path
- if lxc.VersionAtLeast(2, 1, 0) {
+ if shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
rootfsPath := fmt.Sprintf("dir:%s", c.RootfsPath())
err = lxcSetConfigItem(cc, "lxc.rootfs.path", rootfsPath)
} else {
@@ -1922,7 +1922,7 @@ func (c *containerLXC) startCommon() (string, error) {
}
} else if m["type"] == "nic" {
networkKeyPrefix := "lxc.net"
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
networkKeyPrefix = "lxc.network"
}
@@ -4487,7 +4487,7 @@ func (c *containerLXC) Migrate(cmd uint, stateDir string, function string, stop
/* This feature was only added in 2.0.1, let's not ask for it
* before then or migrations will fail.
*/
- if !lxc.VersionAtLeast(2, 0, 1) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 0, 1) {
preservesInodes = false
}
@@ -6922,7 +6922,7 @@ func (c *containerLXC) setNetworkPriority() error {
func (c *containerLXC) getHostInterface(name string) string {
if c.IsRunning() {
networkKeyPrefix := "lxc.net"
- if !lxc.VersionAtLeast(2, 1, 0) {
+ if !shared.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
networkKeyPrefix = "lxc.network"
}
diff --git a/lxd/migrate.go b/lxd/migrate.go
index 555fb0714..197d25a1e 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -486,7 +486,7 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
return abort(err)
}
- if lxc.VersionAtLeast(2, 0, 4) {
+ if shared.RuntimeLiblxcVersionAtLeast(2, 0, 4) {
/* What happens below is slightly convoluted. Due to various
* complications with networking, there's no easy way for criu
* to exit and leave the container in a frozen state for us to
diff --git a/shared/util_linux.go b/shared/util_linux.go
index 78d782924..80e2de9f2 100644
--- a/shared/util_linux.go
+++ b/shared/util_linux.go
@@ -12,6 +12,7 @@ import (
"path/filepath"
"reflect"
"strings"
+ "strconv"
"sync"
"sync/atomic"
"syscall"
@@ -20,7 +21,7 @@ import (
"github.com/lxc/lxd/shared/logger"
)
-// #cgo LDFLAGS: -lutil -lpthread
+// #cgo LDFLAGS: -lutil -lpthread -llxc
/*
#define _GNU_SOURCE
#include <errno.h>
@@ -37,6 +38,7 @@ import (
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
+#include <lxc/lxccontainer.h>
#ifndef AT_SYMLINK_FOLLOW
#define AT_SYMLINK_FOLLOW 0x400
@@ -864,3 +866,70 @@ func Statvfs(path string) (*syscall.Statfs_t, error) {
return &st, nil
}
+
+func RuntimeLiblxcVersionAtLeast(major int, minor int, micro int) bool {
+ version := C.GoString(C.lxc_get_version())
+ parts := strings.Split(version, ".")
+ partsLen := len(parts)
+ if partsLen == 0 {
+ return false
+ }
+
+ develParts := strings.Split(parts[partsLen - 1], "-")
+ if len(develParts) == 2 && develParts[1] == "devel" {
+ return true
+ }
+
+ maj := -1
+ min := -1
+ mic := -1
+
+ for i, v := range parts {
+ num, err := strconv.Atoi(v)
+ if err != nil {
+ return false
+ }
+
+ if i > 2 {
+ return false
+ }
+
+ switch i {
+ case 0:
+ maj = num
+ case 1:
+ min = num
+ case 2:
+ mic = num
+ }
+ }
+
+ /* Major version is greater. */
+ if maj > major {
+ return true
+ }
+
+ if maj < major {
+ return false
+ }
+
+ /* Minor number is greater.*/
+ if min > minor {
+ return true
+ }
+
+ if min < minor {
+ return false
+ }
+
+ /* Patch number is greater. */
+ if mic > micro {
+ return true
+ }
+
+ if mic < micro {
+ return false
+ }
+
+ return true
+}
More information about the lxc-devel
mailing list