forked from altcloud/fence-virt
Enable VM Channel support in serial plugin
- Add cmdline processing for channel_ip - Allow 'port' to be used in fence_virt mode - Allow configuration of vmchannel mode for fence_virtd serial plugin - Remove serial port default from fence_virt. It must now be specified or else VM Channel mode is used. Note that to use VM Channel mode, you need: qemu 0.12.1 or later libvirt 0.7.3 or later - Update man pages Signed-off-by: Lon Hohberger <lon@users.sourceforge.net>
This commit is contained in:
parent
4602faeaf2
commit
f665796f26
@ -59,7 +59,7 @@ main(int argc, char **argv)
|
||||
my_options = "di:a:p:r:C:c:k:M:H:uo:t:?hV";
|
||||
args.mode = MODE_MULTICAST;
|
||||
} else {
|
||||
my_options = "dD:P:M:H:o:t:?hV";
|
||||
my_options = "dD:P:A:p:M:H:o:t:?hV";
|
||||
args.mode = MODE_SERIAL;
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,15 @@ assign_address(fence_virt_args_t *args, struct arg_info *arg, char *value)
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
assign_channel_address(fence_virt_args_t *args, struct arg_info *arg, char *value)
|
||||
{
|
||||
if (args->serial.address)
|
||||
free(args->serial.address);
|
||||
args->serial.address = strdup(value);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
assign_port(fence_virt_args_t *args, struct arg_info *arg, char *value)
|
||||
{
|
||||
@ -319,8 +328,12 @@ static struct arg_info _arg_info[] = {
|
||||
"Multicast address (default=" IPV4_MCAST_DEFAULT " / " IPV6_MCAST_DEFAULT ")",
|
||||
assign_address },
|
||||
|
||||
{ 'A', "-A <address>", "channel_address",
|
||||
"VM Channel IP address (default=" DEFAULT_CHANNEL_IP ")",
|
||||
assign_channel_address },
|
||||
|
||||
{ 'p', "-p <port>", "port",
|
||||
"IP port (default=1229)",
|
||||
"Multicast or VMChannel IP port (default=1229)",
|
||||
assign_port },
|
||||
|
||||
{ 'I', "-I <interface>", "interface",
|
||||
@ -443,8 +456,9 @@ args_init(fence_virt_args_t *args)
|
||||
args->net.port = DEFAULT_MCAST_PORT;
|
||||
args->net.ifindex = 0;
|
||||
args->net.family = PF_INET;
|
||||
args->serial.device = strdup(DEFAULT_SERIAL_DEVICE);
|
||||
args->serial.device = NULL;
|
||||
args->serial.speed = strdup(DEFAULT_SERIAL_SPEED);
|
||||
args->serial.address = strdup(DEFAULT_CHANNEL_IP);
|
||||
args->timeout = 30;
|
||||
args->retr_time = 20;
|
||||
args->flags = 0;
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <xvm.h>
|
||||
#include <options.h>
|
||||
#include <client.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <tcp.h>
|
||||
|
||||
|
||||
static int
|
||||
@ -212,12 +214,15 @@ wait_for(int fd, const char *pattern, size_t size, struct timeval *tout)
|
||||
int
|
||||
serial_fence_virt(fence_virt_args_t *args)
|
||||
{
|
||||
struct in_addr ina;
|
||||
struct in6_addr in6a;
|
||||
serial_req_t req;
|
||||
int fd, ret;
|
||||
char speed[32], *flags = NULL;
|
||||
struct timeval tv;
|
||||
serial_resp_t resp;
|
||||
|
||||
if (args->serial.device) {
|
||||
strncpy(speed, args->serial.speed, sizeof(speed));
|
||||
|
||||
//printf("Port: %s Speed: %s\n", args->serial.device, speed);
|
||||
@ -234,6 +239,21 @@ serial_fence_virt(fence_virt_args_t *args)
|
||||
}
|
||||
|
||||
hangup(fd, 300000);
|
||||
} else {
|
||||
fd = -1;
|
||||
if (inet_pton(PF_INET, args->serial.address, &ina)) {
|
||||
fd = ipv4_connect(&ina, args->net.port, 3);
|
||||
} else if (inet_pton(PF_INET6, args->serial.address, &in6a)) {
|
||||
fd = ipv6_connect(&in6a, args->net.port, 3);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
perror("vmchannel connect");
|
||||
printf("Failed to connect to %s:%d\n", args->serial.address,
|
||||
args->net.port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.magic = SERIAL_MAGIC;
|
||||
@ -241,8 +261,6 @@ serial_fence_virt(fence_virt_args_t *args)
|
||||
gettimeofday(&tv, NULL);
|
||||
req.seqno = (int)tv.tv_usec;
|
||||
|
||||
if (args->flags & RF_UUID)
|
||||
req.flags |= RF_UUID;
|
||||
if (args->domain)
|
||||
strncpy((char *)req.domain, args->domain, sizeof(req.domain));
|
||||
|
||||
|
@ -60,6 +60,7 @@ typedef struct {
|
||||
struct serial_args {
|
||||
char *device; /* Serial device */
|
||||
char *speed;
|
||||
char *address; /* vmchannel IP */
|
||||
} serial;
|
||||
} fence_virt_args_t;
|
||||
|
||||
|
@ -96,6 +96,7 @@ typedef struct __attribute__ ((packed)) _host_info {
|
||||
|
||||
#define DEFAULT_SERIAL_DEVICE "/dev/ttyS1"
|
||||
#define DEFAULT_SERIAL_SPEED "115200,8N1"
|
||||
#define DEFAULT_CHANNEL_IP "10.0.2.179"
|
||||
#define SERIAL_MAGIC 0x61626261 /* endian doesn't matter */
|
||||
|
||||
typedef struct __attribute__((packed)) _serial_fence_req {
|
||||
|
@ -27,7 +27,7 @@ machines from scripts.
|
||||
.TP
|
||||
.B -d
|
||||
.
|
||||
Specify (CCS) / increment (command line) debug level
|
||||
Increment (command line) debug level
|
||||
|
||||
.TP
|
||||
.B -H
|
||||
@ -37,12 +37,12 @@ Virtual machine (domain name) to fence
|
||||
.TP
|
||||
.B -o
|
||||
.
|
||||
Fencing action (null, off, on, [reboot], status, devstatus, or hostlist) (Default Value: reboot)
|
||||
Fencing action (null, off, on, reboot, status, devstatus, or hostlist) (Default Value: reboot)
|
||||
|
||||
.TP
|
||||
.B -t
|
||||
.
|
||||
Fencing timeout (in seconds; default=30) (Default Value: 30)
|
||||
Fencing timeout (in seconds) (Default Value: 30)
|
||||
|
||||
.SH MULTICAST PARAMETERS
|
||||
These parameters are used only when using fence_virt in multicast mode
|
||||
@ -51,37 +51,37 @@ These parameters are used only when using fence_virt in multicast mode
|
||||
.TP
|
||||
.B -i
|
||||
.
|
||||
IP Family ([auto], ipv4, ipv6) (Default Value: auto)
|
||||
IP Family (auto, ipv4, ipv6) (Default Value: auto)
|
||||
|
||||
.TP
|
||||
.B -a
|
||||
.
|
||||
Multicast address (default=225.0.0.12 / ff02::3:1)
|
||||
Multicast address (Default Values: 225.0.0.12 / ff02::3:1)
|
||||
|
||||
.TP
|
||||
.B -p
|
||||
.
|
||||
IP port (default=1229) (Default Value: 1229)
|
||||
IP port (Default Value: 1229)
|
||||
|
||||
.TP
|
||||
.B -T
|
||||
.
|
||||
Multicast time-to-live (in hops; default=2) (Default Value: 2)
|
||||
Multicast time-to-live (in hops) (Default Value: 2)
|
||||
|
||||
.TP
|
||||
.B -r
|
||||
.
|
||||
Multicast retransmit time (in 1/10sec; default=20) (Default Value: 20)
|
||||
Multicast retransmit time (in 1/10sec) (Default Value: 20)
|
||||
|
||||
.TP
|
||||
.B -C
|
||||
.
|
||||
Authentication (none, sha1, [sha256], sha512) (Default Value: sha256)
|
||||
Authentication (none, sha1, sha256, sha512) (Default Value: sha256)
|
||||
|
||||
.TP
|
||||
.B -c
|
||||
.
|
||||
Packet hash strength (none, sha1, [sha256], sha512) (Default Value: sha256)
|
||||
Packet hash strength (none, sha1, sha256, sha512) (Default Value: sha256)
|
||||
|
||||
.TP
|
||||
.B -k
|
||||
@ -93,21 +93,31 @@ Shared key file (Default Value: /etc/cluster/fence_xvm.key)
|
||||
.
|
||||
Treat 'domain' as UUID instead of domain name.
|
||||
|
||||
.SH MULTICAST PARAMETERS
|
||||
.SH SERIAL/VMCHANNEL PARAMETERS
|
||||
These parameters are used only when using fence_virt in multicast mode
|
||||
(e.g. by running fence_xvm).
|
||||
|
||||
.TP
|
||||
.B -D
|
||||
.
|
||||
Serial device (fence_virt mode). Default=/dev/ttyS1. On the host, the
|
||||
serial device must be mapped in each domain's configuration file. See
|
||||
fence_virt.conf(5) for more information.
|
||||
Serial device (fence_virt mode). On the host, the serial device must
|
||||
be mapped in each domain's configuration file. See fence_virt.conf(5)
|
||||
for more information. Specifying a serial device causes fence_virt
|
||||
to use serial mode (as opposed to VMChannel mode).
|
||||
|
||||
.TP
|
||||
.B -P
|
||||
.
|
||||
Serial parameters. Default=115200,8N1
|
||||
Serial parameters. (Default Value: 115200,8N1)
|
||||
|
||||
.TP
|
||||
.B -A
|
||||
VMChannel IP address (Default Value: 10.0.2.179)
|
||||
|
||||
.TP
|
||||
.B -p
|
||||
.
|
||||
VMChannel IP port (Default Value: 1229)
|
||||
|
||||
.SH GENERAL STDIN PARAMETERS
|
||||
These parameters are passed to fence_virt via standard input if
|
||||
@ -134,7 +144,7 @@ Fencing action to perform (See FENCING ACTIONS section)
|
||||
.TP
|
||||
.B timeout
|
||||
.
|
||||
Fencing timeout (in seconds; default=30) (Default Value: 30)
|
||||
Fencing timeout (in seconds) (Default Value: 30)
|
||||
|
||||
.SH MULTICAST STDIN PARAMETERS
|
||||
.TP
|
||||
@ -145,56 +155,69 @@ IP Family ([auto], ipv4, ipv6) (Default Value: auto)
|
||||
.TP
|
||||
.B multicast_address
|
||||
.
|
||||
Multicast address (default=225.0.0.12 / ff02::3:1)
|
||||
Multicast address (Defaults: 225.0.0.12 / ff02::3:1)
|
||||
|
||||
.TP
|
||||
.B port
|
||||
.
|
||||
IP port (default=1229) (Default Value: 1229)
|
||||
IP port (Default Value: 1229)
|
||||
|
||||
.TP
|
||||
.B multicast_ttl
|
||||
.
|
||||
Multicast time-to-live (in hops; default=2) (Default Value: 2)
|
||||
Multicast time-to-live (in hops) (Default Value: 2)
|
||||
|
||||
.TP
|
||||
.B retrans
|
||||
.
|
||||
Multicast retransmit time (in 1/10sec; default=20) (Default Value: 20)
|
||||
Multicast retransmit time (in 1/10sec) (Default Value: 20)
|
||||
|
||||
.TP
|
||||
.B auth
|
||||
.
|
||||
Authentication (none, sha1, [sha256], sha512) (Default Value: sha256)
|
||||
Authentication (none, sha1, sha256, sha512) (Default Value: sha256)
|
||||
|
||||
.TP
|
||||
.B hash
|
||||
.
|
||||
Packet hash strength (none, sha1, [sha256], sha512) (Default Value: sha256)
|
||||
Packet hash strength (none, sha1, sha256, sha512) (Default Value: sha256)
|
||||
|
||||
.TP
|
||||
.B key_file
|
||||
.
|
||||
Shared key file (default=/etc/cluster/fence_xvm.key) (Default Value: /etc/cluster/fence_xvm.key)
|
||||
Shared key file (Default Value: /etc/cluster/fence_xvm.key)
|
||||
|
||||
.TP
|
||||
.B use_uuid
|
||||
.
|
||||
Treat 'domain' as UUID instead of domain name
|
||||
|
||||
.SH SERIAL STDIN PARAMETERS
|
||||
.SH SERIAL/VMCHANNEL STDIN PARAMETERS
|
||||
.TP
|
||||
.B serial_device
|
||||
.
|
||||
Serial device. Default=/dev/ttyS1. On the host, the serial device must
|
||||
be mapped in each domain's configuration file. See fence_virt.conf(5)
|
||||
for more information.
|
||||
Serial device. On the host, the serial device must be mapped in
|
||||
each domain's configuration file. See fence_virt.conf(5)
|
||||
for more information. If specified, causes fence_virt to operate
|
||||
in serial mode (not specifying causes fence_virt to operate in
|
||||
VM Channel mode).
|
||||
|
||||
.TP
|
||||
.B serial_params
|
||||
.
|
||||
Serial parameters. Default=115200,8N1.
|
||||
|
||||
.TP
|
||||
.B channel_ip
|
||||
.
|
||||
Channel IP. Default=10.0.2.179
|
||||
|
||||
.TP
|
||||
.B port
|
||||
.
|
||||
Channel port. Default=1229
|
||||
|
||||
|
||||
.SH FENCING ACTIONS
|
||||
|
||||
.TP
|
||||
|
@ -73,10 +73,6 @@ There are various listeners available for fence_virtd, each one handles
|
||||
decoding and authentication of a given fencing request. The following
|
||||
configuration blocks belong in the \fBlisteners\fP section of fence_virtd.conf
|
||||
|
||||
.SS vmchannel
|
||||
To be done. This listener utilizes serial vmchannel tied to Unix domain
|
||||
sockets on the host in order to receive and route fencing requests.
|
||||
|
||||
.SS multicast
|
||||
.TP
|
||||
.B key_file
|
||||
@ -119,23 +115,25 @@ is used as a gateway.
|
||||
|
||||
.SS serial
|
||||
|
||||
The serial listener plugin utilizes libvirt's serial mapping to listen
|
||||
for requests. When using the serial listener, it is necessary to add
|
||||
a serial port (preferably pointing to /dev/ttyS1) in the libvirt domain
|
||||
description. Note that only serial type
|
||||
The serial listener plugin utilizes libvirt's serial (or VMChannel)
|
||||
mapping to listen for requests. When using the serial listener, it is
|
||||
necessary to add a serial port (preferably pointing to /dev/ttyS1) or
|
||||
a channel (preferrably pointing to 10.0.2.179:1229) to the
|
||||
libvirt domain description. Note that only type
|
||||
.B unix
|
||||
, mode
|
||||
.B bind
|
||||
is supported. The socket path does not matter, and currently, fence_virt
|
||||
will only use the
|
||||
.B first specified
|
||||
virtual serial port of this type. Example libvirt XML:
|
||||
serial ports and channels are supported. Example libvirt XML:
|
||||
|
||||
.in 8
|
||||
<serial type='unix'>
|
||||
<\fBserial\fP type='unix'>
|
||||
<source mode='bind' path='/sandbox/guests/fence_socket_molly'/>
|
||||
<target port='1'/>
|
||||
</serial>
|
||||
<\fBchannel\fP type='unix'>
|
||||
<source mode='bind' path='/sandbox/guests/fence_molly_vmchannel'/>
|
||||
<target type='guestfwd' address='10.0.2.179' port='1229'/>
|
||||
</serial>
|
||||
.in 0
|
||||
|
||||
.TP
|
||||
@ -143,6 +141,19 @@ virtual serial port of this type. Example libvirt XML:
|
||||
.
|
||||
the URI to use when connecting to libvirt by the serial plugin.
|
||||
|
||||
.TP
|
||||
.B path
|
||||
.
|
||||
Sockets must reside in this directory in order to be considered
|
||||
valid. This can be used to prevent fence_virtd from using the wrong
|
||||
sockets.
|
||||
|
||||
.TP
|
||||
.B mode
|
||||
.
|
||||
This selects the type of sockets to register. Valid values are "serial"
|
||||
(default) and "vmchannel".
|
||||
|
||||
|
||||
.SH BACKENDS
|
||||
|
||||
|
@ -71,8 +71,10 @@ typedef struct _serial_info {
|
||||
const fence_callbacks_t *cb;
|
||||
void *priv;
|
||||
char *uri;
|
||||
char *path;
|
||||
history_info_t *history;
|
||||
void *maps;
|
||||
int mode;
|
||||
} serial_info;
|
||||
|
||||
|
||||
@ -260,12 +262,16 @@ serial_dispatch(listener_context_t c, struct timeval *timeout)
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
printf("max = %d\n", max);
|
||||
|
||||
/* find & read request */
|
||||
for (x = 0; x <= max; x++) {
|
||||
if (FD_ISSET(x, &rfds)) {
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
printf("Reading from %d\n", x);
|
||||
|
||||
ret = _read_retry(x, &data, sizeof(data), &tv);
|
||||
|
||||
if (ret != sizeof(data)) {
|
||||
@ -314,6 +320,29 @@ serial_config(config_object_t *config, serial_info *args)
|
||||
args->uri = strdup(value);
|
||||
}
|
||||
|
||||
if (sc_get(config, "listeners/serial/@path",
|
||||
value, sizeof(value)-1) == 0) {
|
||||
dbg_printf(1, "Got %s for uri\n", value);
|
||||
args->path = strdup(value);
|
||||
}
|
||||
|
||||
if (sc_get(config, "listeners/serial/@mode",
|
||||
value, sizeof(value)-1) == 0) {
|
||||
if (!strcasecmp(value, "vmchannel")) {
|
||||
args->mode = 1;
|
||||
} else if (!strcasecmp(value, "serial")) {
|
||||
args->mode = 0;
|
||||
} else {
|
||||
args->mode = atoi(value);
|
||||
if (args->mode < 0)
|
||||
args->mode = 0;
|
||||
}
|
||||
|
||||
dbg_printf(1, "Got %s for mode\n",
|
||||
args->mode?"VMChannel":"serial");
|
||||
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
@ -347,7 +376,7 @@ serial_init(listener_context_t *c, const fence_callbacks_t *cb,
|
||||
info->magic = SERIAL_PLUG_MAGIC;
|
||||
info->history = history_init(check_history, 10, sizeof(fence_req_t));
|
||||
*c = (listener_context_t)info;
|
||||
start_event_listener(info->uri);
|
||||
start_event_listener(info->uri, info->path, info->mode);
|
||||
sleep(1);
|
||||
|
||||
return 0;
|
||||
@ -366,6 +395,7 @@ serial_shutdown(listener_context_t c)
|
||||
stop_event_listener();
|
||||
domain_sock_cleanup();
|
||||
free(info->uri);
|
||||
free(info->path);
|
||||
free(info);
|
||||
|
||||
return 0;
|
||||
|
@ -18,7 +18,7 @@ int static_map_check(void *info, const char *value1, const char *value2);
|
||||
int static_map_init(config_object_t *config, void **perm_info);
|
||||
|
||||
/* virt-serial.c - event thread control functions */
|
||||
int start_event_listener(const char *uri);
|
||||
int start_event_listener(const char *uri, const char *path, int mode);
|
||||
int stop_event_listener(void);
|
||||
|
||||
|
||||
|
@ -185,13 +185,14 @@ myEventRemoveTimeoutFunc(int timer)
|
||||
|
||||
|
||||
static int
|
||||
domainStarted(virDomainPtr mojaDomain)
|
||||
domainStarted(virDomainPtr mojaDomain, const char *path, int mode)
|
||||
{
|
||||
char dom_uuid[42];
|
||||
char *xml;
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr cur, devices, child, serial;
|
||||
xmlAttrPtr attr, attr_mode, attr_path;
|
||||
size_t path_len = 0;
|
||||
|
||||
if (!mojaDomain)
|
||||
return -1;
|
||||
@ -200,6 +201,8 @@ domainStarted(virDomainPtr mojaDomain)
|
||||
|
||||
xml = virDomainGetXMLDesc(mojaDomain, 0);
|
||||
// printf("%s\n", xml);
|
||||
if (path)
|
||||
path_len = strlen(path);
|
||||
|
||||
// @todo: free mojaDomain
|
||||
|
||||
@ -229,7 +232,9 @@ domainStarted(virDomainPtr mojaDomain)
|
||||
|
||||
for (child = devices->xmlChildrenNode; child != NULL;
|
||||
child = child->next) {
|
||||
if (xmlStrcmp(child->name, (const xmlChar *) "serial")) {
|
||||
|
||||
if ((!mode && xmlStrcmp(child->name, (const xmlChar *) "serial")) ||
|
||||
(mode && xmlStrcmp(child->name, (const xmlChar *) "channel"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -252,23 +257,35 @@ domainStarted(virDomainPtr mojaDomain)
|
||||
attr_mode = xmlHasProp(serial, (const xmlChar *)"mode");
|
||||
attr_path = xmlHasProp(serial, (const xmlChar *)"path");
|
||||
|
||||
if ((attr_path != NULL) &&
|
||||
(attr_mode != NULL) &&
|
||||
(!xmlStrcmp(attr_mode->children->content,
|
||||
(const xmlChar *) "bind"))) {
|
||||
if (!attr_path || !attr_mode)
|
||||
continue;
|
||||
|
||||
if (xmlStrcmp(attr_mode->children->content,
|
||||
(const xmlChar *) "bind"))
|
||||
continue;
|
||||
|
||||
if (path) {
|
||||
if (xmlStrlen(attr_path->children->content) <
|
||||
path_len)
|
||||
continue;
|
||||
if (strncmp(attr_path->children->content,
|
||||
path, path_len))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
domain_sock_setup(dom_uuid, (const char *)
|
||||
attr_path->children->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
registerExisting(virConnectPtr vp)
|
||||
registerExisting(virConnectPtr vp, const char *path, int mode)
|
||||
{
|
||||
int *d_ids = NULL;
|
||||
int d_count, x;
|
||||
@ -312,7 +329,7 @@ registerExisting(virConnectPtr vp)
|
||||
|
||||
if (d_info.state != VIR_DOMAIN_SHUTOFF &&
|
||||
d_info.state != VIR_DOMAIN_CRASHED)
|
||||
domainStarted(dom);
|
||||
domainStarted(dom, path, mode);
|
||||
|
||||
virDomainFree(dom);
|
||||
}
|
||||
@ -337,15 +354,28 @@ domainStopped(virDomainPtr mojaDomain)
|
||||
}
|
||||
|
||||
|
||||
struct event_args {
|
||||
char *uri;
|
||||
char *path;
|
||||
int mode;
|
||||
};
|
||||
|
||||
|
||||
static void *
|
||||
event_thread(void *arg)
|
||||
{
|
||||
struct event_args *args = (struct event_args *)arg;
|
||||
virConnectPtr dconn = NULL;
|
||||
struct domain_info dinfo;
|
||||
int sts;
|
||||
int callback1ret = -1;
|
||||
int sts;
|
||||
|
||||
dbg_printf(3,"Event listener starting \n");
|
||||
dbg_printf(3, "Libvirt event listener starting\n");
|
||||
if (args->uri)
|
||||
dbg_printf(3," * URI: %s\n", args->uri);
|
||||
if (args->path)
|
||||
dbg_printf(3," * Socket path: %s\n", args->path);
|
||||
dbg_printf(3," * Mode: %s\n", args->mode?"VMChannel":"Serial");
|
||||
|
||||
virEventRegisterImpl(myEventAddHandleFunc,
|
||||
myEventUpdateHandleFunc,
|
||||
@ -354,15 +384,15 @@ event_thread(void *arg)
|
||||
myEventUpdateTimeoutFunc,
|
||||
myEventRemoveTimeoutFunc);
|
||||
|
||||
dconn = virConnectOpen((char *)arg);
|
||||
dconn = virConnectOpen(args->uri);
|
||||
if (!dconn) {
|
||||
dbg_printf(1, "Error connecting to libvirt\n");
|
||||
return NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUG0("Registering domain event cbs");
|
||||
|
||||
registerExisting(dconn);
|
||||
registerExisting(dconn, args->path, args->mode);
|
||||
|
||||
/* Add 2 callbacks to prove this works with more than just one */
|
||||
memset(&dinfo, 0, sizeof (dinfo));
|
||||
@ -385,7 +415,7 @@ event_thread(void *arg)
|
||||
}
|
||||
|
||||
if (dinfo.event == VIR_DOMAIN_EVENT_STARTED) {
|
||||
domainStarted(dinfo.dom);
|
||||
domainStarted(dinfo.dom, args->path, args->mode);
|
||||
virDomainFree(dinfo.dom);
|
||||
dinfo.dom = NULL;
|
||||
dinfo.event = VIR_DOMAIN_EVENT_UNDEFINED;
|
||||
@ -408,7 +438,7 @@ event_thread(void *arg)
|
||||
|
||||
if (pfd.revents & POLLHUP) {
|
||||
DEBUG0("Reset by peer");
|
||||
return NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (h_cb) {
|
||||
@ -428,26 +458,48 @@ event_thread(void *arg)
|
||||
dbg_printf(1, "error closing libvirt connection\n");
|
||||
}
|
||||
|
||||
out:
|
||||
free(args->uri);
|
||||
free(args->path);
|
||||
free(args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
start_event_listener(const char *uri)
|
||||
start_event_listener(const char *uri, const char *path, int mode)
|
||||
{
|
||||
char *arg = NULL;
|
||||
struct event_args *args = NULL;
|
||||
|
||||
virInitialize();
|
||||
|
||||
if (uri) {
|
||||
arg = strdup(uri);
|
||||
if (uri == NULL)
|
||||
args = malloc(sizeof(*args));
|
||||
if (!args)
|
||||
return -1;
|
||||
memset(args, 0, sizeof(*args));
|
||||
|
||||
if (uri) {
|
||||
args->uri = strdup(uri);
|
||||
if (args->uri == NULL)
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (path) {
|
||||
args->path = strdup(path);
|
||||
if (args->path == NULL)
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
args->mode = mode;
|
||||
run = 1;
|
||||
|
||||
return pthread_create(&event_tid, NULL, event_thread, arg);
|
||||
return pthread_create(&event_tid, NULL, event_thread, args);
|
||||
|
||||
out_fail:
|
||||
free(args->uri);
|
||||
free(args->path);
|
||||
free(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user