Add support for systemd-machined CreateMachineWithNetwork

systemd-machined introduced a new method CreateMachineWithNetwork
that obsoletes CreateMachine. It expects to be given a list of
VETH/TAP device indexes for the host side device(s) associated
with a container/machine.

This falls back to the old CreateMachine method when the new
one is not supported.
This commit is contained in:
Daniel P. Berrange 2014-11-11 17:38:43 +00:00
parent 5035279198
commit 318df5a05f
8 changed files with 147 additions and 26 deletions

View File

@ -216,6 +216,7 @@ src/util/virstorageencryption.c
src/util/virstoragefile.c src/util/virstoragefile.c
src/util/virstring.c src/util/virstring.c
src/util/virsysinfo.c src/util/virsysinfo.c
src/util/virsystemd.c
src/util/virerror.c src/util/virerror.c
src/util/virerror.h src/util/virerror.h
src/util/virtime.c src/util/virtime.c

View File

@ -486,6 +486,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def)
NULL, NULL,
getpid(), getpid(),
true, true,
0, NULL,
def->resource->partition, def->resource->partition,
-1, -1,
&cgroup) < 0) &cgroup) < 0)

View File

@ -769,6 +769,7 @@ qemuInitCgroup(virQEMUDriverPtr driver,
NULL, NULL,
vm->pid, vm->pid,
false, false,
0, NULL,
vm->def->resource->partition, vm->def->resource->partition,
cfg->cgroupControllers, cfg->cgroupControllers,
&priv->cgroup) < 0) { &priv->cgroup) < 0) {

View File

@ -1584,6 +1584,8 @@ virCgroupNewMachineSystemd(const char *name,
const char *rootdir, const char *rootdir,
pid_t pidleader, pid_t pidleader,
bool isContainer, bool isContainer,
size_t nnicindexes,
int *nicindexes,
const char *partition, const char *partition,
int controllers, int controllers,
virCgroupPtr *group) virCgroupPtr *group)
@ -1602,6 +1604,8 @@ virCgroupNewMachineSystemd(const char *name,
rootdir, rootdir,
pidleader, pidleader,
isContainer, isContainer,
nnicindexes,
nicindexes,
partition)) < 0) partition)) < 0)
return rv; return rv;
@ -1747,6 +1751,8 @@ virCgroupNewMachine(const char *name,
const char *rootdir, const char *rootdir,
pid_t pidleader, pid_t pidleader,
bool isContainer, bool isContainer,
size_t nnicindexes,
int *nicindexes,
const char *partition, const char *partition,
int controllers, int controllers,
virCgroupPtr *group) virCgroupPtr *group)
@ -1762,6 +1768,8 @@ virCgroupNewMachine(const char *name,
rootdir, rootdir,
pidleader, pidleader,
isContainer, isContainer,
nnicindexes,
nicindexes,
partition, partition,
controllers, controllers,
group)) == 0) group)) == 0)

View File

@ -100,6 +100,8 @@ int virCgroupNewMachine(const char *name,
const char *rootdir, const char *rootdir,
pid_t pidleader, pid_t pidleader,
bool isContainer, bool isContainer,
size_t nnicindexes,
int *nicindexes,
const char *partition, const char *partition,
int controllers, int controllers,
virCgroupPtr *group) virCgroupPtr *group)

View File

