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