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
|
# util/virsystemd.h
|
||||||
virSystemdCreateMachine;
|
virSystemdCreateMachine;
|
||||||
|
virSystemdMakeScopeName;
|
||||||
|
virSystemdMakeSliceName;
|
||||||
|
|
||||||
|
|
||||||
# util/virthread.h
|
# util/virthread.h
|
||||||
|
@ -27,9 +27,96 @@
|
|||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virutil.h"
|
#include "virutil.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
|
#include "virerror.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_SYSTEMD
|
#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:
|
* virSystemdCreateMachine:
|
||||||
* @name: driver unique name of the machine
|
* @name: driver unique name of the machine
|
||||||
@ -75,8 +162,8 @@ int virSystemdCreateMachine(const char *name,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (partition) {
|
if (partition) {
|
||||||
if (virAsprintf(&slicename, "%s.slice", partition) < 0)
|
if (!(slicename = virSystemdMakeSliceName(partition)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if (VIR_STRDUP(slicename, "") < 0)
|
if (VIR_STRDUP(slicename, "") < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
|
|
||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
|
|
||||||
|
char *virSystemdMakeScopeName(const char *name,
|
||||||
|
const char *drivername,
|
||||||
|
const char *slicename);
|
||||||
|
char *virSystemdMakeSliceName(const char *partition);
|
||||||
|
|
||||||
int virSystemdCreateMachine(const char *name,
|
int virSystemdCreateMachine(const char *name,
|
||||||
const char *drivername,
|
const char *drivername,
|
||||||
bool privileged,
|
bool privileged,
|
||||||
|
@ -138,6 +138,38 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
|
|||||||
return 0;
|
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
|
static int
|
||||||
mymain(void)
|
mymain(void)
|
||||||
{
|
{
|
||||||
@ -152,6 +184,23 @@ mymain(void)
|
|||||||
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
|
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
|
||||||
ret = -1;
|
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;
|
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user