mirror of https://gitee.com/openkylin/libvirt.git
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:
parent
5035279198
commit
318df5a05f
|
@ -216,6 +216,7 @@ src/util/virstorageencryption.c
|
|||
src/util/virstoragefile.c
|
||||
src/util/virstring.c
|
||||
src/util/virsysinfo.c
|
||||
src/util/virsystemd.c
|
||||
src/util/virerror.c
|
||||
src/util/virerror.h
|
||||
src/util/virtime.c
|
||||
|
|
|
@ -486,6 +486,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def)
|
|||
NULL,
|
||||
getpid(),
|
||||
true,
|
||||
0, NULL,
|
||||
def->resource->partition,
|
||||
-1,
|
||||
&cgroup) < 0)
|
||||
|
|
|
@ -769,6 +769,7 @@ qemuInitCgroup(virQEMUDriverPtr driver,
|
|||
NULL,
|
||||
vm->pid,
|
||||
false,
|
||||
0, NULL,
|
||||
vm->def->resource->partition,
|
||||
cfg->cgroupControllers,
|
||||
&priv->cgroup) < 0) {
|
||||
|
|
|
@ -1584,6 +1584,8 @@ virCgroupNewMachineSystemd(const char *name,
|
|||
const char *rootdir,
|
||||
pid_t pidleader,
|
||||
bool isContainer,
|
||||
size_t nnicindexes,
|
||||
int *nicindexes,
|
||||
const char *partition,
|
||||
int controllers,
|
||||
virCgroupPtr *group)
|
||||
|
@ -1602,6 +1604,8 @@ virCgroupNewMachineSystemd(const char *name,
|
|||
rootdir,
|
||||
pidleader,
|
||||
isContainer,
|
||||
nnicindexes,
|
||||
nicindexes,
|
||||
partition)) < 0)
|
||||
return rv;
|
||||
|
||||
|
@ -1747,6 +1751,8 @@ virCgroupNewMachine(const char *name,
|
|||
const char *rootdir,
|
||||
pid_t pidleader,
|
||||
bool isContainer,
|
||||
size_t nnicindexes,
|
||||
int *nicindexes,
|
||||
const char *partition,
|
||||
int controllers,
|
||||
virCgroupPtr *group)
|
||||
|
@ -1762,6 +1768,8 @@ virCgroupNewMachine(const char *name,
|
|||
rootdir,
|
||||
pidleader,
|
||||
isContainer,
|
||||
nnicindexes,
|
||||
nicindexes,
|
||||
partition,
|
||||
controllers,
|
||||
group)) == 0)
|
||||
|
|
|
@ -100,6 +100,8 @@ int virCgroupNewMachine(const char *name,
|
|||
const char *rootdir,
|
||||
pid_t pidleader,
|
||||
bool isContainer,
|
||||
size_t nnicindexes,
|
||||
int *nicindexes,
|
||||
const char *partition,
|
||||
int controllers,
|
||||
virCgroupPtr *group)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#endif
|
||||
|
||||
#include "virsystemd.h"
|
||||
#include "viratomic.h"
|
||||
#include "virdbus.h"
|
||||
#include "virstring.h"
|
||||
#include "viralloc.h"
|
||||
|
@ -147,7 +148,10 @@ char *virSystemdMakeMachineName(const char *name,
|
|||
* @uuid: globally unique UUID of the machine
|
||||
* @rootdir: root directory of machine filesystem
|
||||
* @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
|
||||
*/
|
||||
|
@ -158,6 +162,8 @@ int virSystemdCreateMachine(const char *name,
|
|||
const char *rootdir,
|
||||
pid_t pidleader,
|
||||
bool iscontainer,
|
||||
size_t nnicindexes,
|
||||
int *nicindexes,
|
||||
const char *partition)
|
||||
{
|
||||
int ret;
|
||||
|
@ -165,6 +171,7 @@ int virSystemdCreateMachine(const char *name,
|
|||
char *machinename = NULL;
|
||||
char *creatorname = NULL;
|
||||
char *slicename = NULL;
|
||||
static int hasCreateWithNetwork = 1;
|
||||
|
||||
ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
|
||||
if (ret < 0)
|
||||
|
@ -192,8 +199,18 @@ int virSystemdCreateMachine(const char *name,
|
|||
}
|
||||
|
||||
/*
|
||||
* The systemd DBus API we're invoking has the
|
||||
* following signature
|
||||
* The systemd DBus APIs we're invoking have the
|
||||
* 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,
|
||||
* in ay id,
|
||||
|
@ -221,38 +238,91 @@ int virSystemdCreateMachine(const char *name,
|
|||
* @root_directory: the root directory of the container, if
|
||||
* 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
|
||||
* passed on to PID 1 when creating a scope unit for your machine.
|
||||
* Will allow initial settings for the cgroup & similar.
|
||||
*
|
||||
* @path: a bus path returned for the machine object created, to
|
||||
* allow further API calls to be made against the object.
|
||||
*
|
||||
*/
|
||||
|
||||
VIR_DEBUG("Attempting to create machine via systemd");
|
||||
if (virDBusCallMethod(conn,
|
||||
NULL,
|
||||
NULL,
|
||||
"org.freedesktop.machine1",
|
||||
"/org/freedesktop/machine1",
|
||||
"org.freedesktop.machine1.Manager",
|
||||
"CreateMachine",
|
||||
"sayssusa(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 : "",
|
||||
3,
|
||||
"Slice", "s", slicename,
|
||||
"After", "as", 1, "libvirtd.service",
|
||||
"Before", "as", 1, "libvirt-guests.service") < 0)
|
||||
goto cleanup;
|
||||
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,
|
||||
NULL,
|
||||
NULL,
|
||||
"org.freedesktop.machine1",
|
||||
"/org/freedesktop/machine1",
|
||||
"org.freedesktop.machine1.Manager",
|
||||
"CreateMachine",
|
||||
"sayssusa(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 : "",
|
||||
3,
|
||||
"Slice", "s", slicename,
|
||||
"After", "as", 1, "libvirtd.service",
|
||||
"Before", "as", 1, "libvirt-guests.service") < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ int virSystemdCreateMachine(const char *name,
|
|||
const char *rootdir,
|
||||
pid_t pidleader,
|
||||
bool iscontainer,
|
||||
size_t nnicindexes,
|
||||
int *nicindexes,
|
||||
const char *partition);
|
||||
|
||||
int virSystemdTerminateMachine(const char *name,
|
||||
|
|
|
@ -146,6 +146,7 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
|
|||
"/proc/123/root",
|
||||
123,
|
||||
true,
|
||||
0, NULL,
|
||||
"highpriority.slice") < 0) {
|
||||
fprintf(stderr, "%s", "Failed to create LXC machine\n");
|
||||
return -1;
|
||||
|
@ -181,6 +182,7 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
|
|||
NULL,
|
||||
123,
|
||||
false,
|
||||
0, NULL,
|
||||
NULL) < 0) {
|
||||
fprintf(stderr, "%s", "Failed to create KVM machine\n");
|
||||
return -1;
|
||||
|
@ -220,6 +222,7 @@ static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
|
|||
NULL,
|
||||
123,
|
||||
false,
|
||||
0, NULL,
|
||||
NULL)) == 0) {
|
||||
unsetenv("FAIL_NO_SERVICE");
|
||||
fprintf(stderr, "%s", "Unexpected create machine success\n");
|
||||
|
@ -254,6 +257,7 @@ static int testCreateSystemdNotRunning(const void *opaque ATTRIBUTE_UNUSED)
|
|||
NULL,
|
||||
123,
|
||||
false,
|
||||
0, NULL,
|
||||
NULL)) == 0) {
|
||||
unsetenv("FAIL_NOT_REGISTERED");
|
||||
fprintf(stderr, "%s", "Unexpected create machine success\n");
|
||||
|
@ -288,6 +292,7 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
|
|||
NULL,
|
||||
123,
|
||||
false,
|
||||
0, NULL,
|
||||
NULL)) == 0) {
|
||||
unsetenv("FAIL_BAD_SERVICE");
|
||||
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 {
|
||||
const char *name;
|
||||
const char *partition;
|
||||
|
@ -435,6 +469,8 @@ mymain(void)
|
|||
ret = -1;
|
||||
if (virtTestRun("Test create bad systemd ", testCreateBadSystemd, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("Test create with network ", testCreateNetwork, NULL) < 0)
|
||||
ret = -1;
|
||||
|
||||
# define TEST_SCOPE(name, partition, unitname) \
|
||||
do { \
|
||||
|
|
Loading…
Reference in New Issue