/tests/virshtest
/tests/virstoragetest
/tests/virstringtest
+/tests/virsystemdtest
/tests/virtimetest
/tests/viruritest
/tests/vmx2xmltest
# Require whitespace immediately after keywords,
# but none after the opening bracket
- while ($data =~ /(if|for|while|switch|return)\(/ ||
- $data =~ /(if|for|while|switch|return)\s+\(\s/) {
+ while ($data =~ /\b(if|for|while|switch|return)\(/ ||
+ $data =~ /\b(if|for|while|switch|return)\s+\(\s/) {
print "$file:$.: $line";
$ret = 1;
last;
VIR_FROM_CGROUP = 54, /* Error from cgroups */
VIR_FROM_ACCESS = 55, /* Error from access control manager */
+ VIR_FROM_SYSTEMD = 56, /* Error from systemd code */
# ifdef VIR_ENUM_SENTINELS
VIR_ERR_DOMAIN_LAST
util/virstoragefile.c util/virstoragefile.h \
util/virstring.h util/virstring.c \
util/virsysinfo.c util/virsysinfo.h \
+ util/virsystemd.c util/virsystemd.h \
util/virthread.c util/virthread.h \
util/virthreadpthread.h \
util/virthreadwin32.h \
virSysinfoSetup;
+# util/virsystemd.h
+virSystemdCreateMachine;
+
+
# util/virthread.h
virCondBroadcast;
virCondDestroy;
"Cgroup",
"Access Manager", /* 55 */
+ "Systemd",
)
--- /dev/null
+/*
+ * virsystemd.c: helpers for using systemd APIs
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <config.h>
+
+#include "virsystemd.h"
+#include "virdbus.h"
+#include "virstring.h"
+#include "viralloc.h"
+#include "virutil.h"
+
+#define VIR_FROM_THIS VIR_FROM_SYSTEMD
+
+/**
+ * virSystemdCreateMachine:
+ * @name: driver unique name of the machine
+ * @drivername: name of the virt driver
+ * @privileged: whether driver is running privileged or per user
+ * @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
+ */
+int virSystemdCreateMachine(const char *name,
+ const char *drivername,
+ bool privileged,
+ const unsigned char *uuid,
+ const char *rootdir,
+ pid_t pidleader,
+ bool iscontainer,
+ const char *partition)
+{
+ int ret = -1;
+ DBusConnection *conn;
+ char *machinename = NULL;
+ char *creatorname = NULL;
+ char *username = NULL;
+ char *slicename = NULL;
+
+ if (!(conn = virDBusGetSystemBus()))
+ return -1;
+
+ if (privileged) {
+ if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
+ goto cleanup;
+ } else {
+ if (!(username = virGetUserName(geteuid())))
+ goto cleanup;
+ if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
+ goto cleanup;
+ }
+
+ if (virAsprintf(&creatorname, "libvirt-%s", drivername) < 0)
+ goto cleanup;
+
+ if (partition) {
+ if (virAsprintf(&slicename, "%s.slice", partition) < 0)
+ goto cleanup;
+ } else {
+ if (VIR_STRDUP(slicename, "") < 0)
+ goto cleanup;
+ }
+
+ /*
+ * The systemd DBus API we're invoking has the
+ * following signature
+ *
+ * CreateMachine(in s name,
+ * in ay id,
+ * in s service,
+ * in s class,
+ * in u leader,
+ * in s root_directory,
+ * in a(sv) scope_properties,
+ * out o path);
+ *
+ * @name a host unique name for the machine. shows up
+ * in 'ps' listing & similar
+ *
+ * @id: a UUID of the machine, ideally matching /etc/machine-id
+ * for containers
+ *
+ * @service: identifier of the client ie "libvirt-lxc"
+ *
+ * @class: either the string "container" or "vm" depending
+ * on the type of machine
+ *
+ * @leader: main PID of the machine, either the host emulator
+ * process, or the 'init' PID of the container
+ *
+ * @root_directory: the root directory of the container, if
+ * this is known & visible in the host filesystem, or empty string
+ *
+ * @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.
+ */
+
+ if (virDBusCallMethod(conn,
+ 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 : "",
+ 1, "Slice", "s",
+ slicename) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(username);
+ VIR_FREE(creatorname);
+ VIR_FREE(machinename);
+ return ret;
+}
--- /dev/null
+/*
+ * virsystemd.h: helpers for using systemd APIs
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __VIR_SYSTEMD_H__
+# define __VIR_SYSTEMD_H__
+
+# include "internal.h"
+
+int virSystemdCreateMachine(const char *name,
+ const char *drivername,
+ bool privileged,
+ const unsigned char *uuid,
+ const char *rootdir,
+ pid_t pidleader,
+ bool iscontainer,
+ const char *partition);
+
+#endif /* __VIR_SYSTEMD_H__ */
$(NULL)
if WITH_DBUS
-test_programs += virdbustest
+test_programs += virdbustest \
+ virsystemdtest
endif
-
if WITH_GNUTLS
test_programs += virnettlscontexttest
endif
test_libraries += libqemumonitortestutils.la
endif
+if WITH_DBUS
+test_libraries += virsystemdmock.la
+endif
+
if WITH_TESTS
noinst_PROGRAMS = $(test_programs) $(test_helpers)
noinst_LTLIBRARIES = $(test_libraries)
virdbustest.c testutils.h testutils.c
virdbustest_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
virdbustest_LDADD = $(LDADDS)
+
+virsystemdtest_SOURCES = \
+ virsystemdtest.c testutils.h testutils.c
+virsystemdtest_CFLAGS = $(AM_CFLAGS)
+virsystemdtest_LDADD = $(LDADDS)
+
+virsystemdmock_la_SOURCES = \
+ virsystemdmock.c
+virsystemdmock_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+virsystemdmock_la_LDFLAGS = -module -avoid-version \
+ -rpath /evil/libtool/hack/to/force/shared/lib/creation
+
else
-EXTRA_DIST += virdbustest.c
+EXTRA_DIST += virdbustest.c virsystemdtest.c virsystemdmock.c
endif
viruritest_SOURCES = \
# include <stdio.h>
# include "viralloc.h"
+# include "virfile.h"
+# include "virstring.h"
# define EXIT_AM_SKIP 77 /* tell Automake we're skipping a test */
# define EXIT_AM_HARDFAIL 99 /* tell Automake that the framework is broken */
--- /dev/null
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include "internal.h"
+
+#include <stdlib.h>
+
+#include <dbus/dbus.h>
+
+void dbus_connection_set_change_sigpipe(dbus_bool_t will_modify_sigpipe ATTRIBUTE_UNUSED)
+{
+}
+
+dbus_bool_t dbus_threads_init_default(void)
+{
+ return 1;
+}
+
+DBusConnection *dbus_bus_get(DBusBusType type ATTRIBUTE_UNUSED,
+ DBusError *error ATTRIBUTE_UNUSED)
+{
+ return (DBusConnection *)0x1;
+}
+
+void dbus_connection_set_exit_on_disconnect(DBusConnection *connection ATTRIBUTE_UNUSED,
+ dbus_bool_t exit_on_disconnect ATTRIBUTE_UNUSED)
+{
+}
+
+
+dbus_bool_t dbus_connection_set_watch_functions(DBusConnection *connection ATTRIBUTE_UNUSED,
+ DBusAddWatchFunction add_function ATTRIBUTE_UNUSED,
+ DBusRemoveWatchFunction remove_function ATTRIBUTE_UNUSED,
+ DBusWatchToggledFunction toggled_function ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ DBusFreeFunction free_data_function ATTRIBUTE_UNUSED)
+{
+ return 1;
+}
+
+DBusMessage *dbus_connection_send_with_reply_and_block(DBusConnection *connection ATTRIBUTE_UNUSED,
+ DBusMessage *message,
+ int timeout_milliseconds ATTRIBUTE_UNUSED,
+ DBusError *error ATTRIBUTE_UNUSED)
+{
+ DBusMessage *reply;
+
+ dbus_message_set_serial(message, 7);
+
+ if (getenv("FAIL_NO_SERVICE"))
+ reply = dbus_message_new_error(message,
+ "org.freedesktop.DBus.Error.ServiceUnknown",
+ "The name org.freedesktop.machine1 was not provided by any .service files");
+ else
+ reply = dbus_message_new_method_return(message);
+
+ return reply;
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "virsystemd.h"
+#include "virlog.h"
+#include "testutils.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+static int testCreateContainer(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
+ };
+ if (virSystemdCreateMachine("demo",
+ "lxc",
+ true,
+ uuid,
+ "/proc/123/root",
+ 123,
+ true,
+ "highpriority.slice") < 0) {
+ fprintf(stderr, "%s", "Failed to create LXC machine\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int testCreateMachine(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
+ };
+ if (virSystemdCreateMachine("demo",
+ "qemu",
+ false,
+ uuid,
+ NULL,
+ 123,
+ false,
+ NULL) < 0) {
+ fprintf(stderr, "%s", "Failed to create KVM machine\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int testCreateNoSystemd(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
+ };
+
+ setenv("FAIL_NO_SERVICE", "1", 1);
+
+ if (virSystemdCreateMachine("demo",
+ "qemu",
+ true,
+ uuid,
+ NULL,
+ 123,
+ false,
+ NULL) == 0) {
+ fprintf(stderr, "%s", "Unexpected create machine success\n");
+ return -1;
+ }
+
+ virErrorPtr err = virGetLastError();
+
+ if (!err) {
+ fprintf(stderr, "No error raised");
+ return -1;
+ }
+
+ if (err->code == VIR_ERR_DBUS_SERVICE &&
+ STREQ(err->str2, "org.freedesktop.DBus.Error.ServiceUnknown"))
+ return 0;
+
+ fprintf(stderr, "Unexpected error code %d / message %s\n",
+ err->code, err->str2);
+ return -1;
+}
+
+static int
+mymain(void)
+{
+ int ret = 0;
+
+ if (virtTestRun("Test create container ", 1, testCreateContainer, NULL) < 0)
+ ret = -1;
+ if (virtTestRun("Test create machine ", 1, testCreateMachine, NULL) < 0)
+ ret = -1;
+ if (virtTestRun("Test create nosystemd ", 1, testCreateNoSystemd, NULL) < 0)
+ ret = -1;
+
+ return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virsystemdmock.so")