summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
authorLaurent Léonard <laurent@open-minds.org>2010-07-05 18:38:41 +0200
committerLaurent Léonard <laurent@open-minds.org>2010-07-05 18:38:41 +0200
commit02cd3d58b0009f3a3fcd3c5466f4b954eaf84b2b (patch)
tree1c33e5ded76e709487e70181655c46cc858ec1e1 /daemon
parent647cbd63e43bc2ec6942c99c18dede066dc2b368 (diff)
Imported Upstream version 0.8.2
Diffstat (limited to 'daemon')
-rw-r--r--daemon/Makefile.am17
-rw-r--r--daemon/Makefile.in61
-rw-r--r--daemon/THREADING.txt52
-rw-r--r--daemon/libvirt-guests.init.in304
-rw-r--r--daemon/libvirt-guests.sysconf24
-rw-r--r--daemon/libvirtd.c225
-rw-r--r--daemon/libvirtd.conf13
-rw-r--r--daemon/libvirtd.h1
-rw-r--r--daemon/libvirtd.init.in9
-rw-r--r--daemon/libvirtd.sysconf3
-rw-r--r--daemon/remote.c61
-rw-r--r--daemon/remote_dispatch_args.h1
-rw-r--r--daemon/remote_dispatch_prototypes.h8
-rw-r--r--daemon/remote_dispatch_ret.h1
-rw-r--r--daemon/remote_dispatch_table.h5
15 files changed, 674 insertions, 111 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index a82e9a9c7..df34ef1a0 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -29,6 +29,9 @@ EXTRA_DIST = \
libvirtd.lxc.logrotate.in \
libvirtd.uml.logrotate.in \
test_libvirtd.aug \
+ THREADING.txt \
+ libvirt-guests.init.in \
+ libvirt-guests.sysconf \
$(AVAHI_SOURCES) \
$(DAEMON_SOURCES)
@@ -216,21 +219,27 @@ install-logrotate: $(LOGROTATE_CONFS)
$(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
if LIBVIRT_INIT_SCRIPT_RED_HAT
-install-init: libvirtd.init
+install-init: libvirtd.init libvirt-guests.init
mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d
$(INSTALL_SCRIPT) libvirtd.init \
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
+ $(INSTALL_SCRIPT) libvirt-guests.init \
+ $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests
mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
$(INSTALL_SCRIPT) $(srcdir)/libvirtd.sysconf \
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
+ $(INSTALL_SCRIPT) $(srcdir)/libvirt-guests.sysconf \
+ $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
uninstall-init:
rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd \
- $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
+ $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd \
+ $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests \
+ $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
-BUILT_SOURCES += libvirtd.init
+BUILT_SOURCES += libvirtd.init libvirt-guests.init
-libvirtd.init: libvirtd.init.in
+%.init: %.init.in $(top_builddir)/config.status
$(AM_V_GEN)sed \
-e s!\@localstatedir\@!@localstatedir@!g \
-e s!\@sbindir\@!@sbindir@!g \
diff --git a/daemon/Makefile.in b/daemon/Makefile.in
index 75298137f..c6e4e2045 100644
--- a/daemon/Makefile.in
+++ b/daemon/Makefile.in
@@ -51,13 +51,14 @@ host_triplet = @host@
@HAVE_AVAHI_TRUE@@WITH_LIBVIRTD_TRUE@am__append_13 = $(AVAHI_CFLAGS)
@HAVE_AVAHI_TRUE@@WITH_LIBVIRTD_TRUE@am__append_14 = $(AVAHI_LIBS)
@WITH_LIBVIRTD_TRUE@am__append_15 = $(LOGROTATE_CONFS)
-@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@am__append_16 = libvirtd.init
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@am__append_16 = libvirtd.init libvirt-guests.init
subdir = daemon
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/gnulib/m4/00gnulib.m4 \
$(top_srcdir)/gnulib/m4/alloca.m4 \
$(top_srcdir)/gnulib/m4/arpa_inet_h.m4 \
+ $(top_srcdir)/gnulib/m4/asm-underscore.m4 \
$(top_srcdir)/gnulib/m4/base64.m4 \
$(top_srcdir)/gnulib/m4/canonicalize.m4 \
$(top_srcdir)/gnulib/m4/close.m4 \
@@ -69,6 +70,8 @@ am__aclocal_m4_deps = $(top_srcdir)/gnulib/m4/00gnulib.m4 \
$(top_srcdir)/gnulib/m4/errno_h.m4 \
$(top_srcdir)/gnulib/m4/extensions.m4 \
$(top_srcdir)/gnulib/m4/fclose.m4 \
+ $(top_srcdir)/gnulib/m4/fcntl-o.m4 \
+ $(top_srcdir)/gnulib/m4/fcntl_h.m4 \
$(top_srcdir)/gnulib/m4/float_h.m4 \
$(top_srcdir)/gnulib/m4/fseeko.m4 \
$(top_srcdir)/gnulib/m4/getaddrinfo.m4 \
@@ -85,6 +88,7 @@ am__aclocal_m4_deps = $(top_srcdir)/gnulib/m4/00gnulib.m4 \
$(top_srcdir)/gnulib/m4/inet_pton.m4 \
$(top_srcdir)/gnulib/m4/intmax_t.m4 \
$(top_srcdir)/gnulib/m4/inttypes_h.m4 \
+ $(top_srcdir)/gnulib/m4/ioctl.m4 \
$(top_srcdir)/gnulib/m4/longlong.m4 \
$(top_srcdir)/gnulib/m4/lseek.m4 \
$(top_srcdir)/gnulib/m4/lstat.m4 \
@@ -104,10 +108,12 @@ am__aclocal_m4_deps = $(top_srcdir)/gnulib/m4/00gnulib.m4 \
$(top_srcdir)/gnulib/m4/po.m4 $(top_srcdir)/gnulib/m4/poll.m4 \
$(top_srcdir)/gnulib/m4/posix-shell.m4 \
$(top_srcdir)/gnulib/m4/printf.m4 \
+ $(top_srcdir)/gnulib/m4/pthread.m4 \
$(top_srcdir)/gnulib/m4/random_r.m4 \
$(top_srcdir)/gnulib/m4/rawmemchr.m4 \
$(top_srcdir)/gnulib/m4/readlink.m4 \
$(top_srcdir)/gnulib/m4/realloc.m4 \
+ $(top_srcdir)/gnulib/m4/sched_h.m4 \
$(top_srcdir)/gnulib/m4/select.m4 \
$(top_srcdir)/gnulib/m4/servent.m4 \
$(top_srcdir)/gnulib/m4/sleep.m4 \
@@ -141,11 +147,14 @@ am__aclocal_m4_deps = $(top_srcdir)/gnulib/m4/00gnulib.m4 \
$(top_srcdir)/gnulib/m4/sys_socket_h.m4 \
$(top_srcdir)/gnulib/m4/sys_stat_h.m4 \
$(top_srcdir)/gnulib/m4/sys_time_h.m4 \
+ $(top_srcdir)/gnulib/m4/sys_utsname_h.m4 \
+ $(top_srcdir)/gnulib/m4/sys_wait_h.m4 \
$(top_srcdir)/gnulib/m4/tempname.m4 \
$(top_srcdir)/gnulib/m4/time_h.m4 \
$(top_srcdir)/gnulib/m4/time_r.m4 \
$(top_srcdir)/gnulib/m4/timegm.m4 \
$(top_srcdir)/gnulib/m4/tm_gmtoff.m4 \
+ $(top_srcdir)/gnulib/m4/uname.m4 \
$(top_srcdir)/gnulib/m4/ungetc.m4 \
$(top_srcdir)/gnulib/m4/unistd_h.m4 \
$(top_srcdir)/gnulib/m4/usleep.m4 \
@@ -270,6 +279,7 @@ APPARMOR_LIBS = @APPARMOR_LIBS@
APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
AR = @AR@
AS = @AS@
+ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@
AUGPARSE = @AUGPARSE@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -347,6 +357,7 @@ GNULIB_FCHDIR = @GNULIB_FCHDIR@
GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FCNTL = @GNULIB_FCNTL@
GNULIB_FFLUSH = @GNULIB_FFLUSH@
GNULIB_FOPEN = @GNULIB_FOPEN@
GNULIB_FPRINTF = @GNULIB_FPRINTF@
@@ -431,6 +442,8 @@ GNULIB_MKTIME = @GNULIB_MKTIME@
GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_OPEN = @GNULIB_OPEN@
+GNULIB_OPENAT = @GNULIB_OPENAT@
GNULIB_PERROR = @GNULIB_PERROR@
GNULIB_PIPE2 = @GNULIB_PIPE2@
GNULIB_POPEN = @GNULIB_POPEN@
@@ -442,6 +455,7 @@ GNULIB_PUTC = @GNULIB_PUTC@
GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
GNULIB_PUTENV = @GNULIB_PUTENV@
GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
GNULIB_READLINK = @GNULIB_READLINK@
@@ -492,6 +506,7 @@ GNULIB_TIMEGM = @GNULIB_TIMEGM@
GNULIB_TIME_R = @GNULIB_TIME_R@
GNULIB_TMPFILE = @GNULIB_TMPFILE@
GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNAME = @GNULIB_UNAME@
GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
GNULIB_UNLINK = @GNULIB_UNLINK@
@@ -561,6 +576,7 @@ HAVE_FACCESSAT = @HAVE_FACCESSAT@
HAVE_FCHDIR = @HAVE_FCHDIR@
HAVE_FCHMODAT = @HAVE_FCHMODAT@
HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
HAVE_FSEEKO = @HAVE_FSEEKO@
HAVE_FSTATAT = @HAVE_FSTATAT@
HAVE_FSYNC = @HAVE_FSYNC@
@@ -606,10 +622,12 @@ HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
HAVE_NETDB_H = @HAVE_NETDB_H@
HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
+HAVE_OPENAT = @HAVE_OPENAT@
HAVE_OS_H = @HAVE_OS_H@
HAVE_PIPE2 = @HAVE_PIPE2@
HAVE_PREAD = @HAVE_PREAD@
HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
HAVE_RANDOM_H = @HAVE_RANDOM_H@
HAVE_RANDOM_R = @HAVE_RANDOM_R@
HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
@@ -620,6 +638,7 @@ HAVE_REALPATH = @HAVE_REALPATH@
HAVE_RENAMEAT = @HAVE_RENAMEAT@
HAVE_RPMATCH = @HAVE_RPMATCH@
HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@
+HAVE_SCHED_H = @HAVE_SCHED_H@
HAVE_SETENV = @HAVE_SETENV@
HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
@@ -639,8 +658,10 @@ HAVE_STRTOLL = @HAVE_STRTOLL@
HAVE_STRTOULL = @HAVE_STRTOULL@
HAVE_STRUCT_ADDRINFO = @HAVE_STRUCT_ADDRINFO@
HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SCHED_PARAM = @HAVE_STRUCT_SCHED_PARAM@
HAVE_STRUCT_SOCKADDR_STORAGE = @HAVE_STRUCT_SOCKADDR_STORAGE@
HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
+HAVE_STRUCT_UTSNAME = @HAVE_STRUCT_UTSNAME@
HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
HAVE_SYMLINK = @HAVE_SYMLINK@
HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
@@ -653,8 +674,10 @@ HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@
HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@
HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_SYS_UTSNAME_H = @HAVE_SYS_UTSNAME_H@
HAVE_TIMEGM = @HAVE_TIMEGM@
HAVE_TTYNAME_R = @HAVE_TTYNAME_R@
+HAVE_UNAME = @HAVE_UNAME@
HAVE_UNISTD_H = @HAVE_UNISTD_H@
HAVE_UNLINKAT = @HAVE_UNLINKAT@
HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
@@ -693,6 +716,8 @@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
LIBCURL_LIBS = @LIBCURL_LIBS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
LIBOBJS = @LIBOBJS@
LIBPARTED_CFLAGS = @LIBPARTED_CFLAGS@
LIBPARTED_LIBS = @LIBPARTED_LIBS@
@@ -715,6 +740,7 @@ LIBXENSERVER_CFLAGS = @LIBXENSERVER_CFLAGS@
LIBXENSERVER_LIBS = @LIBXENSERVER_LIBS@
LIBXML_CFLAGS = @LIBXML_CFLAGS@
LIBXML_LIBS = @LIBXML_LIBS@
+LIB_PTHREAD = @LIB_PTHREAD@
LIPO = @LIPO@
LN_S = @LN_S@
LOCK_CHECKING_CFLAGS = @LOCK_CHECKING_CFLAGS@
@@ -737,14 +763,15 @@ MSGMERGE = @MSGMERGE@
MV = @MV@
NETCF_CFLAGS = @NETCF_CFLAGS@
NETCF_LIBS = @NETCF_LIBS@
-NETDB_H = @NETDB_H@
NETINET_IN_H = @NETINET_IN_H@
NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
+NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
NEXT_AS_FIRST_DIRECTIVE_NETDB_H = @NEXT_AS_FIRST_DIRECTIVE_NETDB_H@
NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@
+NEXT_AS_FIRST_DIRECTIVE_SCHED_H = @NEXT_AS_FIRST_DIRECTIVE_SCHED_H@
NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
@@ -756,13 +783,17 @@ NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@
NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H@
NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@
NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_UTSNAME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UTSNAME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
NEXT_FLOAT_H = @NEXT_FLOAT_H@
NEXT_NETDB_H = @NEXT_NETDB_H@
NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@
+NEXT_SCHED_H = @NEXT_SCHED_H@
NEXT_STDDEF_H = @NEXT_STDDEF_H@
NEXT_STDINT_H = @NEXT_STDINT_H@
NEXT_STDIO_H = @NEXT_STDIO_H@
@@ -774,6 +805,8 @@ NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@
NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_H@
NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@
NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@
+NEXT_SYS_UTSNAME_H = @NEXT_SYS_UTSNAME_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
NEXT_TIME_H = @NEXT_TIME_H@
NEXT_UNISTD_H = @NEXT_UNISTD_H@
NEXT_WCHAR_H = @NEXT_WCHAR_H@
@@ -805,6 +838,8 @@ POSIX_SHELL = @POSIX_SHELL@
POSUB = @POSUB@
PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
PREFERABLY_POSIX_SHELL = @PREFERABLY_POSIX_SHELL@
+PTHREAD_H = @PTHREAD_H@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
PVCREATE = @PVCREATE@
PVREMOVE = @PVREMOVE@
@@ -827,6 +862,7 @@ REPLACE_DUP = @REPLACE_DUP@
REPLACE_DUP2 = @REPLACE_DUP2@
REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
REPLACE_FFLUSH = @REPLACE_FFLUSH@
REPLACE_FOPEN = @REPLACE_FOPEN@
REPLACE_FPRINTF = @REPLACE_FPRINTF@
@@ -868,11 +904,14 @@ REPLACE_MKTIME = @REPLACE_MKTIME@
REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
REPLACE_NULL = @REPLACE_NULL@
REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
REPLACE_PERROR = @REPLACE_PERROR@
REPLACE_POPEN = @REPLACE_POPEN@
REPLACE_PREAD = @REPLACE_PREAD@
REPLACE_PRINTF = @REPLACE_PRINTF@
REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
REPLACE_READLINK = @REPLACE_READLINK@
REPLACE_REALPATH = @REPLACE_REALPATH@
REPLACE_REMOVE = @REPLACE_REMOVE@
@@ -900,6 +939,7 @@ REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
REPLACE_SYMLINK = @REPLACE_SYMLINK@
REPLACE_TIMEGM = @REPLACE_TIMEGM@
REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
REPLACE_UNLINK = @REPLACE_UNLINK@
REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
REPLACE_UNSETENV = @REPLACE_UNSETENV@
@@ -921,6 +961,7 @@ RM = @RM@
RPCGEN = @RPCGEN@
SASL_CFLAGS = @SASL_CFLAGS@
SASL_LIBS = @SASL_LIBS@
+SCHED_H = @SCHED_H@
SED = @SED@
SELINUX_CFLAGS = @SELINUX_CFLAGS@
SELINUX_LIBS = @SELINUX_LIBS@
@@ -959,6 +1000,7 @@ VGS = @VGS@
VGSCAN = @VGSCAN@
VIRSH_LIBS = @VIRSH_LIBS@
WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
WARN_PYTHON_CFLAGS = @WARN_PYTHON_CFLAGS@
WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
WIN32_EXTRA_CFLAGS = @WIN32_EXTRA_CFLAGS@
@@ -1065,6 +1107,9 @@ EXTRA_DIST = \
libvirtd.lxc.logrotate.in \
libvirtd.uml.logrotate.in \
test_libvirtd.aug \
+ THREADING.txt \
+ libvirt-guests.init.in \
+ libvirt-guests.sysconf \
$(AVAHI_SOURCES) \
$(DAEMON_SOURCES)
@@ -1699,19 +1744,25 @@ uninstall-am: uninstall-augeasDATA uninstall-augeastestsDATA \
@WITH_LIBVIRTD_TRUE@ $(INSTALL_DATA) libvirtd.lxc.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc
@WITH_LIBVIRTD_TRUE@ $(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
-@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@install-init: libvirtd.init
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@install-init: libvirtd.init libvirt-guests.init
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(INSTALL_SCRIPT) libvirtd.init \
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(INSTALL_SCRIPT) libvirt-guests.init \
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(INSTALL_SCRIPT) $(srcdir)/libvirtd.sysconf \
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(INSTALL_SCRIPT) $(srcdir)/libvirt-guests.sysconf \
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@uninstall-init:
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd \
-@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd \
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests \
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
-@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@libvirtd.init: libvirtd.init.in
+@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@%.init: %.init.in $(top_builddir)/config.status
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ $(AM_V_GEN)sed \
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ -e s!\@localstatedir\@!@localstatedir@!g \
@LIBVIRT_INIT_SCRIPT_RED_HAT_TRUE@@WITH_LIBVIRTD_TRUE@ -e s!\@sbindir\@!@sbindir@!g \
diff --git a/daemon/THREADING.txt b/daemon/THREADING.txt
new file mode 100644
index 000000000..6386941da
--- /dev/null
+++ b/daemon/THREADING.txt
@@ -0,0 +1,52 @@
+
+ Threading in the libvirtd daemon
+ ================================
+
+To allow efficient processing of RPC requests, the libvirtd daemon
+makes use of threads.
+
+ - The process leader. This is the initial thread of control
+ when the daemon starts running. It is responsible for
+ initializing all the state, and starting the event loop.
+ Once that's all done, this thread does nothing except
+ wait for the event loop to quit, thus indicating an orderly
+ shutdown is required.
+
+ - The event loop. This thread runs the event loop, sitting
+ in poll() on all monitored file handles, and calculating
+ and dispatching any timers that may be registered. When
+ this thread quits, the entire daemon will shutdown.
+
+ - The workers. These 'n' threads all sit around waiting to
+ process incoming RPC requests. Since RPC requests may take
+ a long time to complete, with long idle periods, there will
+ be quite a few workers running.
+
+The use of threads obviously requires locking to ensure safety when
+accessing/changing data structures.
+
+ - the top level lock is on 'struct qemud_server'. This must be
+ held before acquiring any other lock
+
+ - Each 'struct qemud_client' object has a lock. The server lock
+ must be held before acquiring it. Once the client lock is acquired
+ the server lock can (optionally) be dropped.
+
+ - The event loop has its own self-contained lock. You can ignore
+ this as a caller of virEvent APIs.
+
+
+The server lock is used in conjunction with a condition variable
+to pass jobs from the event loop thread to the workers. The main
+event loop thread handles I/O from the client socket, and once a
+complete RPC message has been read off the wire (and optionally
+decrypted), it will be placed onto the 'dx' job queue for the
+associated client object. The job condition will be signalled and
+a worker will wakup and process it.
+
+The worker thread must quickly drop its locks on the server and
+client to allow the main event loop thread to continue running
+with its other work. Critically important, is that now libvirt
+API call will ever be made with the server or client locks held.
+
+-- End
diff --git a/daemon/libvirt-guests.init.in b/daemon/libvirt-guests.init.in
new file mode 100644
index 000000000..f99c0705c
--- /dev/null
+++ b/daemon/libvirt-guests.init.in
@@ -0,0 +1,304 @@
+#!/bin/sh
+
+# the following is the LSB init header
+#
+### BEGIN INIT INFO
+# Provides: libvirt-guests
+# Required-Start: libvirtd
+# Required-Stop: libvirtd
+# Default-Start: 3 4 5
+# Short-Description: suspend/resume libvirt guests on shutdown/boot
+# Description: This is a script for suspending active libvirt guests
+# on shutdown and resuming them on next boot
+# See http://libvirt.org
+### END INIT INFO
+
+# the following is chkconfig init header
+#
+# libvirt-guests: suspend/resume libvirt guests on shutdown/boot
+#
+# chkconfig: 345 98 02
+# description: This is a script for suspending active libvirt guests \
+# on shutdown and resuming them on next boot \
+# See http://libvirt.org
+#
+
+sysconfdir=@sysconfdir@
+localstatedir=@localstatedir@
+
+# Source function library.
+. "$sysconfdir"/rc.d/init.d/functions
+
+URIS=default
+ON_BOOT=start
+ON_SHUTDOWN=suspend
+SHUTDOWN_TIMEOUT=0
+
+test -f "$sysconfdir"/sysconfig/libvirt-guests && . "$sysconfdir"/sysconfig/libvirt-guests
+
+LISTFILE="$localstatedir"/lib/libvirt/libvirt-guests
+VAR_SUBSYS_LIBVIRT_GUESTS="$localstatedir"/lock/subsys/libvirt-guests
+
+RETVAL=0
+
+retval() {
+ "$@"
+ if [ $? -ne 0 ]; then
+ RETVAL=1
+ return 1
+ else
+ return 0
+ fi
+}
+
+run_virsh() {
+ uri=$1
+ shift
+
+ if [ "x$uri" = xdefault ]; then
+ conn=
+ else
+ conn="-c $uri"
+ fi
+
+ virsh $conn "$@" </dev/null
+}
+
+run_virsh_c() {
+ ( export LC_ALL=C; run_virsh "$@" )
+}
+
+list_guests() {
+ uri=$1
+
+ list=$(run_virsh_c $uri list)
+ if [ $? -ne 0 ]; then
+ RETVAL=1
+ return 1
+ fi
+
+ uuids=
+ for id in $(echo "$list" | awk 'NR > 2 {print $1}'); do
+ uuid=$(run_virsh_c $uri dominfo $id | awk '/^UUID:/{print $2}')
+ if [ -z "$uuid" ]; then
+ RETVAL=1
+ return 1
+ fi
+ uuids="$uuids $uuid"
+ done
+
+ echo $uuids
+}
+
+guest_name() {
+ uri=$1
+ uuid=$2
+
+ name=$(run_virsh_c $uri dominfo $uuid 2>/dev/null | \
+ awk '/^Name:/{print $2}')
+ [ -n "$name" ] || name=$uuid
+
+ echo "$name"
+}
+
+guest_is_on() {
+ uri=$1
+ uuid=$2
+
+ guest_running=false
+ info=$(run_virsh_c $uri dominfo $uuid)
+ if [ $? -ne 0 ]; then
+ RETVAL=1
+ return 1
+ fi
+
+ id=$(echo "$info" | awk '/^Id:/{print $2}')
+
+ [ -n "$id" ] && [ "x$id" != x- ] && guest_running=true
+ return 0
+}
+
+started() {
+ touch "$VAR_SUBSYS_LIBVIRT_GUESTS"
+}
+
+start() {
+ [ -f "$LISTFILE" ] || { started; return 0; }
+
+ if [ "x$ON_BOOT" != xstart ]; then
+ echo $"libvirt-guests is configured not to start any guests on boot"
+ rm -f "$LISTFILE"
+ started
+ return 0
+ fi
+
+ while read uri list; do
+ configured=false
+ for confuri in $URIS; do
+ if [ $confuri = $uri ]; then
+ configured=true
+ break
+ fi
+ done
+ if ! $configured; then
+ echo $"Ignoring guests on $uri URI"
+ continue
+ fi
+
+ echo $"Resuming guests on $uri URI..."
+ for guest in $list; do
+ name=$(guest_name $uri $guest)
+ echo -n $"Resuming guest $name: "
+ if guest_is_on $uri $guest; then
+ if $guest_running; then
+ echo $"already active"
+ else
+ retval run_virsh $uri start "$name" >/dev/null && \
+ echo $"done"
+ fi
+ fi
+ done
+ done <"$LISTFILE"
+
+ rm -f "$LISTFILE"
+ started
+}
+
+suspend_guest()
+{
+ uri=$1
+ guest=$2
+
+ name=$(guest_name $uri $guest)
+ label=$"Suspending $name: "
+ echo -n "$label"
+ run_virsh $uri managedsave $guest >/dev/null &
+ virsh_pid=$!
+ while true; do
+ sleep 1
+ kill -0 $virsh_pid >&/dev/null || break
+ progress=$(run_virsh_c $uri domjobinfo $guest 2>/dev/null | \
+ awk '/^Data processed:/{print $3, $4}')
+ if [ -n "$progress" ]; then
+ printf '\r%s%12s ' "$label" "$progress"
+ else
+ printf '\r%s%-12s ' "$label" "..."
+ fi
+ done
+ retval wait $virsh_pid && printf '\r%s%-12s\n' "$label" $"done"
+}
+
+shutdown_guest()
+{
+ uri=$1
+ guest=$2
+
+ name=$(guest_name $uri $guest)
+ label=$"Shutting down $name: "
+ echo -n "$label"
+ retval run_virsh $uri shutdown $guest >/dev/null || return
+ timeout=$SHUTDOWN_TIMEOUT
+ while [ $timeout -gt 0 ]; do
+ sleep 1
+ timeout=$[timeout - 1]
+ guest_is_on $uri $guest || return
+ $guest_running || break
+ printf '\r%s%-12d ' "$label" $timeout
+ done
+
+ if guest_is_on $uri $guest; then
+ if $guest_running; then
+ printf '\r%s%-12s\n' "$label" $"failed to shutdown in time"
+ else
+ printf '\r%s%-12s\n' "$label" $"done"
+ fi
+ fi
+}
+
+stop() {
+ # last stop was not followed by start
+ [ -f "$LISTFILE" ] && return 0
+
+ suspending=true
+ if [ "x$ON_SHUTDOWN" = xshutdown ]; then
+ suspending=false
+ if [ $SHUTDOWN_TIMEOUT -le 0 ]; then
+ echo $"Shutdown action requested but SHUTDOWN_TIMEOUT was not set"
+ RETVAL=6
+ return
+ fi
+ fi
+
+ : >"$LISTFILE"
+ for uri in $URIS; do
+ echo -n $"Running guests on $uri URI: "
+ list=$(list_guests $uri)
+ if [ $? -eq 0 ]; then
+ empty=true
+ for uuid in $list; do
+ $empty || printf ", "
+ echo -n $(guest_name $uri $uuid)
+ empty=false
+ done
+ if $empty; then
+ echo $"no running guests."
+ else
+ echo
+ echo $uri $list >>"$LISTFILE"
+ fi
+ fi
+ done
+
+ while read uri list; do
+ if $suspending; then
+ echo $"Suspending guests on $uri URI..."
+ else
+ echo $"Shutting down guests on $uri URI..."
+ fi
+
+ for guest in $list; do
+ if $suspending; then
+ suspend_guest $uri $guest
+ else
+ shutdown_guest $uri $guest
+ fi
+ done
+ done <"$LISTFILE"
+
+ rm -f "$VAR_SUBSYS_LIBVIRT_GUESTS"
+}
+
+gueststatus() {
+ for uri in $URIS; do
+ echo "* $uri URI:"
+ retval run_virsh $uri list || echo
+ done
+}
+
+# See how we were called.
+case "$1" in
+ start|stop|gueststatus)
+ $1
+ ;;
+ restart)
+ stop && start
+ ;;
+ force-reload)
+ ;;
+ status)
+ if [ -f "$LISTFILE" ]; then
+ RETVAL=3
+ else
+ RETVAL=0
+ fi
+ ;;
+ shutdown)
+ ON_SHUTDOWN=shutdown
+ stop
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|restart|force-reload|gueststatus|shutdown}"
+ exit 3
+ ;;
+esac
+exit $RETVAL
diff --git a/daemon/libvirt-guests.sysconf b/daemon/libvirt-guests.sysconf
new file mode 100644
index 000000000..cd58728b4
--- /dev/null
+++ b/daemon/libvirt-guests.sysconf
@@ -0,0 +1,24 @@
+# URIs to check for running guests
+# example: URIS='default xen:/// vbox+tcp://host/system lxc:///'
+#URIS=default
+
+# action taken on host boot
+# - start all guests which were running on shutdown are started on boot
+# regardless on their autostart settings
+# - ignore libvirt-guests init script won't start any guest on boot, however,
+# guests marked as autostart will still be automatically started by
+# libvirtd
+#ON_BOOT=start
+
+# action taken on host shutdown
+# - suspend all running guests are suspended using virsh managedsave
+# - shutdown all running guests are asked to shutdown. Please be careful with
+# this settings since there is no way to distinguish between a
+# guest which is stuck or ignores shutdown requests and a guest
+# which just needs a long time to shutdown. When setting
+# ON_SHUTDOWN=shutdown, you must also set SHUTDOWN_TIMEOUT to a
+# value suitable for your guests.
+#ON_SHUTDOWN=suspend
+
+# number of seconds we're willing to wait for a guest to shut down
+#SHUTDOWN_TIMEOUT=0
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 4533f4071..711360b63 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -57,6 +57,7 @@
#include "dispatch.h"
#include "util.h"
+#include "uuid.h"
#include "remote_driver.h"
#include "conf.h"
#include "event.h"
@@ -190,6 +191,7 @@ static int max_client_requests = 5;
static sig_atomic_t sig_errors = 0;
static int sig_lasterrno = 0;
+static const char *argv0;
enum {
VIR_DAEMON_ERR_NONE = 0,
@@ -384,14 +386,14 @@ qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
virHookCall(VIR_HOOK_DRIVER_DAEMON, "-",
VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, "SIGHUP", NULL);
if (virStateReload() < 0)
- VIR_WARN0(_("Error while reloading drivers"));
+ VIR_WARN0("Error while reloading drivers");
break;
case SIGINT:
case SIGQUIT:
case SIGTERM:
- VIR_WARN(_("Shutting down on signal %d"), siginfo.si_signo);
+ VIR_WARN("Shutting down on signal %d", siginfo.si_signo);
server->quitEventThread = 1;
break;
@@ -484,8 +486,8 @@ static int daemonForkIntoBackground(void) {
if (ret == 1 && status != 0) {
fprintf(stderr,
- "error: %s. Check /var/log/messages or run without "
- "--daemon for more info.\n",
+ _("%s: error: %s. Check /var/log/messages or run without "
+ "--daemon for more info.\n"), argv0,
virDaemonErrTypeToString(status));
}
_exit(ret == 1 && status == 0 ? 0 : 1);
@@ -515,15 +517,15 @@ static int qemudWritePidFile(const char *pidFile) {
}
if (fprintf(fh, "%lu\n", (unsigned long)getpid()) < 0) {
- VIR_ERROR(_("Failed to write to pid file '%s' : %s"),
- pidFile, virStrerror(errno, ebuf, sizeof ebuf));
+ VIR_ERROR(_("%s: Failed to write to pid file '%s' : %s"),
+ argv0, pidFile, virStrerror(errno, ebuf, sizeof ebuf));
fclose(fh);
return -1;
}
if (fclose(fh) == EOF) {
- VIR_ERROR(_("Failed to close pid file '%s' : %s"),
- pidFile, virStrerror(errno, ebuf, sizeof ebuf));
+ VIR_ERROR(_("%s: Failed to close pid file '%s' : %s"),
+ argv0, pidFile, virStrerror(errno, ebuf, sizeof ebuf));
return -1;
}
@@ -531,7 +533,7 @@ static int qemudWritePidFile(const char *pidFile) {
}
static int qemudListenUnix(struct qemud_server *server,
- const char *path, int readonly, int auth) {
+ char *path, int readonly, int auth) {
struct qemud_socket *sock;
struct sockaddr_un addr;
mode_t oldmask;
@@ -539,7 +541,7 @@ static int qemudListenUnix(struct qemud_server *server,
char ebuf[1024];
if (VIR_ALLOC(sock) < 0) {
- VIR_ERROR("%s", _("Failed to allocate memory for struct qemud_socket"));
+ VIR_ERROR0(_("Failed to allocate memory for struct qemud_socket"));
return -1;
}
@@ -547,6 +549,7 @@ static int qemudListenUnix(struct qemud_server *server,
sock->port = -1;
sock->type = QEMUD_SOCK_TYPE_UNIX;
sock->auth = auth;
+ sock->path = path;
if ((sock->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
VIR_ERROR(_("Failed to create socket: %s"),
@@ -741,17 +744,30 @@ cleanup:
}
static int qemudInitPaths(struct qemud_server *server,
- char *sockname,
- char *roSockname,
- int maxlen)
+ char **sockname,
+ char **roSockname)
{
- char *sock_dir;
- char *dir_prefix = NULL;
- int ret = -1;
+ char *base_dir_prefix = NULL;
char *sock_dir_prefix = NULL;
+ int ret = -1;
+
+ /* The base_dir_prefix is the base under which all libvirtd
+ * files live */
+ if (server->privileged) {
+ if (!(base_dir_prefix = strdup (LOCAL_STATE_DIR)))
+ goto no_memory;
+ } else {
+ uid_t uid = geteuid();
+ if (!(base_dir_prefix = virGetUserDirectory(uid)))
+ goto cleanup;
+ }
+ /* The unix_sock_dir is the location under which all
+ * unix domain sockets live */
if (unix_sock_dir) {
- sock_dir = unix_sock_dir;
+ if (!(sock_dir_prefix = strdup(unix_sock_dir)))
+ goto no_memory;
+
/* Change the group ownership of /var/run/libvirt to unix_sock_gid */
if (server->privileged) {
if (chown(unix_sock_dir, -1, unix_sock_gid) < 0)
@@ -759,69 +775,53 @@ static int qemudInitPaths(struct qemud_server *server,
unix_sock_dir);
}
} else {
- sock_dir = sockname;
if (server->privileged) {
- dir_prefix = strdup (LOCAL_STATE_DIR);
- if (dir_prefix == NULL) {
- virReportOOMError();
- goto cleanup;
- }
- if (snprintf (sock_dir, maxlen, "%s/run/libvirt",
- dir_prefix) >= maxlen)
- goto snprintf_error;
+ if (virAsprintf(&sock_dir_prefix, "%s/run/libvirt",
+ base_dir_prefix) < 0)
+ goto no_memory;
} else {
- uid_t uid = geteuid();
- dir_prefix = virGetUserDirectory(uid);
- if (dir_prefix == NULL) {
- /* Do not diagnose here; virGetUserDirectory does that. */
- goto snprintf_error;
- }
-
- if (snprintf(sock_dir, maxlen, "%s/.libvirt", dir_prefix) >= maxlen)
- goto snprintf_error;
+ if (virAsprintf(&sock_dir_prefix, "%s/.libvirt",
+ base_dir_prefix) < 0)
+ goto no_memory;
}
}
- sock_dir_prefix = strdup (sock_dir);
- if (!sock_dir_prefix) {
- virReportOOMError();
- goto cleanup;
- }
-
if (server->privileged) {
- if (snprintf (sockname, maxlen, "%s/libvirt-sock",
- sock_dir_prefix) >= maxlen
- || (snprintf (roSockname, maxlen, "%s/libvirt-sock-ro",
- sock_dir_prefix) >= maxlen))
- goto snprintf_error;
- unlink(sockname);
- unlink(roSockname);
+ if (virAsprintf(sockname, "%s/libvirt-sock",
+ sock_dir_prefix) < 0)
+ goto no_memory;
+ if (virAsprintf(roSockname, "%s/libvirt-sock-ro",
+ sock_dir_prefix) < 0)
+ goto no_memory;
+ unlink(*sockname);
+ unlink(*roSockname);
} else {
- if (snprintf(sockname, maxlen, "@%s/libvirt-sock",
- sock_dir_prefix) >= maxlen)
- goto snprintf_error;
+ if (virAsprintf(sockname, "@%s/libvirt-sock",
+ sock_dir_prefix) < 0)
+ goto no_memory;
+ /* There is no RO socket in unprivileged mode,
+ * since the user always has full RW access
+ * to their private instance */
}
if (server->privileged) {
- if (!(server->logDir = strdup (LOCAL_STATE_DIR "/log/libvirt")))
- virReportOOMError();
+ if (virAsprintf(&server->logDir, "%s/log/libvirt",
+ base_dir_prefix) < 0)
+ goto no_memory;
} else {
- if (virAsprintf(&server->logDir, "%s/.libvirt/log", dir_prefix) < 0)
- virReportOOMError();
+ if (virAsprintf(&server->logDir, "%s/.libvirt/log",
+ base_dir_prefix) < 0)
+ goto no_memory;
}
- if (server->logDir == NULL)
- goto cleanup;
-
ret = 0;
- snprintf_error:
- if (ret)
- VIR_ERROR("%s",
- _("Resulting path too long for buffer in qemudInitPaths()"));
+no_memory:
+ if (ret != 0)
+ virReportOOMError();
cleanup:
- VIR_FREE(dir_prefix);
+ VIR_FREE(base_dir_prefix);
VIR_FREE(sock_dir_prefix);
return ret;
}
@@ -844,12 +844,12 @@ static struct qemud_server *qemudInitialize(void) {
server->sigread = server->sigwrite = -1;
if (virMutexInit(&server->lock) < 0) {
- VIR_ERROR("%s", _("cannot initialize mutex"));
+ VIR_ERROR0(_("cannot initialize mutex"));
VIR_FREE(server);
return NULL;
}
if (virCondInit(&server->job) < 0) {
- VIR_ERROR("%s", _("cannot initialize condition variable"));
+ VIR_ERROR0(_("cannot initialize condition variable"));
virMutexDestroy(&server->lock);
VIR_FREE(server);
return NULL;
@@ -930,22 +930,22 @@ static struct qemud_server *qemudInitialize(void) {
}
static int qemudNetworkInit(struct qemud_server *server) {
- char sockname[PATH_MAX];
- char roSockname[PATH_MAX];
+ char *sockname = NULL;
+ char *roSockname = NULL;
#if HAVE_SASL
int err;
#endif /* HAVE_SASL */
- roSockname[0] = '\0';
-
- if (qemudInitPaths(server, sockname, roSockname, PATH_MAX) < 0)
+ if (qemudInitPaths(server, &sockname, &roSockname) < 0)
goto cleanup;
if (qemudListenUnix(server, sockname, 0, auth_unix_rw) < 0)
goto cleanup;
+ sockname = NULL;
- if (roSockname[0] != '\0' && qemudListenUnix(server, roSockname, 1, auth_unix_ro) < 0)
+ if (roSockname != NULL && qemudListenUnix(server, roSockname, 1, auth_unix_ro) < 0)
goto cleanup;
+ roSockname = NULL;
#if HAVE_SASL
if (auth_unix_rw == REMOTE_AUTH_SASL ||
@@ -1056,6 +1056,8 @@ static int qemudNetworkInit(struct qemud_server *server) {
return 0;
cleanup:
+ VIR_FREE(sockname);
+ VIR_FREE(roSockname);
return -1;
}
@@ -1079,6 +1081,7 @@ static int qemudNetworkEnable(struct qemud_server *server) {
return 0;
}
+
static gnutls_session_t
remoteInitializeTLSSession (void)
{
@@ -1359,7 +1362,7 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket
if (VIR_ALLOC(client) < 0)
goto cleanup;
if (virMutexInit(&client->lock) < 0) {
- VIR_ERROR("%s", _("cannot initialize mutex"));
+ VIR_ERROR0(_("cannot initialize mutex"));
VIR_FREE(client);
goto cleanup;
}
@@ -2421,6 +2424,14 @@ static void qemudCleanup(struct qemud_server *server) {
if (sock->watch)
virEventRemoveHandleImpl(sock->watch);
close(sock->fd);
+
+ /* Unlink unix domain sockets which are not in
+ * the abstract namespace */
+ if (sock->path &&
+ sock->path[0] != '@')
+ unlink(sock->path);
+ VIR_FREE(sock->path);
+
VIR_FREE(sock);
sock = next;
}
@@ -2718,6 +2729,7 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
char *unix_sock_rw_perms = NULL;
char *unix_sock_group = NULL;
char *buf = NULL;
+ char *host_uuid = NULL;
#if HAVE_POLKIT
/* Change the default back to no auth for non-root */
@@ -2761,7 +2773,7 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
GET_CONF_STR (conf, filename, unix_sock_group);
if (unix_sock_group) {
if (!server->privileged) {
- VIR_WARN0(_("Cannot set group when not running as root"));
+ VIR_WARN0("Cannot set group when not running as root");
} else {
int ret;
struct group grpdata, *grp;
@@ -2771,7 +2783,7 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
maxbuf = 1024;
if (VIR_ALLOC_N(buf, maxbuf) < 0) {
- VIR_ERROR("%s", _("Failed to allocate memory for buffer"));
+ VIR_ERROR0(_("Failed to allocate memory for buffer"));
goto free_and_fail;
}
@@ -2780,7 +2792,7 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
&grp)) == ERANGE) {
maxbuf *= 2;
if (maxbuf > 65536 || VIR_REALLOC_N(buf, maxbuf) < 0) {
- VIR_ERROR("%s", _("Failed to reallocate enough memory for buffer"));
+ VIR_ERROR0(_("Failed to reallocate enough memory for buffer"));
goto free_and_fail;
}
}
@@ -2840,11 +2852,20 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
GET_CONF_INT (conf, filename, max_requests);
GET_CONF_INT (conf, filename, max_client_requests);
+ GET_CONF_STR (conf, filename, host_uuid);
+ if (virSetHostUUIDStr(host_uuid)) {
+ VIR_ERROR(_("invalid host UUID: %s"), host_uuid);
+ goto free_and_fail;
+ }
+
+ VIR_FREE(host_uuid);
+
virConfFree (conf);
return 0;
free_and_fail:
virConfFree (conf);
+ VIR_FREE(host_uuid);
VIR_FREE(mdns_name);
VIR_FREE(unix_sock_ro_perms);
VIR_FREE(unix_sock_rw_perms);
@@ -2869,7 +2890,7 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
/* Display version information. */
static void
-version (const char *argv0)
+version (void)
{
printf ("%s (%s) %s\n", argv0, PACKAGE_NAME, PACKAGE_VERSION);
}
@@ -2961,10 +2982,10 @@ error:
/* Print command-line usage. */
static void
-usage (const char *argv0)
+usage (void)
{
fprintf (stderr,
- "\n\
+ _("\n\
Usage:\n\
%s [options]\n\
\n\
@@ -2982,27 +3003,33 @@ libvirt management daemon:\n\
Default paths:\n\
\n\
Configuration file (unless overridden by -f):\n\
- " SYSCONF_DIR "/libvirt/libvirtd.conf\n\
+ %s/libvirt/libvirtd.conf\n\
\n\
Sockets (as root):\n\
- " LOCAL_STATE_DIR "/run/libvirt/libvirt-sock\n\
- " LOCAL_STATE_DIR "/run/libvirt/libvirt-sock-ro\n\
+ %s/run/libvirt/libvirt-sock\n\
+ %s/run/libvirt/libvirt-sock-ro\n\
\n\
Sockets (as non-root):\n\
$HOME/.libvirt/libvirt-sock (in UNIX abstract namespace)\n\
\n\
TLS:\n\
- CA certificate: " LIBVIRT_CACERT "\n\
- Server certificate: " LIBVIRT_SERVERCERT "\n\
- Server private key: " LIBVIRT_SERVERKEY "\n\
+ CA certificate: %s\n\
+ Server certificate: %s\n\
+ Server private key: %s\n\
\n\
PID file (unless overridden by --pid-file):\n\
%s\n\
-\n",
- argv0,
- REMOTE_PID_FILE[0] != '\0'
- ? REMOTE_PID_FILE
- : "(disabled in ./configure)");
+\n"),
+ argv0,
+ SYSCONF_DIR,
+ LOCAL_STATE_DIR,
+ LOCAL_STATE_DIR,
+ LIBVIRT_CACERT,
+ LIBVIRT_SERVERCERT,
+ LIBVIRT_SERVERKEY,
+ (REMOTE_PID_FILE[0] != '\0'
+ ? REMOTE_PID_FILE
+ : _("(disabled in ./configure)")));
}
enum {
@@ -3016,6 +3043,7 @@ int main(int argc, char **argv) {
const char *remote_config_file = NULL;
int statuswrite = -1;
int ret = 1;
+ argv0 = argv[0];
struct option opts[] = {
{ "verbose", no_argument, &verbose, 1},
@@ -3029,7 +3057,10 @@ int main(int argc, char **argv) {
{0, 0, 0, 0}
};
- virInitialize();
+ if (virInitialize() < 0) {
+ fprintf (stderr, _("%s: initialization failed\n"), argv0);
+ exit (EXIT_FAILURE);
+ }
while (1) {
int optidx = 0;
@@ -3073,16 +3104,16 @@ int main(int argc, char **argv) {
break;
case OPT_VERSION:
- version (argv[0]);
+ version ();
return 0;
case '?':
- usage (argv[0]);
+ usage ();
return 2;
default:
- fprintf (stderr, "libvirtd: internal error: unknown flag: %c\n",
- c);
+ fprintf (stderr, _("%s: internal error: unknown flag: %c\n"),
+ argv0, c);
exit (EXIT_FAILURE);
}
}
@@ -3199,7 +3230,7 @@ int main(int argc, char **argv) {
/* Start the event loop in a background thread, since
* state initialization needs events to be being processed */
if (qemudStartEventLoop(server) < 0) {
- VIR_ERROR0("Event thread startup failed");
+ VIR_ERROR0(_("Event thread startup failed"));
goto error;
}
@@ -3208,14 +3239,14 @@ int main(int argc, char **argv) {
* we're ready, since it can take a long time and this will
* seriously delay OS bootup process */
if (virStateInitialize(server->privileged) < 0) {
- VIR_ERROR0("Driver state initialization failed");
+ VIR_ERROR0(_("Driver state initialization failed"));
goto shutdown;
}
/* Start accepting new clients from network */
virMutexLock(&server->lock);
if (qemudNetworkEnable(server) < 0) {
- VIR_ERROR0("Network event loop enablement failed");
+ VIR_ERROR0(_("Network event loop enablement failed"));
goto shutdown;
}
virMutexUnlock(&server->lock);
diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf
index 49de46634..d11c0fb08 100644
--- a/daemon/libvirtd.conf
+++ b/daemon/libvirtd.conf
@@ -312,3 +312,16 @@
# e.g.:
# log_outputs="3:syslog:libvirtd"
# to log all warnings and errors to syslog under the libvirtd ident
+
+# UUID of the host:
+# Provide the UUID of the host here in case the command
+# 'dmidecode -s system-uuid' does not provide a valid uuid. In case
+# 'dmidecode' does not provide a valid UUID and none is provided here, a
+# temporary UUID will be generated.
+# Keep the format of the example UUID below. UUID must not have all digits
+# be the same.
+
+# NB This default all-zeros UUID will not work. Replace
+# it with the output of the 'uuidgen' command and then
+# uncomment this entry
+#host_uuid = "00000000-0000-0000-0000-000000000000"
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index d29268100..4d8e7e295 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -233,6 +233,7 @@ struct qemud_client {
struct qemud_socket {
+ char *path;
int fd;
int watch;
int readonly;
diff --git a/daemon/libvirtd.init.in b/daemon/libvirtd.init.in
index d4dc98b1b..aa7870c86 100644
--- a/daemon/libvirtd.init.in
+++ b/daemon/libvirtd.init.in
@@ -9,7 +9,7 @@
# Should-Start: $named
# Should-Start: xend
# Should-Start: hal
-# Should-Start: avahi
+# Should-Start: avahi-daemon
# Required-Stop: $network messagebus
# Should-Stop: $named
# Default-Start: 3 4 5
@@ -24,8 +24,8 @@
# libvirtd: guest and virtual network management daemon
#
# chkconfig: 345 97 03
-# description: This is a daemon for managing guest instances
-# and libvirt virtual networks
+# description: This is a daemon for managing guest instances \
+# and libvirt virtual networks \
# See http://libvirt.org
#
# processname: libvirtd
@@ -45,6 +45,9 @@ KRB5_KTNAME=/etc/libvirt/krb5.tab
test -f @sysconfdir@/sysconfig/libvirtd && . @sysconfdir@/sysconfig/libvirtd
+export QEMU_AUDIO_DRV
+export SDL_AUDIODRIVER
+
LIBVIRTD_CONFIG_ARGS=
if [ -n "$LIBVIRTD_CONFIG" ]
then
diff --git a/daemon/libvirtd.sysconf b/daemon/libvirtd.sysconf
index 28080a0e3..b730c5e0b 100644
--- a/daemon/libvirtd.sysconf
+++ b/daemon/libvirtd.sysconf
@@ -11,7 +11,8 @@
# Override the QEMU/SDL default audio driver probing when
# starting virtual machines using SDL graphics
#
-# NB these have no effect for VMs using VNC
+# NB these have no effect for VMs using VNC, unless vnc_allow_host_audio
+# is enabled in /etc/libvirt/qemu.conf
#QEMU_AUDIO_DRV=sdl
#
#SDL_AUDIODRIVER=pulse
diff --git a/daemon/remote.c b/daemon/remote.c
index c54565c89..cb9e83d26 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -979,9 +979,10 @@ remoteDispatchDomainMemoryStats (struct qemud_server *server ATTRIBUTE_UNUSED,
/* Allocate stats array for making dispatch call */
if (VIR_ALLOC_N(stats, args->maxStats) < 0) {
+ virDomainFree (dom);
remoteDispatchOOMError(rerr);
return -1;
- }
+ }
nr_stats = virDomainMemoryStats (dom, stats, args->maxStats, 0);
virDomainFree (dom);
@@ -1213,6 +1214,34 @@ remoteDispatchDomainCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
}
static int
+remoteDispatchDomainCreateWithFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_message_header *hdr ATTRIBUTE_UNUSED,
+ remote_error *rerr,
+ remote_domain_create_with_flags_args *args,
+ remote_domain_create_with_flags_ret *ret)
+{
+ virDomainPtr dom;
+
+ dom = get_nonnull_domain (conn, args->dom);
+ if (dom == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ if (virDomainCreateWithFlags (dom, args->flags) == -1) {
+ virDomainFree(dom);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ make_nonnull_domain (&ret->dom, dom);
+ virDomainFree(dom);
+ return 0;
+}
+
+static int
remoteDispatchDomainCreateXml (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn,
@@ -1885,6 +1914,7 @@ remoteDispatchDomainMigrateFinish2 (struct qemud_server *server ATTRIBUTE_UNUSED
}
make_nonnull_domain (&ret->ddom, ddom);
+ virDomainFree (ddom);
return 0;
}
@@ -4982,11 +5012,13 @@ remoteDispatchNodeDeviceGetParent (struct qemud_server *server ATTRIBUTE_UNUSED,
/* remoteDispatchClientRequest will free this. */
char **parent_p;
if (VIR_ALLOC(parent_p) < 0) {
+ virNodeDeviceFree(dev);
remoteDispatchOOMError(rerr);
return -1;
}
*parent_p = strdup(parent);
if (*parent_p == NULL) {
+ virNodeDeviceFree(dev);
remoteDispatchOOMError(rerr);
return -1;
}
@@ -5018,6 +5050,7 @@ remoteDispatchNodeDeviceNumOfCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
ret->num = virNodeDeviceNumOfCaps(dev);
if (ret->num < 0) {
+ virNodeDeviceFree(dev);
remoteDispatchConnError(rerr, conn);
return -1;
}
@@ -5046,6 +5079,7 @@ remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
}
if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
+ virNodeDeviceFree(dev);
remoteDispatchFormatError(rerr,
"%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
return -1;
@@ -5053,6 +5087,7 @@ remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
/* Allocate return buffer. */
if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
+ virNodeDeviceFree(dev);
remoteDispatchOOMError(rerr);
return -1;
}
@@ -5061,11 +5096,13 @@ remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
virNodeDeviceListCaps (dev, ret->names.names_val,
args->maxnames);
if (ret->names.names_len == -1) {
+ virNodeDeviceFree(dev);
remoteDispatchConnError(rerr, conn);
VIR_FREE(ret->names.names_val);
return -1;
}
+ virNodeDeviceFree(dev);
return 0;
}
@@ -5089,10 +5126,12 @@ remoteDispatchNodeDeviceDettach (struct qemud_server *server ATTRIBUTE_UNUSED,
}
if (virNodeDeviceDettach(dev) == -1) {
+ virNodeDeviceFree(dev);
remoteDispatchConnError(rerr, conn);
return -1;
}
+ virNodeDeviceFree(dev);
return 0;
}
@@ -5116,10 +5155,12 @@ remoteDispatchNodeDeviceReAttach (struct qemud_server *server ATTRIBUTE_UNUSED,
}
if (virNodeDeviceReAttach(dev) == -1) {
+ virNodeDeviceFree(dev);
remoteDispatchConnError(rerr, conn);
return -1;
}
+ virNodeDeviceFree(dev);
return 0;
}
@@ -5143,10 +5184,12 @@ remoteDispatchNodeDeviceReset (struct qemud_server *server ATTRIBUTE_UNUSED,
}
if (virNodeDeviceReset(dev) == -1) {
+ virNodeDeviceFree(dev);
remoteDispatchConnError(rerr, conn);
return -1;
}
+ virNodeDeviceFree(dev);
return 0;
}
@@ -5193,10 +5236,12 @@ remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED,
}
if (virNodeDeviceDestroy(dev) == -1) {
+ virNodeDeviceFree(dev);
remoteDispatchConnError(rerr, conn);
return -1;
}
+ virNodeDeviceFree(dev);
return 0;
}
@@ -5570,10 +5615,12 @@ static int remoteDispatchDomainIsActive(struct qemud_server *server ATTRIBUTE_UN
ret->active = virDomainIsActive(domain);
if (ret->active < 0) {
+ virDomainFree(domain);
remoteDispatchConnError(err, conn);
return -1;
}
+ virDomainFree(domain);
return 0;
}
@@ -5596,10 +5643,12 @@ static int remoteDispatchDomainIsPersistent(struct qemud_server *server ATTRIBUT
ret->persistent = virDomainIsPersistent(domain);
if (ret->persistent < 0) {
+ virDomainFree(domain);
remoteDispatchConnError(err, conn);
return -1;
}
+ virDomainFree(domain);
return 0;
}
@@ -5622,10 +5671,12 @@ static int remoteDispatchInterfaceIsActive(struct qemud_server *server ATTRIBUTE
ret->active = virInterfaceIsActive(iface);
if (ret->active < 0) {
+ virInterfaceFree(iface);
remoteDispatchConnError(err, conn);
return -1;
}
+ virInterfaceFree(iface);
return 0;
}
@@ -5648,10 +5699,12 @@ static int remoteDispatchNetworkIsActive(struct qemud_server *server ATTRIBUTE_U
ret->active = virNetworkIsActive(network);
if (ret->active < 0) {
+ virNetworkFree(network);
remoteDispatchConnError(err, conn);
return -1;
}
+ virNetworkFree(network);
return 0;
}
@@ -5674,10 +5727,12 @@ static int remoteDispatchNetworkIsPersistent(struct qemud_server *server ATTRIBU
ret->persistent = virNetworkIsPersistent(network);
if (ret->persistent < 0) {
+ virNetworkFree(network);
remoteDispatchConnError(err, conn);
return -1;
}
+ virNetworkFree(network);
return 0;
}
@@ -5700,10 +5755,12 @@ static int remoteDispatchStoragePoolIsActive(struct qemud_server *server ATTRIBU
ret->active = virStoragePoolIsActive(pool);
if (ret->active < 0) {
+ virStoragePoolFree(pool);
remoteDispatchConnError(err, conn);
return -1;
}
+ virStoragePoolFree(pool);
return 0;
}
@@ -5726,10 +5783,12 @@ static int remoteDispatchStoragePoolIsPersistent(struct qemud_server *server ATT
ret->persistent = virStoragePoolIsPersistent(pool);
if (ret->persistent < 0) {
+ virStoragePoolFree(pool);
remoteDispatchConnError(err, conn);
return -1;
}
+ virStoragePoolFree(pool);
return 0;
}
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index b0c52d260..ee9504370 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -164,3 +164,4 @@
remote_domain_revert_to_snapshot_args val_remote_domain_revert_to_snapshot_args;
remote_domain_snapshot_delete_args val_remote_domain_snapshot_delete_args;
remote_domain_get_block_info_args val_remote_domain_get_block_info_args;
+ remote_domain_create_with_flags_args val_remote_domain_create_with_flags_args;
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
index 79d1eeca2..cf1a0f944 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -122,6 +122,14 @@ static int remoteDispatchDomainCreate(
remote_error *err,
remote_domain_create_args *args,
void *ret);
+static int remoteDispatchDomainCreateWithFlags(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_message_header *hdr,
+ remote_error *err,
+ remote_domain_create_with_flags_args *args,
+ remote_domain_create_with_flags_ret *ret);
static int remoteDispatchDomainCreateXml(
struct qemud_server *server,
struct qemud_client *client,
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
index f9d62376a..75ac0b2a4 100644
--- a/daemon/remote_dispatch_ret.h
+++ b/daemon/remote_dispatch_ret.h
@@ -134,3 +134,4 @@
remote_domain_has_current_snapshot_ret val_remote_domain_has_current_snapshot_ret;
remote_domain_snapshot_current_ret val_remote_domain_snapshot_current_ret;
remote_domain_get_block_info_ret val_remote_domain_get_block_info_ret;
+ remote_domain_create_with_flags_ret val_remote_domain_create_with_flags_ret;
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index 86bd3b0ae..ef00edd1b 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -982,3 +982,8 @@
.args_filter = (xdrproc_t) xdr_void,
.ret_filter = (xdrproc_t) xdr_void,
},
+{ /* DomainCreateWithFlags => 196 */
+ .fn = (dispatch_fn) remoteDispatchDomainCreateWithFlags,
+ .args_filter = (xdrproc_t) xdr_remote_domain_create_with_flags_args,
+ .ret_filter = (xdrproc_t) xdr_remote_domain_create_with_flags_ret,
+},