@ -26,6 +26,7 @@
#endif #endif
#include "virsystemd.h" #include "virsystemd.h"
#include "viratomic.h"
#include "virdbus.h" #include "virdbus.h"
#include "virstring.h" #include "virstring.h"
#include "viralloc.h" #include "viralloc.h"
@ -147,7 +148,10 @@ char *virSystemdMakeMachineName(const char *name,
* @uuid: globally unique UUID of the machine * @uuid: globally unique UUID of the machine
* @rootdir: root directory of machine filesystem * @rootdir: root directory of machine filesystem
* @pidleader: PID of the leader process * @pidleader: PID of the leader process
* @slice: name of the slice to place the machine in * @iscontainer: true if a container, false if a VM
* @nnicindexes: number of network interface indexes in list
* @nicindexes: list of network interface indexes
* @partition: name of the slice to place the machine in
* *
* Returns 0 on success, -1 on fatal error, or -2 if systemd-machine is not available * Returns 0 on success, -1 on fatal error, or -2 if systemd-machine is not available
*/ */
@ -158,6 +162,8 @@ int virSystemdCreateMachine(const char *name,
const char *rootdir, const char *rootdir,
pid_t pidleader, pid_t pidleader,
bool iscontainer, bool iscontainer,
size_t nnicindexes,
int *nicindexes,
const char *partition) const char *partition)
{ {
int ret; int ret;
@ -165,6 +171,7 @@ int virSystemdCreateMachine(const char *name,
char *machinename = NULL; char *machinename = NULL;
char *creatorname = NULL; char *creatorname = NULL;
char *slicename = NULL; char *slicename = NULL;
static int hasCreateWithNetwork = 1;
ret = virDBusIsServiceEnabled("org.freedesktop.machine1"); ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
if (ret < 0) if (ret < 0)
@ -192,8 +199,18 @@ int virSystemdCreateMachine(const char *name,
} }
/* /*
* The systemd DBus API we're invoking has the * The systemd DBus APIs we're invoking have the
* following signature * following signature(s)
*
* CreateMachineWithNetwork(in s name,
* in ay id,
* in s service,
* in s class,
* in u leader,
* in s root_directory,
* in ai nicindexes
* in a(sv) scope_properties,
* out o path);
* *
* CreateMachine(in s name, * CreateMachine(in s name,
* in ay id, * in ay id,
@ -221,15 +238,67 @@ int virSystemdCreateMachine(const char *name,
* @root_directory: the root directory of the container, if * @root_directory: the root directory of the container, if
* this is known & visible in the host filesystem, or empty string * this is known & visible in the host filesystem, or empty string
* *
* @nicindexes: list of network interface indexes for the
* host end of the VETH device pairs.
*
* @scope_properties:an array (not a dict!) of properties that are * @scope_properties:an array (not a dict!) of properties that are
* passed on to PID 1 when creating a scope unit for your machine. * passed on to PID 1 when creating a scope unit for your machine.
* Will allow initial settings for the cgroup & similar. * Will allow initial settings for the cgroup & similar.
* *
* @path: a bus path returned for the machine object created, to * @path: a bus path returned for the machine object created, to
* allow further API calls to be made against the object. * allow further API calls to be made against the object.
*
*/ */
VIR_DEBUG("Attempting to create machine via systemd"); VIR_DEBUG("Attempting to create machine via systemd");
if (virAtomicIntGet(&hasCreateWithNetwork)) {
DBusError error;
dbus_error_init(&error);
if (virDBusCallMethod(conn,
NULL,
&error,
"org.freedesktop.machine1",
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
"CreateMachineWithNetwork",
"sayssusa&ia(sv)",
machinename,
16,
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11],
uuid[12], uuid[13], uuid[14], uuid[15],
creatorname,
iscontainer ? "container" : "vm",
(unsigned int)pidleader,
rootdir ? rootdir : "",
nnicindexes, nicindexes,
3,
"Slice", "s", slicename,
"After", "as", 1, "libvirtd.service",
"Before", "as", 1, "libvirt-guests.service") < 0)
goto cleanup;
if (dbus_error_is_set(&error)) {
if (STREQ_NULLABLE("org.freedesktop.DBus.Error.UnknownMethod",
error.name)) {
VIR_INFO("CreateMachineWithNetwork isn't supported, switching "
"to legacy CreateMachine method for systemd-machined");
dbus_error_free(&error);
virAtomicIntSet(&hasCreateWithNetwork, 0);
/* Could re-structure without Using goto, but this
* avoids another atomic read which would trigger
* another memory barrier */
goto fallback;
}
virReportError(VIR_ERR_DBUS_SERVICE,
_("CreateMachineWithNetwork: %s"),
error.message ? error.message : _("unknown error"));
goto cleanup;
}
} else {
fallback:
if (virDBusCallMethod(conn, if (virDBusCallMethod(conn,
NULL, NULL,
NULL, NULL,
@ -253,6 +322,7 @@ int virSystemdCreateMachine(const char *name,
"After", "as", 1, "libvirtd.service", "After", "as", 1, "libvirtd.service",
"Before", "as", 1, "libvirt-guests.service") < 0) "Before", "as", 1, "libvirt-guests.service") < 0)
goto cleanup; goto cleanup;
}
ret = 0; ret = 0;

View File

@ -40,6 +40,8 @@ int virSystemdCreateMachine(const char *name,
const char *rootdir, const char *rootdir,
pid_t pidleader, pid_t pidleader,
bool iscontainer, bool iscontainer,
size_t nnicindexes,
int *nicindexes,
const char *partition); const char *partition);
int virSystemdTerminateMachine(const char *name, int virSystemdTerminateMachine(const char *name,

View File

@ -146,6 +146,7 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
"/proc/123/root", "/proc/123/root",
123, 123,
true, true,
0, NULL,
"highpriority.slice") < 0) { "highpriority.slice") < 0) {
fprintf(stderr, "%s", "Failed to create LXC machine\n"); fprintf(stderr, "%s", "Failed to create LXC machine\n");
return -1; return -1;
@ -181,6 +182,7 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
NULL, NULL,
123, 123,
false, false,
0, NULL,
NULL) < 0) { NULL) < 0) {
fprintf(stderr, "%s", "Failed to create KVM machine\n"); fprintf(stderr, "%s", "Failed to create KVM machine\n");
return -1; return -1;
@ -220,6 +222,7 @@ static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
NULL, NULL,
123, 123,
false, false,
0, NULL,
NULL)) == 0) { NULL)) == 0) {
unsetenv("FAIL_NO_SERVICE"); unsetenv("FAIL_NO_SERVICE");
fprintf(stderr, "%s", "Unexpected create machine success\n"); fprintf(stderr, "%s", "Unexpected create machine success\n");
@ -254,6 +257,7 @@ static int testCreateSystemdNotRunning(const void *opaque ATTRIBUTE_UNUSED)
NULL, NULL,
123, 123,
false, false,
0, NULL,
NULL)) == 0) { NULL)) == 0) {
unsetenv("FAIL_NOT_REGISTERED"); unsetenv("FAIL_NOT_REGISTERED");
fprintf(stderr, "%s", "Unexpected create machine success\n"); fprintf(stderr, "%s", "Unexpected create machine success\n");
@ -288,6 +292,7 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
NULL, NULL,
123, 123,
false, false,
0, NULL,
NULL)) == 0) { NULL)) == 0) {
unsetenv("FAIL_BAD_SERVICE"); unsetenv("FAIL_BAD_SERVICE");
fprintf(stderr, "%s", "Unexpected create machine success\n"); fprintf(stderr, "%s", "Unexpected create machine success\n");
@ -304,6 +309,35 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
} }
static int testCreateNetwork(const void *opaque ATTRIBUTE_UNUSED)
{
unsigned char uuid[VIR_UUID_BUFLEN] = {
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4
};
int nicindexes[] = {
2, 1729, 87539319,
};
size_t nnicindexes = ARRAY_CARDINALITY(nicindexes);
if (virSystemdCreateMachine("demo",
"lxc",
true,
uuid,
"/proc/123/root",
123,
true,
nnicindexes, nicindexes,
"highpriority.slice") < 0) {
fprintf(stderr, "%s", "Failed to create LXC machine\n");
return -1;
}
return 0;
}
struct testScopeData { struct testScopeData {
const char *name; const char *name;
const char *partition; const char *partition;
@ -435,6 +469,8 @@ mymain(void)
ret = -1; ret = -1;
if (virtTestRun("Test create bad systemd ", testCreateBadSystemd, NULL) < 0) if (virtTestRun("Test create bad systemd ", testCreateBadSystemd, NULL) < 0)
ret = -1; ret = -1;
if (virtTestRun("Test create with network ", testCreateNetwork, NULL) < 0)
ret = -1;
# define TEST_SCOPE(name, partition, unitname) \ # define TEST_SCOPE(name, partition, unitname) \
do { \ do { \