diff --git a/.fence-virt.metadata b/.fence-virt.metadata new file mode 100644 index 0000000..8e67cdb --- /dev/null +++ b/.fence-virt.metadata @@ -0,0 +1 @@ +f2aba75fd5e3fbbbcacaec5397aae634d3574693 SOURCES/fence-virt-0.3.2.tar.bz2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8557c2d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/fence-virt-0.3.2.tar.bz2 diff --git a/SOURCES/bz1078197-fix_broken_restrictions_on_the_port_ranges.patch b/SOURCES/bz1078197-fix_broken_restrictions_on_the_port_ranges.patch new file mode 100644 index 0000000..228236e --- /dev/null +++ b/SOURCES/bz1078197-fix_broken_restrictions_on_the_port_ranges.patch @@ -0,0 +1,44 @@ +From 630f390d94254c0b689e9ba386479f2e56f37784 Mon Sep 17 00:00:00 2001 +From: Ryan McCabe +Date: Tue, 3 Mar 2015 13:38:25 -0500 +Subject: [PATCH] fence-virt: Fix broken restrictions on the port ranges + +Fix broken port range check. + +Resolves: rhbz#1078197 + +Signed-off-by: Ryan McCabe +--- + client/options.c | 2 +- + server/config.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/client/options.c b/client/options.c +index 653fae4..a44c15f 100644 +--- a/client/options.c ++++ b/client/options.c +@@ -134,7 +134,7 @@ assign_port(fence_virt_args_t *args, struct arg_info *arg, char *value) + return; + + args->net.port = atoi(value); +- if (args->net.port <= 0 || args->net.port >= 65500) { ++ if (args->net.port <= 0 || args->net.port >= 65536) { + printf("Invalid port: '%s'\n", value); + args->flags |= F_ERR; + } +diff --git a/server/config.c b/server/config.c +index 87d826e..6ba8b6d 100644 +--- a/server/config.c ++++ b/server/config.c +@@ -239,7 +239,7 @@ listener_config_multicast(config_object_t *config) + text_input("Multicast IP Port", val, inp, sizeof(inp)); + + done = atoi(inp); +- if (done <= 0 || done > 65534) { ++ if (done <= 0 || done >= 65536) { + printf("Port value '%s' is out of range\n", val); + continue; + } +-- +2.5.5 + diff --git a/SOURCES/bz1092531-enable_hardening.patch b/SOURCES/bz1092531-enable_hardening.patch new file mode 100644 index 0000000..4eeb56c --- /dev/null +++ b/SOURCES/bz1092531-enable_hardening.patch @@ -0,0 +1,84 @@ +diff -ur a/client/Makefile.in b/client/Makefile.in +--- a/client/Makefile.in 2014-06-23 15:56:09.000000000 -0400 ++++ b/client/Makefile.in 2017-05-22 12:33:13.587241001 -0400 +@@ -40,10 +40,10 @@ + ln -snf $^ $@ + + fence_virt: ${fence_virt_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -L../common -lfence_virt ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -L../common -lfence_virt + + %.o: %.c +- $(CC) $(CFLAGS) -c -o $@ $^ $(INCLUDES) ++ $(CC) -c -o $@ $^ $(INCLUDES) $(CFLAGS) + + install: all + if [ ! -d ${DESTDIR}/${sbindir} ]; then \ +diff -ur a/Makefile.top.in b/Makefile.top.in +--- a/Makefile.top.in 2014-06-23 15:56:09.000000000 -0400 ++++ b/Makefile.top.in 2017-05-22 12:24:26.973934895 -0400 +@@ -1,8 +1,9 @@ + CC=@CC@ + CXX=@CXX@ + +-CFLAGS=@CFLAGS@ +-CFLAGS+=-fPIC -Wall -Wstrict-prototypes -Wshadow -D_GNU_SOURCE ++CFLAGS=-fPIC -Wall -Wstrict-prototypes -Wshadow -D_GNU_SOURCE -Wl,-z,relro,-z,now ++CFLAGS_BIN=@CFLAGS@ ++LDFLAGS=@LDFLAGS@ + + LEX=@LEX@ + YACC=@YACC@ +diff -ur a/server/Makefile.in b/server/Makefile.in +--- a/server/Makefile.in 2014-06-23 15:56:09.000000000 -0400 ++++ b/server/Makefile.in 2017-05-22 13:03:14.183158260 -0400 +@@ -152,38 +152,38 @@ + all: ${TARGETS} ${MODULES} + + fence_virtd: ${fence_virtd_SOURCES:.c=.o} ${fence_virtd_cxx_SOURCES:.cpp=.opp} +- $(CXX) -o $@ $^ $(MAIN_LIBS) $(LIBS) ++ $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(MAIN_LIBS) $(LIBS) + + multicast.so: ${multicast_so_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -shared $(NSS_LIBS) ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared $(NSS_LIBS) + + libvirt.so: ${libvirt_so_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -shared $(VIRT_LIBS) $(UUID_LIBS) ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared $(VIRT_LIBS) $(UUID_LIBS) + + libvirt-qmf.so: ${libvirt_qmf_so_SOURCES:.c=.o} ${libvirt_qmf_cxx_so_SOURCES:.cpp=.opp} +- $(CXX) -o $@ $^ $(LIBS) -shared $(VIRT_QPID) ++ $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared $(VIRT_QPID) + + pm-fence.so: ${pm_fence_so_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -shared $(PACEMAKER_LIBS) ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared $(PACEMAKER_LIBS) + + null.so: ${null_so_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -shared ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared + + checkpoint.so: ${checkpoint_so_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -shared $(AIS_LIBS) $(VIRT_LIBS) \ ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared $(AIS_LIBS) $(VIRT_LIBS) \ + $(COROSYNC_LIBS) $(CMAN_LIBS) + + serial.so: ${serial_so_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -shared $(VIRT_LIBS) $(UUID_LIBS) $(XML_LIBS) ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared $(VIRT_LIBS) $(UUID_LIBS) $(XML_LIBS) + + tcp.so: ${tcp_so_SOURCES:.c=.o} +- $(CC) -o $@ $^ $(LIBS) -shared $(NSS_LIBS) ++ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) -shared $(NSS_LIBS) + + %.o: %.c +- $(CC) $(CFLAGS) -c -o $@ $^ $(INCLUDES) ++ $(CC) -c -o $@ $^ $(INCLUDES) $(CFLAGS) + + %.opp: %.cpp +- $(CXX) $(CFLAGS) -c -o $@ $^ $(INCLUDES) ++ $(CXX) -c -o $@ $^ $(INCLUDES) $(CFLAGS) + + install: all + if [ ! -d ${DESTDIR}/${sbindir} ]; then \ diff --git a/SOURCES/bz1204873-fix_delay_parameter_checking_copy_paste.patch b/SOURCES/bz1204873-fix_delay_parameter_checking_copy_paste.patch new file mode 100644 index 0000000..f660bb0 --- /dev/null +++ b/SOURCES/bz1204873-fix_delay_parameter_checking_copy_paste.patch @@ -0,0 +1,31 @@ +From f49a7d68d5fecf781bae55056f2e7d02bddd47d7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Mon, 23 Mar 2015 17:14:25 +0100 +Subject: [PATCH] client: fix "delay" parameter checking (copy-paste) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: rhbz#1204873 + +Signed-off-by: Jan Pokorný +--- + client/options.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/client/options.c b/client/options.c +index a44c15f..a20e09f 100644 +--- a/client/options.c ++++ b/client/options.c +@@ -336,7 +336,7 @@ assign_delay(fence_virt_args_t *args, struct arg_info *arg, char *value) + return; + + args->delay = atoi(value); +- if (args->timeout <= 0) { ++ if (args->delay <= 0) { + printf("Invalid delay: '%s'\n", value); + args->flags |= F_ERR; + } +-- +2.5.5 + diff --git a/SOURCES/bz1204877-remove_delay_from_the_status,_monitor_and_list.patch b/SOURCES/bz1204877-remove_delay_from_the_status,_monitor_and_list.patch new file mode 100644 index 0000000..d06d232 --- /dev/null +++ b/SOURCES/bz1204877-remove_delay_from_the_status,_monitor_and_list.patch @@ -0,0 +1,29 @@ +From f1f1a2437c5b0811269b5859a5ef646f44105a88 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Tue, 3 May 2016 15:58:00 +0200 +Subject: [PATCH] Remove delay from the status, monitor and list + functions + +--- + client/main.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/client/main.c b/client/main.c +index 7be4a8e..dd064dc 100644 +--- a/client/main.c ++++ b/client/main.c +@@ -119,7 +119,10 @@ main(int argc, char **argv) + return 0; + } + +- if (args.delay > 0) ++ if (args.delay > 0 && ++ args.op != FENCE_STATUS && ++ args.op != FENCE_DEVSTATUS && ++ args.op != FENCE_HOSTLIST) + sleep(args.delay); + + switch(args.mode) { +-- +2.5.5 + diff --git a/SOURCES/bz1207422-client_do_not_truncate_vm_domains_in_list_output.patch b/SOURCES/bz1207422-client_do_not_truncate_vm_domains_in_list_output.patch new file mode 100644 index 0000000..765fc02 --- /dev/null +++ b/SOURCES/bz1207422-client_do_not_truncate_vm_domains_in_list_output.patch @@ -0,0 +1,31 @@ +From 4a749e3f7de4c82446634a1b57d3877b7dc46223 Mon Sep 17 00:00:00 2001 +From: Ryan McCabe +Date: Fri, 17 Jul 2015 10:52:01 -0400 +Subject: [PATCH] fence-virt: client: Do not truncate VM domains in list output + +Don't truncate the domain string for VMs when listing their status +in the output of the list command. + +Resolves: rhbz#1207422 + +Signed-off-by: Ryan McCabe +--- + client/mcast.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/client/mcast.c b/client/mcast.c +index a247e8c..f2654bd 100644 +--- a/client/mcast.c ++++ b/client/mcast.c +@@ -117,7 +117,7 @@ do_read_hostlist(int fd, int timeout) + strlen((char *)hinfo.domain) == 0) + break; + +- printf("%-20.20s %s %s\n", hinfo.domain, hinfo.uuid, ++ printf("%-32s %s %s\n", hinfo.domain, hinfo.uuid, + (hinfo.state == 1) ? "on" : "off"); + + } while (1); +-- +2.4.3 + diff --git a/SOURCES/bz1291522-Install_firewalld_unit_file.patch b/SOURCES/bz1291522-Install_firewalld_unit_file.patch new file mode 100644 index 0000000..f92e4d9 --- /dev/null +++ b/SOURCES/bz1291522-Install_firewalld_unit_file.patch @@ -0,0 +1,11 @@ +diff -urN a/fence_virt.xml b/fence_virt.xml +--- a/fence_virt.xml 1969-12-31 19:00:00.000000000 -0500 ++++ b/fence_virt.xml 2016-06-28 13:27:39.351692601 -0400 +@@ -0,0 +1,7 @@ ++ ++ ++ fence_virt ++ fence_virt is an I/O fencing agent that can be used to fence virtual machines. ++ ++ ++ diff --git a/SOURCES/bz1334170-2-fix_use_of_undefined_#define.patch b/SOURCES/bz1334170-2-fix_use_of_undefined_#define.patch new file mode 100644 index 0000000..9d0a363 --- /dev/null +++ b/SOURCES/bz1334170-2-fix_use_of_undefined_#define.patch @@ -0,0 +1,25 @@ +From 87b4eb3d8c9046b66beeae424d0f9d2b4c4d9eee Mon Sep 17 00:00:00 2001 +From: Andrew Beekhof +Date: Mon, 9 May 2016 14:54:10 +1000 +Subject: [PATCH] Fix use of undefined #define + +--- + server/tcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/server/tcp.c b/server/tcp.c +index 6c93f14..a6186c6 100644 +--- a/server/tcp.c ++++ b/server/tcp.c +@@ -417,7 +417,7 @@ tcp_config(config_object_t *config, tcp_options *args) + return -1; + } + +- args->port = DEFAULT_TCP_PORT; ++ args->port = DEFAULT_MCAST_PORT; + if (sc_get(config, "listeners/tcp/@port", + value, sizeof(value)-1) == 0) { + dbg_printf(1, "Got %s for port\n", value); +-- +2.5.5 + diff --git a/SOURCES/bz1334170-allow_fence_virtd_to_run_as_non_root.patch b/SOURCES/bz1334170-allow_fence_virtd_to_run_as_non_root.patch new file mode 100644 index 0000000..1eced64 --- /dev/null +++ b/SOURCES/bz1334170-allow_fence_virtd_to_run_as_non_root.patch @@ -0,0 +1,168 @@ +diff -ur a/server/daemon_init.c b/server/daemon_init.c +--- a/server/daemon_init.c 2014-06-23 15:56:09.000000000 -0400 ++++ b/server/daemon_init.c 2016-06-27 11:46:20.838477025 -0400 +@@ -29,14 +29,14 @@ + /* + * This should ultimately go in a header file. + */ +-void daemon_init(const char *prog, int nofork); ++void daemon_init(const char *prog, const char *pid_file, int nofork); + void daemon_cleanup(void); +-int check_process_running(const char *prog, pid_t * pid); ++int check_process_running(const char *cmd, const char *pid_file, pid_t * pid); + + /* + * Local prototypes. + */ +-static void update_pidfile(const char *prog); ++static void update_pidfile(const char *filename); + static int setup_sigmask(void); + static char pid_filename[PATH_MAX]; + +@@ -99,12 +99,10 @@ + + + int +-check_process_running(const char *prog, pid_t * pid) ++check_process_running(const char *cmd, const char *filename, pid_t * pid) + { + pid_t oldpid; + FILE *fp; +- char filename[PATH_MAX]; +- char *cmd; + int ret; + struct stat st; + +@@ -114,11 +112,6 @@ + * Now see if there is a pidfile associated with this cmd in /var/run + */ + fp = NULL; +- memset(filename, 0, PATH_MAX); +- +- cmd = basename((char *)prog); +- snprintf(filename, sizeof (filename), "/var/run/%s.pid", cmd); +- + ret = stat(filename, &st); + if ((ret < 0) || (!st.st_size)) + return 0; +@@ -146,15 +139,11 @@ + + + static void +-update_pidfile(const char *prog) ++update_pidfile(const char *filename) + { + FILE *fp = NULL; +- char *cmd; +- +- memset(pid_filename, 0, PATH_MAX); + +- cmd = basename((char *)prog); +- snprintf(pid_filename, sizeof (pid_filename), "/var/run/%s.pid", cmd); ++ strncpy(pid_filename, filename, PATH_MAX); + + fp = fopen(pid_filename, "w"); + if (fp == NULL) { +@@ -197,19 +186,11 @@ + + + void +-daemon_init(const char *prog, int nofork) ++daemon_init(const char *prog, const char *pid_file, int nofork) + { +- uid_t uid; + pid_t pid; + +- uid = getuid(); +- if (uid) { +- syslog(LOG_ERR, +- "daemon_init: Sorry, only root wants to run this.\n"); +- exit(1); +- } +- +- if (check_process_running(prog, &pid) && (pid != getpid())) { ++ if (check_process_running(prog, pid_file, &pid) && (pid != getpid())) { + syslog(LOG_ERR, + "daemon_init: Process \"%s\" already running.\n", + prog); +@@ -226,7 +207,7 @@ + exit(1); + } + +- update_pidfile(prog); ++ update_pidfile(pid_file); + } + + +diff -ur a/server/main.c b/server/main.c +--- a/server/main.c 2014-06-23 15:56:09.000000000 -0400 ++++ b/server/main.c 2016-06-27 11:39:55.345859796 -0400 +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + /* Local includes */ + #include +@@ -16,7 +17,7 @@ + + /* configure.c */ + int do_configure(config_object_t *config, const char *filename); +-int daemon_init(const char *prog, int nofork); ++int daemon_init(const char *prog, const char *pid_file, int nofork); + int daemon_cleanup(void); + + +@@ -29,6 +30,8 @@ + printf(" -d Set debugging level to .\n"); + printf(" -c Configuration mode.\n"); + printf(" -l List plugins.\n"); ++ printf(" -w Wait for initialization.\n"); ++ printf(" -p Use to record the active process id.\n"); + } + + +@@ -47,6 +50,7 @@ + char listener_name[80]; + char backend_name[80]; + const char *config_file = DEFAULT_CONFIG_FILE; ++ char *pid_file = NULL; + config_object_t *config = NULL; + map_object_t *map = NULL; + const listener_plugin_t *lp; +@@ -64,7 +68,7 @@ + return -1; + } + +- while ((opt = getopt(argc, argv, "Ff:d:cwlh")) != EOF) { ++ while ((opt = getopt(argc, argv, "Ff:d:cwlhp:")) != EOF) { + switch(opt) { + case 'F': + printf("Background mode disabled\n"); +@@ -74,6 +78,10 @@ + printf("Using %s\n", optarg); + config_file = optarg; + break; ++ case 'p': ++ printf("Using %s\n", optarg); ++ pid_file = optarg; ++ break; + case 'd': + debug_set = atoi(optarg); + break; +@@ -190,7 +198,13 @@ + return 1; + } + +- daemon_init(basename(argv[0]), foreground); ++ if(pid_file == NULL) { ++ pid_file = malloc(PATH_MAX); ++ memset(pid_file, 0, PATH_MAX); ++ snprintf(pid_file, PATH_MAX, "/var/run/%s.pid", basename(argv[0])); ++ } ++ ++ daemon_init(basename(argv[0]), pid_file, foreground); + signal(SIGINT, exit_handler); + signal(SIGTERM, exit_handler); + signal(SIGQUIT, exit_handler); diff --git a/SOURCES/bz1334170-cleanup_documentation_of_the_tcp_listener.patch b/SOURCES/bz1334170-cleanup_documentation_of_the_tcp_listener.patch new file mode 100644 index 0000000..21d7d2d --- /dev/null +++ b/SOURCES/bz1334170-cleanup_documentation_of_the_tcp_listener.patch @@ -0,0 +1,51 @@ +From 0015556ddfbf22a1deca3b86217d0ac29afd3fbc Mon Sep 17 00:00:00 2001 +From: Ryan McCabe +Date: Wed, 17 May 2017 13:21:33 -0400 +Subject: [PATCH] fence-virtd: Cleanup documentation of the TCP listener + +Remove overly specific documentation of the TCP listener. vios-proxy appears to be dead, +so all references to that and its configuration have been removed. + +Resolves: rhbz#1334170 +Signed-off-by: Ryan McCabe +--- + man/fence_virt.conf.5 | 16 ++-------------- + 1 file changed, 2 insertions(+), 14 deletions(-) + +diff --git a/man/fence_virt.conf.5 b/man/fence_virt.conf.5 +index 412e769..dcf0d21 100644 +--- a/man/fence_virt.conf.5 ++++ b/man/fence_virt.conf.5 +@@ -154,19 +154,7 @@ This selects the type of sockets to register. Valid values are "serial" + (default) and "vmchannel". + + .SS tcp +-The tcp plugin was designed to be used with vios-proxy. vios-proxy uses a virtio-serial channel to proxy TCP connections between guests and a host. In order to use the tcp plugin, vios-proxy-host must be running on all the physical cluster nodes, and vios-proxy-guest must be running on all guest cluster nodes. Prior to running vios-proxy-host or vios-proxy-guest, the virtio-serial channel and host sockets must be configured for all guest domains. Example libvirt XML: +- +-.in 8 +- <\fBcontroller\fP type='virtio-serial' index='0'> +-
+- +- +- <\fBchannel\fP type='unix'> +- +- +-
+- +-.in 0 ++The tcp listener operates similarly to the multicast listener but uses TCP sockets for communication instead of using multicast packets. + + .TP + .B key_file +@@ -193,7 +181,7 @@ the IP family to use (default: ipv4, but may be ipv6) + .TP + .B address + . +-the IP address to listen on (default: 127.0.0.1) ++the IP address to listen on (default: 127.0.0.1 for IPv4, ::1 for IPv6) + + .TP + .B port +-- +2.9.3 + diff --git a/SOURCES/bz1384181-make_the_libvirt_backend_survive_libvirtd.patch b/SOURCES/bz1384181-make_the_libvirt_backend_survive_libvirtd.patch new file mode 100644 index 0000000..522bf0d --- /dev/null +++ b/SOURCES/bz1384181-make_the_libvirt_backend_survive_libvirtd.patch @@ -0,0 +1,1147 @@ +diff -ur a/server/checkpoint.c b/server/checkpoint.c +--- a/server/checkpoint.c 2014-06-23 15:56:09.000000000 -0400 ++++ b/server/checkpoint.c 2017-08-09 13:30:40.708689303 -0400 +@@ -79,7 +79,7 @@ + { + virt_list_t *list = NULL; + +- list = vl_get(vp, my_id); ++ list = vl_get(vp, 1, my_id); + if (!list) + return -1; + +diff -ur a/server/libvirt.c b/server/libvirt.c +--- a/server/libvirt.c 2014-06-23 15:56:09.000000000 -0400 ++++ b/server/libvirt.c 2017-08-09 13:30:40.709689288 -0400 +@@ -1,5 +1,5 @@ + /* +- Copyright Red Hat, Inc. 2006 ++ Copyright Red Hat, Inc. 2006-2017 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the +@@ -61,13 +61,15 @@ + + + #define NAME "libvirt" +-#define VERSION "0.1" ++#define VERSION "0.3" + + #define MAGIC 0x1e19317a + + struct libvirt_info { + int magic; +- virConnectPtr vp; ++ config_object_t *config; ++ int vp_count; ++ virConnectPtr *vp; + }; + + #define VALIDATE(arg) \ +@@ -79,179 +81,128 @@ + } while(0) + + +-static inline int +-wait_domain(const char *vm_name, virConnectPtr vp, +- int timeout) +-{ +- int tries = 0; +- int response = 1; +- int ret; +- virDomainPtr vdp; +- virDomainInfo vdi; +- int uuid_check; +- +- uuid_check = is_uuid(vm_name); +- +- if (uuid_check) { +- vdp = virDomainLookupByUUIDString(vp, (const char *)vm_name); +- } else { +- vdp = virDomainLookupByName(vp, vm_name); ++static void ++libvirt_init_libvirt_conf(struct libvirt_info *info) { ++ config_object_t *config = info->config; ++ int i = 0; ++ ++ if (info->vp) { ++ dbg_printf(2, "Lost libvirtd connection. Reinitializing.\n"); ++ for (i = 0 ; i < info->vp_count ; i++) ++ virConnectClose(info->vp[i]); ++ free(info->vp); ++ info->vp = NULL; + } +- if (!vdp) +- return 0; ++ info->vp_count = 0; + +- /* Check domain liveliness. If the domain is still here, +- we return failure, and the client must then retry */ +- /* XXX On the xen 3.0.4 API, we will be able to guarantee +- synchronous virDomainDestroy, so this check will not +- be necessary */ + do { +- if (++tries > timeout) +- break; ++ virConnectPtr vp; ++ virConnectPtr *vpl = NULL; ++ char conf_attr[256]; ++ char value[1024]; ++ char *uri; ++ ++ if (i != 0) { ++ snprintf(conf_attr, sizeof(conf_attr), ++ "backends/libvirt/@uri%d", i); ++ } else ++ snprintf(conf_attr, sizeof(conf_attr), "backends/libvirt/@uri"); ++ ++i; + +- sleep(1); +- if (uuid_check) { +- vdp = virDomainLookupByUUIDString(vp, +- (const char *)vm_name); +- } else { +- vdp = virDomainLookupByName(vp, vm_name); +- } +- if (!vdp) { +- dbg_printf(2, "Domain no longer exists\n"); +- response = 0; ++ if (sc_get(config, conf_attr, value, sizeof(value)) != 0) + break; +- } + +- memset(&vdi, 0, sizeof(vdi)); +- ret = virDomainGetInfo(vdp, &vdi); +- virDomainFree(vdp); +- if (ret < 0) ++ uri = value; ++ vp = virConnectOpen(uri); ++ if (!vp) { ++ dbg_printf(1, "[libvirt:INIT] Failed to connect to URI: %s\n", uri); + continue; ++ } + +- if (vdi.state == VIR_DOMAIN_SHUTOFF) { +- dbg_printf(2, "Domain has been shut off\n"); +- response = 0; +- break; ++ vpl = realloc(info->vp, sizeof(*info->vp) * (info->vp_count + 1)); ++ if (!vpl) { ++ dbg_printf(1, "[libvirt:INIT] Out of memory allocating URI: %s\n", ++ uri); ++ virConnectClose(vp); ++ continue; + } +- +- dbg_printf(4, "Domain still exists (state %d) " +- "after %d seconds\n", +- vdi.state, tries); ++ ++ info->vp = vpl; ++ info->vp[info->vp_count++] = vp; ++ ++ if (i > 1) ++ dbg_printf(1, "[libvirt:INIT] Added URI%d %s\n", i - 1, uri); ++ else ++ dbg_printf(1, "[libvirt:INIT] Added URI %s\n", uri); + } while (1); ++} + +- return response; ++ ++static int ++libvirt_bad_connections(struct libvirt_info *info) { ++ int bad = 0; ++ int i; ++ ++ for (i = 0 ; i < info->vp_count ; i++) { ++ /* ++ ** Send a dummy command to trigger an error if libvirtd ++ ** died or restarted ++ */ ++ virConnectNumOfDomains(info->vp[i]); ++ if (!virConnectIsAlive(info->vp[i])) { ++ dbg_printf(1, "libvirt connection %d is dead\n", i); ++ bad++; ++ } ++ } ++ ++ if (info->vp_count < 1 || bad) ++ libvirt_init_libvirt_conf(info); ++ ++ return bad || info->vp_count < 1; + } + ++static void ++libvirt_validate_connections(struct libvirt_info *info) { ++ while (1) { ++ if (libvirt_bad_connections(info)) ++ sleep(1); ++ else ++ break; ++ } ++} + + static int + libvirt_null(const char *vm_name, void *priv) + { +- dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); ++ dbg_printf(5, "ENTER %s %s\n", __FUNCTION__, vm_name); + printf("NULL operation: returning failure\n"); + return 1; + } + + + static int +-libvirt_off(const char *vm_name, const char *src, +- uint32_t seqno, void *priv) ++libvirt_off(const char *vm_name, const char *src, uint32_t seqno, void *priv) + { + struct libvirt_info *info = (struct libvirt_info *)priv; +- virDomainPtr vdp; +- virDomainInfo vdi; +- int ret = -1; + +- dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); ++ dbg_printf(5, "ENTER %s %s %u\n", __FUNCTION__, vm_name, seqno); + VALIDATE(info); + +- if (is_uuid(vm_name)) { +- vdp = virDomainLookupByUUIDString(info->vp, +- (const char *)vm_name); +- } else { +- vdp = virDomainLookupByName(info->vp, vm_name); +- } +- +- if (!vdp) { +- dbg_printf(2, "Nothing to do - domain does not exist\n"); +- return 1; +- } +- +- if (((virDomainGetInfo(vdp, &vdi) == 0) && +- (vdi.state == VIR_DOMAIN_SHUTOFF))) { +- dbg_printf(2, "Nothing to do - domain is off\n"); +- virDomainFree(vdp); +- return 0; +- } +- +- syslog(LOG_NOTICE, "Destroying domain %s\n", vm_name); +- dbg_printf(2, "[OFF] Calling virDomainDestroy\n"); +- ret = virDomainDestroy(vdp); +- if (ret < 0) { +- syslog(LOG_NOTICE, "Failed to destroy domain: %d\n", ret); +- printf("virDomainDestroy() failed: %d\n", ret); +- return 1; +- } +- +- if (ret) { +- syslog(LOG_NOTICE, +- "Domain %s still exists; fencing failed\n", +- vm_name); +- printf("Domain %s still exists; fencing failed\n", vm_name); +- return 1; +- } +- +- return 0; ++ libvirt_validate_connections(info); ++ return vm_off(info->vp, info->vp_count, vm_name); + } + + + static int +-libvirt_on(const char *vm_name, const char *src, +- uint32_t seqno, void *priv) ++libvirt_on(const char *vm_name, const char *src, uint32_t seqno, void *priv) + { + struct libvirt_info *info = (struct libvirt_info *)priv; +- virDomainPtr vdp; +- virDomainInfo vdi; +- int ret = -1; + +- dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); ++ dbg_printf(5, "ENTER %s %s %u\n", __FUNCTION__, vm_name, seqno); + VALIDATE(info); + +- if (is_uuid(vm_name)) { +- vdp = virDomainLookupByUUIDString(info->vp, +- (const char *)vm_name); +- } else { +- vdp = virDomainLookupByName(info->vp, vm_name); +- } +- +- if (vdp && +- ((virDomainGetInfo(vdp, &vdi) == 0) && +- (vdi.state != VIR_DOMAIN_SHUTOFF))) { +- dbg_printf(2, "Nothing to do - domain is running\n"); +- +- if (vdp) +- virDomainFree(vdp); +- return 0; +- } +- +- syslog(LOG_NOTICE, "Starting domain %s\n", vm_name); +- dbg_printf(2, "[ON] Calling virDomainCreate\n"); +- ret = virDomainCreate(vdp); +- if (ret < 0) { +- syslog(LOG_NOTICE, "Failed to start domain: %d\n", ret); +- printf("virDomainCreate() failed: %d\n", ret); +- return 1; +- } +- +- if (ret) { +- syslog(LOG_NOTICE, +- "Domain %s did not start\n", +- vm_name); +- printf("Domain %s did not start\n", vm_name); +- return 1; +- } +- syslog(LOG_NOTICE, "Domain %s started\n", vm_name); +- +- return 0; ++ libvirt_validate_connections(info); ++ return vm_on(info->vp, info->vp_count, vm_name); + } + + +@@ -270,126 +221,25 @@ + libvirt_status(const char *vm_name, void *priv) + { + struct libvirt_info *info = (struct libvirt_info *)priv; +- virDomainPtr vdp; +- virDomainInfo vdi; +- int ret = 0; + +- dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); ++ dbg_printf(5, "ENTER %s %s\n", __FUNCTION__, vm_name); + VALIDATE(info); + +- if (is_uuid(vm_name)) { +- vdp = virDomainLookupByUUIDString(info->vp, +- (const char *)vm_name); +- } else { +- vdp = virDomainLookupByName(info->vp, vm_name); +- } +- +- if (!vdp || ((virDomainGetInfo(vdp, &vdi) == 0) && +- (vdi.state == VIR_DOMAIN_SHUTOFF))) { +- ret = RESP_OFF; +- } +- +- if (vdp) +- virDomainFree(vdp); +- return ret; ++ libvirt_validate_connections(info); ++ return vm_status(info->vp, info->vp_count, vm_name); + } + + + static int +-libvirt_reboot(const char *vm_name, const char *src, +- uint32_t seqno, void *priv) ++libvirt_reboot(const char *vm_name, const char *src, uint32_t seqno, void *priv) + { + struct libvirt_info *info = (struct libvirt_info *)priv; +- virDomainPtr vdp, nvdp; +- virDomainInfo vdi; +- char *domain_desc; +- int ret; + +- //uuid_unparse(vm_uuid, uu_string); +- dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); ++ dbg_printf(5, "ENTER %s %s %u\n", __FUNCTION__, vm_name, seqno); + VALIDATE(info); +- +- if (is_uuid(vm_name)) { +- vdp = virDomainLookupByUUIDString(info->vp, +- (const char *)vm_name); +- } else { +- vdp = virDomainLookupByName(info->vp, vm_name); +- } +- +- if (!vdp) { +- dbg_printf(2, "[libvirt:REBOOT] Nothing to " +- "do - domain does not exist\n"); +- return 1; +- } +- +- if (((virDomainGetInfo(vdp, &vdi) == 0) && +- (vdi.state == VIR_DOMAIN_SHUTOFF))) { +- dbg_printf(2, "[libvirt:REBOOT] Nothing to " +- "do - domain is off\n"); +- virDomainFree(vdp); +- return 0; +- } +- +- +- syslog(LOG_NOTICE, "Rebooting domain %s\n", vm_name); +- printf("Rebooting domain %s...\n", vm_name); +- domain_desc = virDomainGetXMLDesc(vdp, 0); +- +- if (!domain_desc) { +- printf("Failed getting domain description from " +- "libvirt\n"); +- } +- +- dbg_printf(2, "[REBOOT] Calling virDomainDestroy(%p)\n", vdp); +- ret = virDomainDestroy(vdp); +- if (ret < 0) { +- printf("virDomainDestroy() failed: %d/%d\n", ret, errno); +- free(domain_desc); +- virDomainFree(vdp); +- return 1; +- } +- +- ret = wait_domain(vm_name, info->vp, 15); +- +- if (ret) { +- syslog(LOG_NOTICE, "Domain %s still exists; fencing failed\n", +- vm_name); +- printf("Domain %s still exists; fencing failed\n", vm_name); +- if (domain_desc) +- free(domain_desc); +- return 1; +- } +- +- if (!domain_desc) +- return 0; + +- /* 'on' is not a failure */ +- ret = 0; +- +- dbg_printf(3, "[[ XML Domain Info ]]\n"); +- dbg_printf(3, "%s\n[[ XML END ]]\n", domain_desc); +- dbg_printf(2, "Calling virDomainCreateLinux()...\n"); +- +- nvdp = virDomainCreateLinux(info->vp, domain_desc, 0); +- if (nvdp == NULL) { +- /* More recent versions of libvirt or perhaps the +- * KVM back-end do not let you create a domain from +- * XML if there is already a defined domain description +- * with the same name that it knows about. You must +- * then call virDomainCreate() */ +- dbg_printf(2, "Failed; Trying virDomainCreate()...\n"); +- if (virDomainCreate(vdp) < 0) { +- syslog(LOG_NOTICE, +- "Could not restart %s\n", +- vm_name); +- dbg_printf(1, "Failed to recreate guest" +- " %s!\n", vm_name); +- } +- } +- +- free(domain_desc); +- +- return ret; ++ libvirt_validate_connections(info); ++ return vm_reboot(info->vp, info->vp_count, vm_name); + } + + +@@ -400,22 +250,27 @@ + virt_list_t *vl; + int x; + +- dbg_printf(5, "%s\n", __FUNCTION__); ++ dbg_printf(5, "ENTER %s\n", __FUNCTION__); + VALIDATE(info); + +- vl = vl_get(info->vp, 1); ++ libvirt_validate_connections(info); ++ ++ vl = vl_get(info->vp, info->vp_count, 1); + if (!vl) +- return 1; ++ return 0; + + for (x = 0; x < vl->vm_count; x++) { +- dbg_printf(10, "Sending %s\n", vl->vm_states[x].v_uuid); + callback(vl->vm_states[x].v_name, +- vl->vm_states[x].v_uuid, +- vl->vm_states[x].v_state.s_state, arg); ++ vl->vm_states[x].v_uuid, ++ vl->vm_states[x].v_state.s_state, arg); ++ ++ dbg_printf(10, "[libvirt:HOSTLIST] Sent %s %s %d\n", ++ vl->vm_states[x].v_name, ++ vl->vm_states[x].v_uuid, ++ vl->vm_states[x].v_state.s_state); + } + + vl_free(vl); +- + return 0; + } + +@@ -423,46 +278,33 @@ + static int + libvirt_init(backend_context_t *c, config_object_t *config) + { +- virConnectPtr vp; + char value[256]; + struct libvirt_info *info = NULL; +- char *uri = NULL; + +- info = malloc(sizeof(*info)); ++ dbg_printf(5, "ENTER [%s:%d %s]\n", __FILE__, __LINE__, __FUNCTION__); ++ ++ info = calloc(1, sizeof(*info)); + if (!info) + return -1; ++ info->magic = MAGIC; ++ info->config = config; + +- dbg_printf(5, "[%s:%d %s]\n", __FILE__, __LINE__, __FUNCTION__); +- memset(info, 0, sizeof(*info)); ++ libvirt_init_libvirt_conf(info); + + #ifdef _MODULE +- if (sc_get(config, "fence_virtd/@debug", value, sizeof(value))==0) ++ if (sc_get(config, "fence_virtd/@debug", value, sizeof(value)) == 0) + dset(atoi(value)); + #endif + +- if (sc_get(config, "backends/libvirt/@uri", +- value, sizeof(value)) == 0) { +- uri = strdup(value); +- if (!uri) { +- free(info); +- return -1; +- } +- dbg_printf(1, "Using %s\n", uri); +- } +- +- /* We don't need to store the URI; we only use it once */ +- vp = virConnectOpen(uri); +- if (!vp) { +- free(uri); ++ if (info->vp_count < 1) { ++ dbg_printf(1, "[libvirt:INIT] Could not connect to any hypervisors\n"); ++ if (info->vp) ++ free(info->vp); + free(info); + return -1; + } +- free(uri); +- +- info->magic = MAGIC; +- info->vp = vp; + +- *c = (void *)info; ++ *c = (void *) info; + return 0; + } + +@@ -471,16 +313,19 @@ + libvirt_shutdown(backend_context_t c) + { + struct libvirt_info *info = (struct libvirt_info *)c; ++ int i; ++ int ret = 0; + + VALIDATE(info); + +- if (virConnectClose(info->vp) < 0) { +- free(info); +- return -errno; ++ for (i = 0 ; i < info->vp_count ; i++) { ++ if (virConnectClose(info->vp[i]) < 0) ++ ret = -errno; + } + ++ free(info->vp); + free(info); +- return 0; ++ return ret; + } + + +diff -ur a/server/virt.c b/server/virt.c +--- a/server/virt.c 2014-06-23 15:56:09.000000000 -0400 ++++ b/server/virt.c 2017-08-09 13:35:07.247875913 -0400 +@@ -1,5 +1,5 @@ + /* +- Copyright Red Hat, Inc. 2006 ++ Copyright Red Hat, Inc. 2006-2017 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the +@@ -16,7 +16,9 @@ + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + MA 02139, USA. + */ ++ + #include ++#include + #include + #include + #include +@@ -24,8 +26,11 @@ + #include + #include + #include +-#include "virt.h" ++#include + ++#include "debug.h" ++#include "uuid-test.h" ++#include "virt.h" + + static int + _compare_virt(const void *_left, const void *_right) +@@ -37,96 +42,98 @@ + } + + +-virt_list_t *vl_get(virConnectPtr vp, int my_id) +-{ +- virt_list_t *vl = NULL; +- int d_count, x, saved_errno; +- virDomainPtr *dom_list; +- +- errno = EINVAL; +- if (!vp) +- return NULL; +- +- d_count = virConnectListAllDomains(vp, &dom_list, 0); +- if (d_count <= 0) +- goto out_fail; ++static void ++_free_dom_list(virDomainPtr *dom_list, int len) { ++ int x; + +- vl = malloc(sizeof(uint32_t) + sizeof(virt_state_t) * d_count); +- if (!vl) +- goto out_fail; ++ if (!dom_list || len <= 0) ++ return; ++ for (x = 0 ; x < len; x++) ++ virDomainFree(dom_list[x]); + +- vl->vm_count = d_count; ++ free(dom_list); ++} + +- /* Ok, we have the domain IDs - let's get their names and states */ +- for (x = 0; x < d_count; x++) { +- char *d_name; +- virDomainInfo d_info; +- char d_uuid[MAX_DOMAINNAME_LENGTH]; +- virDomainPtr dom = dom_list[x]; + +- if (!(d_name = (char *)virDomainGetName(dom))) +- goto out_fail; ++virt_list_t *vl_get(virConnectPtr *vp, int vp_count, int my_id) ++{ ++ virt_list_t *vl = NULL; ++ int d_count = 0; ++ int i; + +- if (virDomainGetUUIDString(dom, d_uuid) != 0) +- goto out_fail; ++ errno = EINVAL; ++ if (!vp || vp_count < 1) ++ return NULL; + +- if (virDomainGetInfo(dom, &d_info) < 0) +- goto out_fail; ++ for (i = 0 ; i < vp_count ; i++) { ++ int x; ++ virDomainPtr *dom_list; ++ virt_list_t *new_vl; ++ ++ int ret = virConnectListAllDomains(vp[i], &dom_list, 0); ++ if (ret == 0) ++ continue; ++ ++ if (ret < 0) { ++ int saved_errno = errno; ++ dbg_printf(2, "Error: virConnectListAllDomains: %d %d\n", ++ ret, saved_errno); ++ if (vl) ++ free(vl); ++ errno = saved_errno; ++ return NULL; ++ } ++ ++ d_count += ret; ++ new_vl = realloc(vl, sizeof(uint32_t) + sizeof(virt_state_t) * d_count); ++ if (!new_vl) { ++ _free_dom_list(dom_list, ret); ++ free(vl); ++ return NULL; ++ } ++ vl = new_vl; ++ vl->vm_count = d_count; ++ ++ /* Ok, we have the domain IDs - let's get their names and states */ ++ for (x = 0; x < ret; x++) { ++ char *d_name; ++ virDomainInfo d_info; ++ char d_uuid[MAX_DOMAINNAME_LENGTH]; ++ virDomainPtr dom = dom_list[x]; ++ ++ if (!(d_name = (char *)virDomainGetName(dom))) { ++ _free_dom_list(dom_list, ret); ++ free(vl); ++ return NULL; ++ } ++ ++ if (virDomainGetUUIDString(dom, d_uuid) != 0) { ++ _free_dom_list(dom_list, ret); ++ free(vl); ++ return NULL; ++ } ++ ++ if (virDomainGetInfo(dom, &d_info) < 0) { ++ _free_dom_list(dom_list, ret); ++ free(vl); ++ return NULL; ++ } ++ ++ /* Store the name & state */ ++ strncpy(vl->vm_states[x].v_name, d_name, MAX_DOMAINNAME_LENGTH); ++ strncpy(vl->vm_states[x].v_uuid, d_uuid, MAX_DOMAINNAME_LENGTH); ++ vl->vm_states[x].v_state.s_state = d_info.state; ++ vl->vm_states[x].v_state.s_owner = my_id; ++ } + +- /* Store the name & state */ +- strncpy(vl->vm_states[x].v_name, d_name, MAX_DOMAINNAME_LENGTH); +- strncpy(vl->vm_states[x].v_uuid, d_uuid, MAX_DOMAINNAME_LENGTH); +- vl->vm_states[x].v_state.s_state = d_info.state; +- vl->vm_states[x].v_state.s_owner = my_id; ++ _free_dom_list(dom_list, ret); + } + +- for (x = 0 ; x < d_count; x++) +- virDomainFree(dom_list[x]); +- free(dom_list); +- + /* We have all the locally running domains & states now */ + /* Sort */ + qsort(&vl->vm_states[0], vl->vm_count, sizeof(vl->vm_states[0]), + _compare_virt); + return vl; +- +-out_fail: +- saved_errno = errno; +- for (x = 0 ; x < d_count; x++) +- virDomainFree(dom_list[x]); +- free(dom_list); +- +- if (vl) +- free(vl); +- errno = saved_errno; +- return NULL; +-} +- +- +-/* Returns 0 if equal, nonzero if not */ +-int +-vl_cmp(virt_list_t *left, virt_list_t *right) +-{ +- int x; +- +- /* Quick checks */ +- if (!left->vm_count && !right->vm_count) +- return 1; +- if (left->vm_count != right->vm_count) +- return 0; +- +- for (x = 0; x < left->vm_count; x++) { +- if (strcmp(left->vm_states[x].v_name, +- right->vm_states[x].v_name)) +- return 1; +- /* +- if (left->vm_states[x].v_state.s_state != +- right->vm_states[x].v_state.s_state) +- return 1; +- */ +- } +- +- return 0; + } + + +@@ -192,3 +199,333 @@ + { + free(old); + } ++ ++ ++static inline int ++wait_domain(const char *vm_name, virConnectPtr vp, int timeout) ++{ ++ int tries = 0; ++ int response = 1; ++ int ret; ++ virDomainPtr vdp; ++ virDomainInfo vdi; ++ int uuid_check; ++ ++ uuid_check = is_uuid(vm_name); ++ ++ if (uuid_check) { ++ vdp = virDomainLookupByUUIDString(vp, (const char *)vm_name); ++ } else { ++ vdp = virDomainLookupByName(vp, vm_name); ++ } ++ if (!vdp) ++ return 0; ++ ++ /* Check domain liveliness. If the domain is still here, ++ we return failure, and the client must then retry */ ++ /* XXX On the xen 3.0.4 API, we will be able to guarantee ++ synchronous virDomainDestroy, so this check will not ++ be necessary */ ++ do { ++ if (++tries > timeout) ++ break; ++ ++ sleep(1); ++ if (uuid_check) { ++ vdp = virDomainLookupByUUIDString(vp, (const char *)vm_name); ++ } else { ++ vdp = virDomainLookupByName(vp, vm_name); ++ } ++ if (!vdp) { ++ dbg_printf(2, "Domain no longer exists\n"); ++ response = 0; ++ break; ++ } ++ ++ memset(&vdi, 0, sizeof(vdi)); ++ ret = virDomainGetInfo(vdp, &vdi); ++ virDomainFree(vdp); ++ if (ret < 0) ++ continue; ++ ++ if (vdi.state == VIR_DOMAIN_SHUTOFF) { ++ dbg_printf(2, "Domain has been shut off\n"); ++ response = 0; ++ break; ++ } ++ ++ dbg_printf(4, "Domain still exists (state %d) after %d seconds\n", ++ vdi.state, tries); ++ } while (1); ++ ++ return response; ++} ++ ++ ++int ++vm_off(virConnectPtr *vp, int vp_count, const char *vm_name) ++{ ++ virDomainPtr vdp = NULL; ++ virDomainInfo vdi; ++ virDomainPtr (*virt_lookup_fn)(virConnectPtr, const char *); ++ int ret = -1; ++ int i; ++ ++ if (is_uuid(vm_name)) ++ virt_lookup_fn = virDomainLookupByUUIDString; ++ else ++ virt_lookup_fn = virDomainLookupByName; ++ ++ for (i = 0 ; i < vp_count ; i++) { ++ vdp = virt_lookup_fn(vp[i], vm_name); ++ if (vdp) ++ break; ++ } ++ ++ if (!vdp) { ++ dbg_printf(2, "[virt:OFF] Domain %s does not exist\n", vm_name); ++ return 1; ++ } ++ ++ if (virDomainGetInfo(vdp, &vdi) == 0 && vdi.state == VIR_DOMAIN_SHUTOFF) ++ { ++ dbg_printf(2, "[virt:OFF] Nothing to do - " ++ "domain %s is already off\n", ++ vm_name); ++ virDomainFree(vdp); ++ return 0; ++ } ++ ++ syslog(LOG_NOTICE, "Destroying domain %s\n", vm_name); ++ dbg_printf(2, "[virt:OFF] Calling virDomainDestroy for %s\n", vm_name); ++ ++ ret = virDomainDestroy(vdp); ++ virDomainFree(vdp); ++ ++ if (ret < 0) { ++ syslog(LOG_NOTICE, ++ "Failed to destroy domain %s: %d\n", vm_name, ret); ++ dbg_printf(2, "[virt:OFF] Failed to destroy domain: %s %d\n", ++ vm_name, ret); ++ return 1; ++ } ++ ++ if (ret) { ++ syslog(LOG_NOTICE, "Domain %s still exists; fencing failed\n", ++ vm_name); ++ dbg_printf(2, ++ "[virt:OFF] Domain %s still exists; fencing failed\n", ++ vm_name); ++ return 1; ++ } ++ ++ dbg_printf(2, "[virt:OFF] Success for %s\n", vm_name); ++ return 0; ++} ++ ++ ++int ++vm_on(virConnectPtr *vp, int vp_count, const char *vm_name) ++{ ++ virDomainPtr vdp = NULL; ++ virDomainInfo vdi; ++ virDomainPtr (*virt_lookup_fn)(virConnectPtr, const char *); ++ int ret = -1; ++ int i; ++ ++ if (is_uuid(vm_name)) ++ virt_lookup_fn = virDomainLookupByUUIDString; ++ else ++ virt_lookup_fn = virDomainLookupByName; ++ ++ for (i = 0 ; i < vp_count ; i++) { ++ vdp = virt_lookup_fn(vp[i], vm_name); ++ if (vdp) ++ break; ++ } ++ ++ if (!vdp) { ++ dbg_printf(2, "[virt:ON] Domain %s does not exist\n", vm_name); ++ return 1; ++ } ++ ++ if (virDomainGetInfo(vdp, &vdi) == 0 && vdi.state != VIR_DOMAIN_SHUTOFF) { ++ dbg_printf(2, "Nothing to do - domain %s is already running\n", ++ vm_name); ++ virDomainFree(vdp); ++ return 0; ++ } ++ ++ syslog(LOG_NOTICE, "Starting domain %s\n", vm_name); ++ dbg_printf(2, "[virt:ON] Calling virDomainCreate for %s\n", vm_name); ++ ++ ret = virDomainCreate(vdp); ++ virDomainFree(vdp); ++ ++ if (ret < 0) { ++ syslog(LOG_NOTICE, "Failed to start domain %s: %d\n", vm_name, ret); ++ dbg_printf(2, "[virt:ON] virDomainCreate() failed for %s: %d\n", ++ vm_name, ret); ++ return 1; ++ } ++ ++ if (ret) { ++ syslog(LOG_NOTICE, "Domain %s did not start\n", vm_name); ++ dbg_printf(2, "[virt:ON] Domain %s did not start\n", vm_name); ++ return 1; ++ } ++ ++ syslog(LOG_NOTICE, "Domain %s started\n", vm_name); ++ dbg_printf(2, "[virt:ON] Success for %s\n", vm_name); ++ return 0; ++} ++ ++ ++int ++vm_status(virConnectPtr *vp, int vp_count, const char *vm_name) ++{ ++ virDomainPtr vdp = NULL; ++ virDomainInfo vdi; ++ int ret = 0; ++ int i; ++ virDomainPtr (*virt_lookup_fn)(virConnectPtr, const char *); ++ ++ if (is_uuid(vm_name)) ++ virt_lookup_fn = virDomainLookupByUUIDString; ++ else ++ virt_lookup_fn = virDomainLookupByName; ++ ++ for (i = 0 ; i < vp_count ; i++) { ++ vdp = virt_lookup_fn(vp[i], vm_name); ++ if (vdp) ++ break; ++ } ++ ++ if (!vdp) { ++ dbg_printf(2, "[virt:STATUS] Unknown VM %s - return OFF\n", vm_name); ++ return RESP_OFF; ++ } ++ ++ if (virDomainGetInfo(vdp, &vdi) == 0 && vdi.state == VIR_DOMAIN_SHUTOFF) { ++ dbg_printf(2, "[virt:STATUS] VM %s is OFF\n", vm_name); ++ ret = RESP_OFF; ++ } ++ ++ if (vdp) ++ virDomainFree(vdp); ++ return ret; ++} ++ ++ ++int ++vm_reboot(virConnectPtr *vp, int vp_count, const char *vm_name) ++{ ++ virDomainPtr vdp = NULL, nvdp; ++ virDomainInfo vdi; ++ char *domain_desc; ++ virConnectPtr vcp = NULL; ++ virDomainPtr (*virt_lookup_fn)(virConnectPtr, const char *); ++ int ret; ++ int i; ++ ++ if (is_uuid(vm_name)) ++ virt_lookup_fn = virDomainLookupByUUIDString; ++ else ++ virt_lookup_fn = virDomainLookupByName; ++ ++ for (i = 0 ; i < vp_count ; i++) { ++ vdp = virt_lookup_fn(vp[i], vm_name); ++ if (vdp) { ++ vcp = vp[i]; ++ break; ++ } ++ } ++ ++ if (!vdp || !vcp) { ++ dbg_printf(2, ++ "[virt:REBOOT] Nothing to do - domain %s does not exist\n", ++ vm_name); ++ return 1; ++ } ++ ++ if (virDomainGetInfo(vdp, &vdi) == 0 && vdi.state == VIR_DOMAIN_SHUTOFF) { ++ dbg_printf(2, "[virt:REBOOT] Nothing to do - domain %s is off\n", ++ vm_name); ++ virDomainFree(vdp); ++ return 0; ++ } ++ ++ syslog(LOG_NOTICE, "Rebooting domain %s\n", vm_name); ++ dbg_printf(5, "[virt:REBOOT] Rebooting domain %s...\n", vm_name); ++ ++ domain_desc = virDomainGetXMLDesc(vdp, 0); ++ ++ if (!domain_desc) { ++ dbg_printf(5, "[virt:REBOOT] Failed getting domain description " ++ "from libvirt for %s...\n", vm_name); ++ } ++ ++ dbg_printf(2, "[virt:REBOOT] Calling virDomainDestroy(%p) for %s\n", ++ vdp, vm_name); ++ ++ ret = virDomainDestroy(vdp); ++ if (ret < 0) { ++ dbg_printf(2, ++ "[virt:REBOOT] virDomainDestroy() failed for %s: %d/%d\n", ++ vm_name, ret, errno); ++ ++ if (domain_desc) ++ free(domain_desc); ++ virDomainFree(vdp); ++ return 1; ++ } ++ ++ ret = wait_domain(vm_name, vcp, 15); ++ ++ if (ret) { ++ syslog(LOG_NOTICE, "Domain %s still exists; fencing failed\n", vm_name); ++ dbg_printf(2, ++ "[virt:REBOOT] Domain %s still exists; fencing failed\n", ++ vm_name); ++ ++ if (domain_desc) ++ free(domain_desc); ++ virDomainFree(vdp); ++ return 1; ++ } ++ ++ if (!domain_desc) ++ return 0; ++ ++ /* 'on' is not a failure */ ++ ret = 0; ++ ++ dbg_printf(3, "[[ XML Domain Info ]]\n"); ++ dbg_printf(3, "%s\n[[ XML END ]]\n", domain_desc); ++ ++ dbg_printf(2, "[virt:REBOOT] Calling virDomainCreateLinux() for %s\n", ++ vm_name); ++ ++ nvdp = virDomainCreateLinux(vcp, domain_desc, 0); ++ if (nvdp == NULL) { ++ /* More recent versions of libvirt or perhaps the ++ * KVM back-end do not let you create a domain from ++ * XML if there is already a defined domain description ++ * with the same name that it knows about. You must ++ * then call virDomainCreate() */ ++ dbg_printf(2, ++ "[virt:REBOOT] virDomainCreateLinux() failed for %s; " ++ "Trying virDomainCreate()\n", ++ vm_name); ++ ++ if (virDomainCreate(vdp) < 0) { ++ syslog(LOG_NOTICE, "Could not restart %s\n", vm_name); ++ dbg_printf(1, "[virt:REBOOT] Failed to recreate guest %s!\n", ++ vm_name); ++ } ++ } ++ ++ free(domain_desc); ++ virDomainFree(vdp); ++ return ret; ++} +diff -ur a/server/virt.h b/server/virt.h +--- a/server/virt.h 2014-06-23 15:56:09.000000000 -0400 ++++ b/server/virt.h 2017-08-09 13:30:40.709689288 -0400 +@@ -1,5 +1,5 @@ + /* +- Copyright Red Hat, Inc. 2006 ++ Copyright Red Hat, Inc. 2006-2017 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the +@@ -16,11 +16,13 @@ + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + MA 02139, USA. + */ ++ + #ifndef _VIRT_H + #define _VIRT_H +-#include ++ + #include + #include ++#include + + #include "xvm.h" + +@@ -59,15 +61,16 @@ + virt_state_t vm_states[0]; + } virt_list_t; + +-virt_list_t *vl_get(virConnectPtr vp, int my_id); +- +-int vl_cmp(virt_list_t *left, virt_list_t *right); +- ++virt_list_t *vl_get(virConnectPtr *vp, int vp_count, int my_id); + void vl_print(virt_list_t *vl); + void vl_free(virt_list_t *old); +-virt_state_t * vl_find_uuid(virt_list_t *vl, const char *name); +-virt_state_t * vl_find_name(virt_list_t *vl, const char *name); ++virt_state_t *vl_find_uuid(virt_list_t *vl, const char *name); ++virt_state_t *vl_find_name(virt_list_t *vl, const char *name); + ++int vm_off(virConnectPtr *vp, int vp_count, const char *vm_name); ++int vm_on(virConnectPtr *vp, int vp_count, const char *vm_name); ++int vm_status(virConnectPtr *vp, int vp_count, const char *vm_name); ++int vm_reboot(virConnectPtr *vp, int vp_count, const char *vm_name); + + typedef void ckpt_handle; + int ckpt_read(void *hp, const char *secid, void *buf, size_t maxlen); diff --git a/SOURCES/bz1393958-cleanup_numeric_argument_parsing.patch b/SOURCES/bz1393958-cleanup_numeric_argument_parsing.patch new file mode 100644 index 0000000..eba1b26 --- /dev/null +++ b/SOURCES/bz1393958-cleanup_numeric_argument_parsing.patch @@ -0,0 +1,118 @@ +diff -ur a/client/options.c b/client/options.c +--- a/client/options.c 2017-03-13 17:48:52.083747432 -0400 ++++ b/client/options.c 2017-03-13 17:50:37.289128784 -0400 +@@ -130,14 +130,18 @@ + static inline void + assign_port(fence_virt_args_t *args, struct arg_info *arg, char *value) + { ++ char *p; ++ int ret; ++ + if (!value) + return; + +- args->net.port = atoi(value); +- if (args->net.port <= 0 || args->net.port >= 65536) { ++ ret = strtol(value, &p, 0); ++ if (ret <= 0 || ret >= 65536 || *p != '\0') { + printf("Invalid port: '%s'\n", value); + args->flags |= F_ERR; +- } ++ } else ++ args->net.port = ret; + } + + +@@ -154,14 +158,18 @@ + static inline void + assign_retrans(fence_virt_args_t *args, struct arg_info *arg, char *value) + { ++ char *p; ++ int ret; ++ + if (!value) + return; + +- args->retr_time = atoi(value); +- if (args->retr_time <= 0) { ++ ret = strtol(value, &p, 0); ++ if (ret <= 0 || *p != '\0') { + printf("Invalid retransmit time: '%s'\n", value); + args->flags |= F_ERR; +- } ++ } else ++ args->retr_time = ret; + } + + static inline void +@@ -319,27 +327,35 @@ + static inline void + assign_timeout(fence_virt_args_t *args, struct arg_info *arg, char *value) + { ++ char *p; ++ int ret; ++ + if (!value) + return; + +- args->timeout = atoi(value); +- if (args->timeout <= 0) { ++ ret = strtol(value, &p, 0); ++ if (ret <= 0 || *p != '\0') { + printf("Invalid timeout: '%s'\n", value); + args->flags |= F_ERR; +- } ++ } else ++ args->timeout = ret; + } + + static inline void + assign_delay(fence_virt_args_t *args, struct arg_info *arg, char *value) + { ++ char *p; ++ int ret; ++ + if (!value) + return; + +- args->delay = atoi(value); +- if (args->delay <= 0) { ++ ret = strtol(value, &p, 0); ++ if (ret < 0 || *p != '\0') { + printf("Invalid delay: '%s'\n", value); + args->flags |= F_ERR; +- } ++ } else ++ args->delay = ret; + } + + static inline void +diff -ur a/server/config.c b/server/config.c +--- a/server/config.c 2017-03-13 17:48:52.081747462 -0400 ++++ b/server/config.c 2017-03-13 17:49:08.526494450 -0400 +@@ -237,9 +237,10 @@ + + do { + text_input("Multicast IP Port", val, inp, sizeof(inp)); ++ char *p; + +- done = atoi(inp); +- if (done <= 0 || done >= 65536) { ++ done = strtol(inp, &p, 0); ++ if (*p != '\0' || done <= 0 || done >= 65536) { + printf("Port value '%s' is out of range\n", val); + continue; + } +@@ -374,9 +375,10 @@ + + do { + text_input("TCP Listen Port", val, inp, sizeof(inp)); ++ char *p; + +- done = atoi(inp); +- if (done <= 0 || done != (done & 0xffff)) { ++ done = strtol(inp, &p, 0); ++ if (*p != '\0' || done <= 0 || done >= 65536) { + printf("Port value '%s' is out of range\n", val); + continue; + } diff --git a/SOURCES/bz1411910-fence_virtd_drop_legacy_sysvstartpriority_from_service.patch b/SOURCES/bz1411910-fence_virtd_drop_legacy_sysvstartpriority_from_service.patch new file mode 100644 index 0000000..fb91778 --- /dev/null +++ b/SOURCES/bz1411910-fence_virtd_drop_legacy_sysvstartpriority_from_service.patch @@ -0,0 +1,40 @@ +From 16503d909bec51b87732cf34efd004818021ed28 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Mon, 3 Aug 2015 18:17:44 +0200 +Subject: [PATCH] fence_virtd: drop legacy SysVStartPriority from service + unit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since systemd-218[1], systemd will emit following lines in the +journal upon (re)loading its configuration: + +Support for option SysVStartPriority= has been removed and it is +ignored + +As it allegedly had no importance for some time even before, simply +drop it. + +[1] http://cgit.freedesktop.org/systemd/systemd/commit/?id=9e37c95 + +Signed-off-by: Jan Pokorný +--- + fence_virtd.service.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/fence_virtd.service.in b/fence_virtd.service.in +index e69d3d3..14c2b3a 100644 +--- a/fence_virtd.service.in ++++ b/fence_virtd.service.in +@@ -17,7 +17,6 @@ WantedBy=multi-user.target + [Service] + Type=forking + Restart=on-failure +-SysVStartPriority=99 + Environment="FENCE_VIRTD_ARGS=-w" + + # Autogenerated below here +-- +2.9.3 + diff --git a/SOURCES/bz1447700-virt_add_support_for_the_validate_all_status.patch b/SOURCES/bz1447700-virt_add_support_for_the_validate_all_status.patch new file mode 100644 index 0000000..ab46eee --- /dev/null +++ b/SOURCES/bz1447700-virt_add_support_for_the_validate_all_status.patch @@ -0,0 +1,110 @@ +diff -ur a/client/main.c b/client/main.c +--- a/client/main.c 2017-08-09 13:13:20.000846414 -0400 ++++ b/client/main.c 2017-08-09 13:09:04.294571613 -0400 +@@ -110,13 +110,17 @@ + } + + if (args.flags & F_ERR) { +- args_usage(argv[0], my_options, (argc == 1)); ++ if (args.op != FENCE_VALIDATEALL) ++ args_usage(argv[0], my_options, (argc == 1)); + exit(1); + } + ++ if (args.op == FENCE_VALIDATEALL) ++ exit(0); ++ + if (args.op == FENCE_METADATA) { + args_metadata(argv[0], my_options); +- return 0; ++ exit(0); + } + + if (args.delay > 0 && +diff -ur a/client/options.c b/client/options.c +--- a/client/options.c 2017-08-09 13:13:20.007846312 -0400 ++++ b/client/options.c 2017-08-09 13:11:23.464550208 -0400 +@@ -255,6 +255,8 @@ + args->op = FENCE_HOSTLIST; + } else if (!strcasecmp(value, "metadata")) { + args->op = FENCE_METADATA; ++ } else if (!strcasecmp(value, "validate-all")) { ++ args->op = FENCE_VALIDATEALL; + } else { + printf("Unsupported operation: %s\n", value); + args->flags |= F_ERR; +@@ -490,12 +492,12 @@ + { '\xff', NULL, "option", + /* Deprecated */ + 0, "string", "reboot", +- "Fencing option (null, off, on, [reboot], status, list, monitor, metadata)", ++ "Fencing option (null, off, on, [reboot], status, list, list-status, monitor, validate-all, metadata)", + assign_op }, + + { 'o', "-o ", "action", + 0, "string", "reboot", +- "Fencing action (null, off, on, [reboot], status, list, monitor, metadata)", ++ "Fencing action (null, off, on, [reboot], status, list, list-status, monitor, validate-all, metadata)", + assign_op }, + + { 'H', "-H ", "port", +@@ -799,7 +801,8 @@ + printf("\t\n"); + printf("\t\n"); + printf("\t\n"); +- printf("\t\n"); ++ printf("\t\n"); ++ printf("\t\n"); + printf("\n"); + printf("\n"); + } +diff -ur a/include/xvm.h b/include/xvm.h +--- a/include/xvm.h 2014-06-23 15:56:09.000000000 -0400 ++++ b/include/xvm.h 2017-08-09 13:09:04.295571598 -0400 +@@ -52,14 +52,15 @@ + #define DEFAULT_AUTH AUTH_SHA256 + + typedef enum { +- FENCE_NULL = 0x0, +- FENCE_OFF = 0x1, /* Turn the VM off */ +- FENCE_REBOOT = 0x2, /* Hit the reset button */ +- FENCE_ON = 0x3, /* Turn the VM on */ +- FENCE_STATUS = 0x4, /* virtual machine status (off/on) */ +- FENCE_DEVSTATUS = 0x5, /* Status of the fencing device */ +- FENCE_HOSTLIST = 0x6, /* List VMs controllable */ +- FENCE_METADATA = 0x7 ++ FENCE_NULL = 0x0, ++ FENCE_OFF = 0x1, /* Turn the VM off */ ++ FENCE_REBOOT = 0x2, /* Hit the reset button */ ++ FENCE_ON = 0x3, /* Turn the VM on */ ++ FENCE_STATUS = 0x4, /* virtual machine status (off/on) */ ++ FENCE_DEVSTATUS = 0x5, /* Status of the fencing device */ ++ FENCE_HOSTLIST = 0x6, /* List VMs controllable */ ++ FENCE_METADATA = 0x7, /* Print fence agent metadata */ ++ FENCE_VALIDATEALL = 0x8 /* Validate command-line or stdin arguments and exit */ + } fence_cmd_t; + + #define DEFAULT_TTL 4 +diff -ur a/man/fence_virt.8 b/man/fence_virt.8 +--- a/man/fence_virt.8 2014-06-23 15:56:09.000000000 -0400 ++++ b/man/fence_virt.8 2017-08-09 13:09:04.295571598 -0400 +@@ -145,7 +145,7 @@ + .TP + .B action + . +-Fencing action (null, off, on, reboot, status, monitor, list, or metadata) (Default Value: reboot). See the FENCING ACTIONS section. ++Fencing action (null, off, on, reboot, status, monitor, list, list-status, validate-all, or metadata) (Default Value: reboot). See the FENCING ACTIONS section. + + .TP + .B timeout +@@ -255,6 +255,10 @@ + on all backends). + + .TP ++\fBvalidate-all\fP ++Validate arguments given on either the command line or standard input. If validation fails, the fence agent will exit with code 1, otherwise it will exit with code 0. ++ ++.TP + \fBmetadata \fP + Print XML metadata to standard output. + diff --git a/SOURCES/bz1600566-fence_virt-dont-report-success-incorrect-parameter.patch b/SOURCES/bz1600566-fence_virt-dont-report-success-incorrect-parameter.patch new file mode 100644 index 0000000..6c541f9 --- /dev/null +++ b/SOURCES/bz1600566-fence_virt-dont-report-success-incorrect-parameter.patch @@ -0,0 +1,35 @@ +From 83e507cd236c304ce6b95b2ba52d3894f8002dc8 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Fri, 9 Nov 2018 13:10:29 +0100 +Subject: [PATCH] fence_virt: dont report success for incorrect parameters + +--- + client/main.c | 2 +- + client/options.c | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/client/main.c b/client/main.c +index 8e94093..a3135e3 100644 +--- a/client/main.c ++++ b/client/main.c +@@ -112,7 +112,7 @@ main(int argc, char **argv) + args.mode = MODE_VSOCK; + + if (args.flags & F_ERR) { +- if (args.op != FENCE_VALIDATEALL) ++ if (args.op != FENCE_VALIDATEALL) + args_usage(argv[0], my_options, (argc == 1)); + exit(1); + } +diff --git a/client/options.c b/client/options.c +index a3f321b..4b5ed56 100644 +--- a/client/options.c ++++ b/client/options.c +@@ -904,6 +904,7 @@ args_get_stdin(const char *optstr, fence_virt_args_t *args) + "parse warning: " + "illegal variable '%s' on line %d\n", name, + line); ++ args->flags |= F_ERR; + continue; + } + diff --git a/SPECS/fence-virt.spec b/SPECS/fence-virt.spec new file mode 100644 index 0000000..f56445c --- /dev/null +++ b/SPECS/fence-virt.spec @@ -0,0 +1,402 @@ +Name: fence-virt +Version: 0.3.2 +Release: 14%{?dist} +Summary: A pluggable fencing framework for virtual machines +Group: System Environment/Base +License: GPLv2+ + +%if 0%{?rhel} +ExclusiveArch: i686 x86_64 ppc64le +%endif + +URL: http://fence-virt.sourceforge.net +Source0: http://people.redhat.com/rmccabe/fence-virt/%{name}-%{version}.tar.bz2 + +Patch0: bz1207422-client_do_not_truncate_vm_domains_in_list_output.patch +Patch1: bz1078197-fix_broken_restrictions_on_the_port_ranges.patch +Patch2: bz1204873-fix_delay_parameter_checking_copy_paste.patch +Patch3: bz1204877-remove_delay_from_the_status,_monitor_and_list.patch +Patch4: bz1334170-allow_fence_virtd_to_run_as_non_root.patch +Patch5: bz1334170-2-fix_use_of_undefined_#define.patch +Patch6: bz1291522-Install_firewalld_unit_file.patch +Patch7: bz1393958-cleanup_numeric_argument_parsing.patch +Patch8: bz1411910-fence_virtd_drop_legacy_sysvstartpriority_from_service.patch +Patch9: bz1334170-cleanup_documentation_of_the_tcp_listener.patch +Patch10: bz1092531-enable_hardening.patch +Patch11: bz1447700-virt_add_support_for_the_validate_all_status.patch +Patch12: bz1384181-make_the_libvirt_backend_survive_libvirtd.patch +Patch13: bz1600566-fence_virt-dont-report-success-incorrect-parameter.patch + +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + +BuildRequires: corosynclib-devel libvirt-devel +BuildRequires: automake autoconf libxml2-devel nss-devel nspr-devel +BuildRequires: flex bison libuuid-devel + +BuildRequires: systemd-units +Requires(post): systemd-sysv systemd-units firewalld-filesystem +Requires(preun): systemd-units +Requires(postun): systemd-units + +Conflicts: fence-agents < 3.0.5-2 + + +%description +Fencing agent for virtual machines. + +%global _hardened_build 1 + +%package -n fence-virtd +Summary: Daemon which handles requests from fence-virt +Group: System Environment/Base + +%description -n fence-virtd +This package provides the host server framework, fence_virtd, +for fence_virt. The fence_virtd host daemon is resposible for +processing fencing requests from virtual machines and routing +the requests to the appropriate physical machine for action. + + +%package -n fence-virtd-multicast +Summary: Multicast listener for fence-virtd +Group: System Environment/Base +Requires: fence-virtd + +%description -n fence-virtd-multicast +Provides multicast listener capability for fence-virtd. + + +%package -n fence-virtd-serial +Summary: Serial VMChannel listener for fence-virtd +Group: System Environment/Base +Requires: libvirt >= 0.6.2 +Requires: fence-virtd + +%description -n fence-virtd-serial +Provides serial VMChannel listener capability for fence-virtd. + +%package -n fence-virtd-tcp +Summary: Tcp listener for fence-virtd +Group: System Environment/Base +Requires: fence-virtd + +%description -n fence-virtd-tcp +Provides TCP listener capability for fence-virtd. + +%package -n fence-virtd-libvirt +Summary: Libvirt backend for fence-virtd +Group: System Environment/Base +Requires: libvirt >= 0.6.0 +Requires: fence-virtd + +%description -n fence-virtd-libvirt +Provides fence_virtd with a connection to libvirt to fence +virtual machines. Useful for running a cluster of virtual +machines on a desktop. + + +%prep +%setup -q + +%patch0 -p1 -b .bz1207422 +%patch1 -p1 -b .bz1078197.1 +%patch2 -p1 -b .bz1204873.1 +%patch3 -p1 -b .bz1204877.1 +%patch4 -p1 -b .bz1334170.1 +%patch5 -p1 -b .bz1334170.2 +%patch6 -p1 -b .bz1291522.1 +%patch7 -p1 -b .bz1393958.1 +%patch8 -p1 -b .bz1411910.1 +%patch9 -p1 -b .bz1334170.1 +%patch10 -p1 -b .bz1092531.1 +%patch11 -p1 -b .bz1447700.1 +%patch12 -p1 -b .bz1384181.1 +%patch13 -p1 -F1 + +%build +%ifarch s390 s390x sparcv9 sparc64 +export PIECFLAGS="-fPIE" +%else +export PIECFLAGS="-fpie" +%endif + +export RELRO="-Wl,-z,relro,-z,now" +export CFLAGS="$RPM_OPT_FLAGS $CPPFLAGS $PIECFLAGS $RELRO" +export CXXFLAGS="$RPM_OPT_FLAGS $CPPFLAGS $PIECFLAGS $RELRO" +export LDFLAGS="$LDFLAGS -pie" + +./autogen.sh +%{configure} --disable-libvirt-qmf-plugin --enable-tcp-plugin +make %{?_smp_mflags} + + +%install +rm -rf %{buildroot} +make install DESTDIR=%{buildroot} + +# Systemd unit file +mkdir -p %{buildroot}/%{_unitdir}/ +install -m 0644 fence_virtd.service %{buildroot}/%{_unitdir}/ + +# firewalld service file +mkdir -p %{buildroot}/%{_prefix}/lib/firewalld/services/ +install -m 0644 fence_virt.xml %{buildroot}/%{_prefix}/lib/firewalld/services/ + +%clean +rm -rf %{buildroot} + + +%files +%defattr(-,root,root,-) +%doc COPYING TODO README +%{_sbindir}/fence_virt +%{_sbindir}/fence_xvm +%{_mandir}/man8/fence_virt.* +%{_mandir}/man8/fence_xvm.* + + +%post +ccs_update_schema > /dev/null 2>&1 ||: +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Systemd +if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl daemon-reload >/dev/null 2>&1 || : +fi + +%preun +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Systemd +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable fence_virtd.service &> /dev/null || : + /bin/systemctl stop fence_virtd.service &> /dev/null || : +fi + +%postun +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Systemd +/bin/systemctl daemon-reload &> /dev/null || : +if [ $1 -ge 1 ] ; then + # Package upgrade, not uninstall + /bin/systemctl try-restart fence_virtd.service &> /dev/null || : +fi + + +%triggerun -- fence_virtd < 0.3.0-1 +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Packages_migrating_to_a_systemd_unit_file_from_a_SysV_initscript +/usr/bin/systemd-sysv-convert --save fence_virtd &> /dev/null || : +/sbin/chkconfig --del fence_virtd &> /dev/null || : +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +/bin/systemctl try-restart fence_virtd.service &> /dev/null || : + + +%files -n fence-virtd +%defattr(-,root,root,-) +%{_sbindir}/fence_virtd +%{_unitdir}/fence_virtd.service +%{_prefix}/lib/firewalld/services/fence_virt.xml +%config(noreplace) %{_sysconfdir}/fence_virt.conf +%dir %{_libdir}/%{name} +%{_mandir}/man5/fence_virt.conf.* +%{_mandir}/man8/fence_virtd.* + +%files -n fence-virtd-multicast +%defattr(-,root,root,-) +%{_libdir}/%{name}/multicast.so + +%files -n fence-virtd-serial +%defattr(-,root,root,-) +%{_libdir}/%{name}/serial.so + +%files -n fence-virtd-tcp +%defattr(-,root,root,-) +%{_libdir}/%{name}/tcp.so + +%files -n fence-virtd-libvirt +%defattr(-,root,root,-) +%{_libdir}/%{name}/libvirt.so + +%changelog +* Tue Jan 22 2019 Oyvind Albrigtsen - 0.3.2-14 +- fence_xvm/fence_virt: dont report success incorrect parameter + Resolves: rhbz#1600566 + +* Wed Aug 09 2017 Ryan McCabe - 0.3.2-13 +- fence_virtd: Make the libvirt backend survive libvirtd restarts + Resolves: rhbz#1384181 +- fence_xvm/fence_virt: Add support for the validate-all status + Resolves: rhbz#1447700 + +* Wed Jun 14 2017 Ryan McCabe - 0.3.2-12 +- fence-virt: Rebuild to restore debuginfo + Resolves: rhbz#1092531 + +* Mon May 22 2017 Ryan McCabe - 0.3.2-11 +- fence-virt: Enable PIE and full RELRO + Resolves: rhbz#1092531 + +* Mon May 22 2017 Ryan McCabe - 0.3.2-10 +- fence-virt: Enable PIE and RELRO + Resolves: rhbz#1092531 + +* Wed May 17 2017 Ryan McCabe - 0.3.2-9 +- fence-virtd: Cleanup documentation of the TCP listener + Resolves: rhbz#1334170 + +* Wed Mar 15 2017 Ryan McCabe - 0.3.2-8 +- fence-virt: Build for ppc64le + Resolves: rhbz#1402572 + +* Mon Mar 13 2017 Ryan McCabe - 0.3.2-7 +- fence_virtd: drop legacy SysVStartPriority from service + Resolves: rhbz#1411910 + +* Mon Mar 13 2017 Ryan McCabe - 0.3.2-6 +- fence-virt: Cleanup numeric argument parsing + Resolves: rhbz#1393958 + +* Tue Jun 28 2016 Ryan McCabe - 0.3.2-5 +- fence-virt: Add firewalld service file. + Resolves: rhbz#1291522 + +* Mon Jun 27 2016 Ryan McCabe - 0.3.2-4 +- fence-virt: Enable the TCP listener plugin + Resolves: rhbz#1334170 +- Allow fence_virtd to run as non-root + Fix use of undefined define + Resolves: rhbz#1334170 + +* Mon Jun 27 2016 Ryan McCabe - 0.3.2-3 +- fence-virt: Fix broken restrictions on the port ranges + Resolves: rhbz#1214301 +- client: Fix "delay" parameter checking + Resolves: rhbz#1204877 +- Remove delay from the status, monitor and list + Resolves: rhbz#1204877 + +* Fri Jul 17 2015 Ryan McCabe - 0.3.2-2 +- Do not truncate VM domains in the output of the list command. + Resolves: rhbz#1207422 + +* Mon Sep 08 2014 Ryan McCabe - 0.3.2-1 +- Rebase to the 0.3.2 release. + Resolves: rhbz#1111384 + +* Wed Feb 19 2014 Ryan McCabe - 0.3.0-16 +- Fail cleanly when unable to bind the TCP listener socket + +* Tue Feb 18 2014 Ryan McCabe - 0.3.0-15 +- Remove references to syslog.target from the fence_virtd systemd unit file + +* Fri Dec 27 2013 Daniel Mach - 0.3.0-14 +- Mass rebuild 2013-12-27 + +* Tue May 07 2013 Ryan McCabe - 0.3.0-13 +- Rebuild + +* Tue May 07 2013 Ryan McCabe - 0.3.0-12 +- Drop libvirt-qmf-plugin + +* Wed Feb 13 2013 Fedora Release Engineering - 0.3.0-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Nov 02 2012 Ryan McCabe - 0.3.0-10 +- bswap fix for big endian + +* Fri Nov 02 2012 Ryan McCabe - 0.3.0-9 +- Return success if a domain exists but is already off. + +* Thu Oct 25 2012 Ryan McCabe - 0.3.0-8 +- Version bump + +* Thu Oct 25 2012 Ryan McCabe - 0.3.0-7 +- Fix uninitialized variable for the -w option. + +* Mon Oct 15 2012 Ryan McCabe - 0.3.0-6 +- Add a -w (delay) option. +- Return failure when attempting to fence a nonexistent domain +- Improve man pages + +* Thu Jul 19 2012 Fedora Release Engineering - 0.3.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Mar 27 2012 Ryan McCabe 0.3.0-4 +- Add QPid build fix patch from upstream. + +* Fri Feb 10 2012 Lon Hohberger 0.3.0-2 +- Fix URL / Source0 lines + Resolves: Fedora#706560 + +* Tue Feb 07 2012 Lon Hohberger 0.3.0-1 +- Rebase from upstream to 0.3.0 +- Systemd unit file integration +- Pacemaker backend +- Various fixes for startup +- Rename libvirt-qpid to libvirt-qmf backend +- Updated default configuration for easier deployment on + Fedora systems + +* Tue Feb 07 2012 Lon Hohberger - 0.2.3-6 +- Bump and rebuild + +* Tue Feb 07 2012 Lon Hohberger - 0.2.3-5 +- Fixup changelog + +* Mon Feb 06 2012 Lon Hohberger - 0.2.3-4 +- Drop checkpoint backend since cman and openais are gone + +* Fri Jan 13 2012 Fedora Release Engineering - 0.2.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Jul 8 2011 Fabio M. Di Nitto - 0.2.3-2 +- add post call to fence-virt to integrate with cluster 3.1.4 + +* Wed Jun 29 2011 Fabio M. Di Nitto 0.2.3-1 +- new upstream release fix compat regression + +* Mon Jun 27 2011 Fabio M. Di Nitto 0.2.2-1 +- new upstream release + +* Mon May 09 2011 Fabio M. Di Nitto 0.2.1-5 +- Rebuilt for libqmfconsole soname change + +* Tue Feb 08 2011 Fedora Release Engineering - 0.2.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Apr 01 2010 Lon Hohberger 0.2.1-3 +- Update specfile to require correct qpid/qmf libraries +- Resolves: bz#565111 + +* Tue Feb 23 2010 Fabio M. Di Nitto 0.2.1-2 +- Update spec file to handle correctly versioned Requires + +* Fri Jan 15 2010 Lon Hohberger 0.2.1-1 +- Update to latest upstream version +- Fix bug around status return codes for VMs which are 'off' + +* Thu Jan 14 2010 Lon Hohberger 0.2-1 +- Update to latest upstream version +- Serial & VMChannel listener support +- Static permission map support +- Man pages +- Init script +- Various bugfixes + +* Mon Sep 21 2009 Lon Hohberger 0.1.3-1 +- Update to latest upstream version +- Adds libvirt-qpid backend support +- Fixes UUID operation with libvirt backend +- Adds man page for fence_xvm and fence_virt +- Provides fence_xvm compatibility for cluster 3.0.6 + +* Mon Sep 21 2009 Lon Hohberger 0.1.2-1 +- Update to latest upstream version +- Fix build issue on i686 + +* Mon Sep 21 2009 Lon Hohberger 0.1.1-1 +- Update to latest upstream version +- Clean up spec file + +* Mon Sep 21 2009 Lon Hohberger 0.1-2 +- Spec file cleanup + +* Thu Sep 17 2009 Lon Hohberger 0.1-1 +- Initial build for rawhide