mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
Add APIs for formatting systemd slice/scope names
There are some interesting escaping rules to consider when dealing with systemd slice/scope names. Thus it is helpful to have APIs for formatting names Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
2d95e8b100
commit
4574b475df
@ -1936,6 +1936,8 @@ virSysinfoSetup;
|
||||
|
||||
# util/virsystemd.h
|
||||
virSystemdCreateMachine;
|
||||
virSystemdMakeScopeName;
|
||||
virSystemdMakeSliceName;
|
||||
|
||||
|
||||
# util/virthread.h
|
||||
|
@ -27,9 +27,96 @@
|
||||
#include "viralloc.h"
|
||||
#include "virutil.h"
|
||||
#include "virlog.h"
|
||||
#include "virerror.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_SYSTEMD
|
||||
|
||||
|
||||
static void virSystemdEscapeName(virBufferPtr buf,
|
||||
const char *name)
|
||||
{
|
||||
static const char hextable[16] = "0123456789abcdef";
|
||||
|
||||
#define ESCAPE(c) \
|
||||
do { \
|
||||
virBufferAddChar(buf, '\\'); \
|
||||
virBufferAddChar(buf, 'x'); \
|
||||
virBufferAddChar(buf, hextable[(c >> 4) & 15]); \
|
||||
virBufferAddChar(buf, hextable[c & 15]); \
|
||||
} while (0)
|
||||
|
||||
#define VALID_CHARS \
|
||||
"0123456789" \
|
||||
"abcdefghijklmnopqrstuvwxyz" \
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||
":-_.\\"
|
||||
|
||||
if (*name == '.') {
|
||||
ESCAPE(*name);
|
||||
name++;
|
||||
}
|
||||
|
||||
while (*name) {
|
||||
if (*name == '/')
|
||||
virBufferAddChar(buf, '-');
|
||||
else if (*name == '-' ||
|
||||
*name == '\\' ||
|
||||
!strchr(VALID_CHARS, *name))
|
||||
ESCAPE(*name);
|
||||
else
|
||||
virBufferAddChar(buf, *name);
|
||||
name++;
|
||||
}
|
||||
|
||||
#undef ESCAPE
|
||||
#undef VALID_CHARS
|
||||
}
|
||||
|
||||
|
||||
char *virSystemdMakeScopeName(const char *name,
|
||||
const char *drivername,
|
||||
const char *partition)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
if (*partition == '/')
|
||||
partition++;
|
||||
|
||||
virSystemdEscapeName(&buf, partition);
|
||||
virBufferAddChar(&buf, '-');
|
||||
virSystemdEscapeName(&buf, drivername);
|
||||
virBufferAddLit(&buf, "\\x2d");
|
||||
virSystemdEscapeName(&buf, name);
|
||||
virBufferAddLit(&buf, ".scope");
|
||||
|
||||
if (virBufferError(&buf)) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return virBufferContentAndReset(&buf);
|
||||
}
|
||||
|
||||
|
||||
char *virSystemdMakeSliceName(const char *partition)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
if (*partition == '/')
|
||||
partition++;
|
||||
|
||||
virSystemdEscapeName(&buf, partition);
|
||||
virBufferAddLit(&buf, ".slice");
|
||||
|
||||
if (virBufferError(&buf)) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return virBufferContentAndReset(&buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virSystemdCreateMachine:
|
||||
* @name: driver unique name of the machine
|
||||
@ -75,8 +162,8 @@ int virSystemdCreateMachine(const char *name,
|
||||
goto cleanup;
|
||||
|
||||
if (partition) {
|
||||
if (virAsprintf(&slicename, "%s.slice", partition) < 0)
|
||||
goto cleanup;
|
||||
if (!(slicename = virSystemdMakeSliceName(partition)))
|
||||
goto cleanup;
|
||||
} else {
|
||||
if (VIR_STRDUP(slicename, "") < 0)
|
||||
goto cleanup;
|
||||
|
@ -24,6 +24,11 @@
|
||||
|
||||
# include "internal.h"
|
||||
|
||||
char *virSystemdMakeScopeName(const char *name,
|
||||
const char *drivername,
|
||||
const char *slicename);
|
||||
char *virSystemdMakeSliceName(const char *partition);
|
||||
|
||||
int virSystemdCreateMachine(const char *name,
|
||||
const char *drivername,
|
||||
bool privileged,
|
||||
|
@ -138,6 +138,38 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct testScopeData {
|
||||
const char *name;
|
||||
const char *partition;
|
||||
const char *expected;
|
||||
};
|
||||
|
||||
static int
|
||||
testScopeName(const void *opaque)
|
||||
{
|
||||
const struct testScopeData *data = opaque;
|
||||
int ret = -1;
|
||||
char *actual = NULL;
|
||||
|
||||
if (!(actual = virSystemdMakeScopeName(data->name,
|
||||
"lxc",
|
||||
data->partition)))
|
||||
goto cleanup;
|
||||
|
||||
if (STRNEQ(actual, data->expected)) {
|
||||
fprintf(stderr, "Expected '%s' but got '%s'\n",
|
||||
data->expected, actual);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(actual);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mymain(void)
|
||||
{
|
||||
@ -152,6 +184,23 @@ mymain(void)
|
||||
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
|
||||
ret = -1;
|
||||
|
||||
#define TEST_SCOPE(name, partition, unitname) \
|
||||
do { \
|
||||
struct testScopeData data = { \
|
||||
name, partition, unitname \
|
||||
}; \
|
||||
if (virtTestRun("Test scopename", 1, testScopeName, &data) < 0) \
|
||||
ret = -1; \
|
||||
} while (0)
|
||||
|
||||
TEST_SCOPE("demo", "/machine", "machine-lxc\\x2ddemo.scope");
|
||||
TEST_SCOPE("demo-name", "/machine", "machine-lxc\\x2ddemo\\x2dname.scope");
|
||||
TEST_SCOPE("demo!name", "/machine", "machine-lxc\\x2ddemo\\x21name.scope");
|
||||
TEST_SCOPE(".demo", "/machine", "machine-lxc\\x2d\\x2edemo.scope");
|
||||
TEST_SCOPE("demo", "/machine/eng-dept", "machine-eng\\x2ddept-lxc\\x2ddemo.scope");
|
||||
TEST_SCOPE("demo", "/machine/eng-dept/testing!stuff",
|
||||
"machine-eng\\x2ddept-testing\\x21stuff-lxc\\x2ddemo.scope");
|
||||
|
||||
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user