|
|
43fe83 |
From 640ff93b2835c02f2f317912e7e2abb20cf3c35d Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <640ff93b2835c02f2f317912e7e2abb20cf3c35d.1375465853.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
|
43fe83 |
Date: Wed, 31 Jul 2013 19:48:17 +0100
|
|
|
43fe83 |
Subject: [PATCH] Add APIs for formatting systemd slice/scope names
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=980929
|
|
|
43fe83 |
|
|
|
43fe83 |
There are some interesting escaping rules to consider when dealing
|
|
|
43fe83 |
with systemd slice/scope names. Thus it is helpful to have APIs
|
|
|
43fe83 |
for formatting names
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit 4574b475df830da437aa6384fd1452cecbb4b7d2)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/libvirt_private.syms | 2 ++
|
|
|
43fe83 |
src/util/virsystemd.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
43fe83 |
src/util/virsystemd.h | 5 +++
|
|
|
43fe83 |
tests/virsystemdtest.c | 49 ++++++++++++++++++++++++++
|
|
|
43fe83 |
4 files changed, 145 insertions(+), 2 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
43fe83 |
index d9615ea..0247a46 100644
|
|
|
43fe83 |
--- a/src/libvirt_private.syms
|
|
|
43fe83 |
+++ b/src/libvirt_private.syms
|
|
|
43fe83 |
@@ -1935,6 +1935,8 @@ virSysinfoSetup;
|
|
|
43fe83 |
|
|
|
43fe83 |
# util/virsystemd.h
|
|
|
43fe83 |
virSystemdCreateMachine;
|
|
|
43fe83 |
+virSystemdMakeScopeName;
|
|
|
43fe83 |
+virSystemdMakeSliceName;
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
# util/virthread.h
|
|
|
43fe83 |
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
|
|
|
43fe83 |
index 11d1153..251b846 100644
|
|
|
43fe83 |
--- a/src/util/virsystemd.c
|
|
|
43fe83 |
+++ b/src/util/virsystemd.c
|
|
|
43fe83 |
@@ -27,9 +27,96 @@
|
|
|
43fe83 |
#include "viralloc.h"
|
|
|
43fe83 |
#include "virutil.h"
|
|
|
43fe83 |
#include "virlog.h"
|
|
|
43fe83 |
+#include "virerror.h"
|
|
|
43fe83 |
|
|
|
43fe83 |
#define VIR_FROM_THIS VIR_FROM_SYSTEMD
|
|
|
43fe83 |
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static void virSystemdEscapeName(virBufferPtr buf,
|
|
|
43fe83 |
+ const char *name)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ static const char hextable[16] = "0123456789abcdef";
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#define ESCAPE(c) \
|
|
|
43fe83 |
+ do { \
|
|
|
43fe83 |
+ virBufferAddChar(buf, '\\'); \
|
|
|
43fe83 |
+ virBufferAddChar(buf, 'x'); \
|
|
|
43fe83 |
+ virBufferAddChar(buf, hextable[(c >> 4) & 15]); \
|
|
|
43fe83 |
+ virBufferAddChar(buf, hextable[c & 15]); \
|
|
|
43fe83 |
+ } while (0)
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#define VALID_CHARS \
|
|
|
43fe83 |
+ "0123456789" \
|
|
|
43fe83 |
+ "abcdefghijklmnopqrstuvwxyz" \
|
|
|
43fe83 |
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
|
|
43fe83 |
+ ":-_.\\"
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (*name == '.') {
|
|
|
43fe83 |
+ ESCAPE(*name);
|
|
|
43fe83 |
+ name++;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ while (*name) {
|
|
|
43fe83 |
+ if (*name == '/')
|
|
|
43fe83 |
+ virBufferAddChar(buf, '-');
|
|
|
43fe83 |
+ else if (*name == '-' ||
|
|
|
43fe83 |
+ *name == '\\' ||
|
|
|
43fe83 |
+ !strchr(VALID_CHARS, *name))
|
|
|
43fe83 |
+ ESCAPE(*name);
|
|
|
43fe83 |
+ else
|
|
|
43fe83 |
+ virBufferAddChar(buf, *name);
|
|
|
43fe83 |
+ name++;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#undef ESCAPE
|
|
|
43fe83 |
+#undef VALID_CHARS
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+char *virSystemdMakeScopeName(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ const char *partition)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (*partition == '/')
|
|
|
43fe83 |
+ partition++;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ virSystemdEscapeName(&buf, partition);
|
|
|
43fe83 |
+ virBufferAddChar(&buf, '-');
|
|
|
43fe83 |
+ virSystemdEscapeName(&buf, drivername);
|
|
|
43fe83 |
+ virBufferAddLit(&buf, "\\x2d");
|
|
|
43fe83 |
+ virSystemdEscapeName(&buf, name);
|
|
|
43fe83 |
+ virBufferAddLit(&buf, ".scope");
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virBufferError(&buf)) {
|
|
|
43fe83 |
+ virReportOOMError();
|
|
|
43fe83 |
+ return NULL;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ return virBufferContentAndReset(&buf;;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+char *virSystemdMakeSliceName(const char *partition)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (*partition == '/')
|
|
|
43fe83 |
+ partition++;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ virSystemdEscapeName(&buf, partition);
|
|
|
43fe83 |
+ virBufferAddLit(&buf, ".slice");
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virBufferError(&buf)) {
|
|
|
43fe83 |
+ virReportOOMError();
|
|
|
43fe83 |
+ return NULL;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ return virBufferContentAndReset(&buf;;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
/**
|
|
|
43fe83 |
* virSystemdCreateMachine:
|
|
|
43fe83 |
* @name: driver unique name of the machine
|
|
|
43fe83 |
@@ -75,8 +162,8 @@ int virSystemdCreateMachine(const char *name,
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
|
|
|
43fe83 |
if (partition) {
|
|
|
43fe83 |
- if (virAsprintf(&slicename, "%s.slice", partition) < 0)
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
+ if (!(slicename = virSystemdMakeSliceName(partition)))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
} else {
|
|
|
43fe83 |
if (VIR_STRDUP(slicename, "") < 0)
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h
|
|
|
43fe83 |
index 9ca4e0b..414ae5a 100644
|
|
|
43fe83 |
--- a/src/util/virsystemd.h
|
|
|
43fe83 |
+++ b/src/util/virsystemd.h
|
|
|
43fe83 |
@@ -24,6 +24,11 @@
|
|
|
43fe83 |
|
|
|
43fe83 |
# include "internal.h"
|
|
|
43fe83 |
|
|
|
43fe83 |
+char *virSystemdMakeScopeName(const char *name,
|
|
|
43fe83 |
+ const char *drivername,
|
|
|
43fe83 |
+ const char *slicename);
|
|
|
43fe83 |
+char *virSystemdMakeSliceName(const char *partition);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
int virSystemdCreateMachine(const char *name,
|
|
|
43fe83 |
const char *drivername,
|
|
|
43fe83 |
bool privileged,
|
|
|
43fe83 |
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
|
|
|
43fe83 |
index bcf3ad3..a9c6d32 100644
|
|
|
43fe83 |
--- a/tests/virsystemdtest.c
|
|
|
43fe83 |
+++ b/tests/virsystemdtest.c
|
|
|
43fe83 |
@@ -138,6 +138,38 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+struct testScopeData {
|
|
|
43fe83 |
+ const char *name;
|
|
|
43fe83 |
+ const char *partition;
|
|
|
43fe83 |
+ const char *expected;
|
|
|
43fe83 |
+};
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static int
|
|
|
43fe83 |
+testScopeName(const void *opaque)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ const struct testScopeData *data = opaque;
|
|
|
43fe83 |
+ int ret = -1;
|
|
|
43fe83 |
+ char *actual = NULL;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (!(actual = virSystemdMakeScopeName(data->name,
|
|
|
43fe83 |
+ "lxc",
|
|
|
43fe83 |
+ data->partition)))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (STRNEQ(actual, data->expected)) {
|
|
|
43fe83 |
+ fprintf(stderr, "Expected '%s' but got '%s'\n",
|
|
|
43fe83 |
+ data->expected, actual);
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = 0;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ cleanup:
|
|
|
43fe83 |
+ VIR_FREE(actual);
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
static int
|
|
|
43fe83 |
mymain(void)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
@@ -152,6 +184,23 @@ mymain(void)
|
|
|
43fe83 |
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
|
|
|
43fe83 |
ret = -1;
|
|
|
43fe83 |
|
|
|
43fe83 |
+#define TEST_SCOPE(name, partition, unitname) \
|
|
|
43fe83 |
+ do { \
|
|
|
43fe83 |
+ struct testScopeData data = { \
|
|
|
43fe83 |
+ name, partition, unitname \
|
|
|
43fe83 |
+ }; \
|
|
|
43fe83 |
+ if (virtTestRun("Test scopename", 1, testScopeName, &data) < 0) \
|
|
|
43fe83 |
+ ret = -1; \
|
|
|
43fe83 |
+ } while (0)
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ TEST_SCOPE("demo", "/machine", "machine-lxc\\x2ddemo.scope");
|
|
|
43fe83 |
+ TEST_SCOPE("demo-name", "/machine", "machine-lxc\\x2ddemo\\x2dname.scope");
|
|
|
43fe83 |
+ TEST_SCOPE("demo!name", "/machine", "machine-lxc\\x2ddemo\\x21name.scope");
|
|
|
43fe83 |
+ TEST_SCOPE(".demo", "/machine", "machine-lxc\\x2d\\x2edemo.scope");
|
|
|
43fe83 |
+ TEST_SCOPE("demo", "/machine/eng-dept", "machine-eng\\x2ddept-lxc\\x2ddemo.scope");
|
|
|
43fe83 |
+ TEST_SCOPE("demo", "/machine/eng-dept/testing!stuff",
|
|
|
43fe83 |
+ "machine-eng\\x2ddept-testing\\x21stuff-lxc\\x2ddemo.scope");
|
|
|
43fe83 |
+
|
|
|
43fe83 |
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|