Drop fence_xvm from upstream and other cleanups
This commit is contained in:
parent
efe8d539b8
commit
346181a94e
@ -10,25 +10,24 @@
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
|
||||
# main (empty) package
|
||||
# http://www.rpm.org/max-rpm/s1-rpm-subpack-spec-file-changes.html
|
||||
|
||||
# keep around ready for later user
|
||||
## define alphatag rc4
|
||||
%global alphatag git0a6184070
|
||||
|
||||
Name: fence-agents
|
||||
Summary: Fence Agents for Red Hat Cluster
|
||||
Version: 3.0.5
|
||||
Release: 1%{?alphatag:.%{alphatag}}%{?dist}
|
||||
Release: 2%{?alphatag:.%{alphatag}}%{?dist}
|
||||
License: GPLv2+ and LGPLv2+
|
||||
Group: System Environment/Base
|
||||
URL: http://sources.redhat.com/cluster/wiki/
|
||||
Source0: ftp://sources.redhat.com/pub/cluster/releases/fence-agents-%{version}%{?alphatag:.%{alphatag}}.tar.gz
|
||||
Source0: ftp://sources.redhat.com/pub/cluster/releases/fence-agents-%{version}.tar.gz
|
||||
Patch0: fence_head.diff
|
||||
|
||||
## Runtime deps
|
||||
Requires: sg3_utils OpenIPMI telnet openssh-clients
|
||||
Requires: pexpect net-snmp-utils
|
||||
Requires: perl-Net-Telnet
|
||||
Requires: fence-virt >= 0.1.3-1
|
||||
|
||||
# This is required by fence_virsh. Per discussion on fedora-devel
|
||||
# switching from package to file based require.
|
||||
@ -49,7 +48,8 @@ BuildRequires: corosynclib-devel >= 1.0.0-1
|
||||
BuildRequires: openaislib-devel >= 1.0.0-1
|
||||
|
||||
%prep
|
||||
%setup -q -n fence-agents-%{version}%{?alphatag:.%{alphatag}}
|
||||
%setup -q -n fence-agents-%{version}
|
||||
%patch0 -p1
|
||||
|
||||
# we inherit configure from cluster project. Configure it for vars we need.
|
||||
# building from source directly without those parameters will NOT work.
|
||||
@ -89,6 +89,13 @@ power management for several devices.
|
||||
%{_mandir}/man8/fence*
|
||||
|
||||
%changelog
|
||||
* Fri Dec 4 2009 Fabio M. Di Nitto <fdinitto@redhat.com> - 3.0.5-2.git0a6184070
|
||||
- Drop fence_xvm from upstream (fence_head.diff)
|
||||
- spec file updates:
|
||||
* Drop unrequired comments
|
||||
* Readd alpha tag and clean it's usage around
|
||||
* Requires: fence-virt in sufficient version to provide fence_xvm
|
||||
|
||||
* Fri Nov 20 2009 Fabio M. Di Nitto <fdinitto@redhat.com> - 3.0.5-1
|
||||
- New upstream release
|
||||
|
||||
|
804
fence_head.diff
Normal file
804
fence_head.diff
Normal file
@ -0,0 +1,804 @@
|
||||
--- a/fence/agents/xvm/Makefile
|
||||
+++ b/fence/agents/xvm/Makefile
|
||||
@@ -1,12 +1,9 @@
|
||||
-TARGET1= fence_xvm
|
||||
-TARGET2= fence_xvmd
|
||||
-TARGET3= testprog
|
||||
+TARGET1= fence_xvmd
|
||||
+TARGET2= testprog
|
||||
|
||||
-SBINDIRT=$(TARGET1) $(TARGET2)
|
||||
+SBINDIRT=$(TARGET1)
|
||||
|
||||
-MANTARGET= fence_xvm.8
|
||||
-
|
||||
-all: ${TARGET1} ${TARGET2} ${MANTARGET}
|
||||
+all: ${TARGET1}
|
||||
|
||||
include ../../../make/defines.mk
|
||||
include $(OBJDIR)/make/cobj.mk
|
||||
@@ -14,22 +11,19 @@ include $(OBJDIR)/make/clean.mk
|
||||
include $(OBJDIR)/make/install.mk
|
||||
include $(OBJDIR)/make/uninstall.mk
|
||||
|
||||
-OBJS1= fence_xvm.o \
|
||||
- ip_lookup.o
|
||||
-
|
||||
-OBJS2= fence_xvmd.o \
|
||||
+OBJS1= fence_xvmd.o \
|
||||
virt.o \
|
||||
options-ccs.o \
|
||||
vm_states.o \
|
||||
- xml.o
|
||||
+ xml.o \
|
||||
+ mcast.o \
|
||||
+ simple_auth.o \
|
||||
+ tcp.o \
|
||||
+ options.o \
|
||||
+ debug.o
|
||||
|
||||
-OBJS3= xml-standalone.o
|
||||
|
||||
-SHAREDOBJS= mcast.o \
|
||||
- simple_auth.o \
|
||||
- tcp.o \
|
||||
- options.o \
|
||||
- debug.o
|
||||
+OBJS2= xml-standalone.o
|
||||
|
||||
CFLAGS += -D_GNU_SOURCE
|
||||
CFLAGS += -I${ccsincdir} -I${cmanincdir}
|
||||
@@ -44,30 +38,19 @@ STANDALONE_CFLAGS += -DSTANDALONE
|
||||
LDFLAGS += -L${nsslibdir} -lnss3
|
||||
LDFLAGS += -L${logtlibdir} -llogthread
|
||||
LDFLAGS += -L${libdir}
|
||||
+LDFLAGS += -L${ccslibdir} -lccs -L${cmanlibdir} -lcman
|
||||
+LDFLAGS += -L${virtlibdir} -lvirt
|
||||
+LDFLAGS += -L${openaislibdir} -lSaCkpt
|
||||
|
||||
-EXTRA_LDFLAGS += -L${ccslibdir} -lccs -L${cmanlibdir} -lcman
|
||||
-EXTRA_LDFLAGS += -L${virtlibdir} -lvirt
|
||||
-EXTRA_LDFLAGS += -L${openaislibdir} -lSaCkpt
|
||||
XML_LDFLAGS += `xml2-config --libs`
|
||||
|
||||
${TARGET1}: ${SHAREDOBJS} ${OBJS1}
|
||||
- $(CC) -o $@ $^ $(LDFLAGS)
|
||||
+ $(CC) -o $@ $^ $(XML_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
-${TARGET2}: ${SHAREDOBJS} ${OBJS2}
|
||||
- $(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(XML_LDFLAGS) $(LDFLAGS)
|
||||
-
|
||||
-${TARGET3}: ${OBJS3}
|
||||
+${TARGET2}: ${OBJS2}
|
||||
$(CC) -o $@ $^ $(XML_LDFLAGS)
|
||||
|
||||
-$(MANTARGET): $(TARGET1) ${SRCDIR}/fence/agents/lib/fence2man.xsl
|
||||
- set -e && \
|
||||
- LD_LIBRARY_PATH=${logtlibdir} ./$(TARGET1) -o metadata > .$@.tmp && \
|
||||
- xsltproc ${SRCDIR}/fence/agents/lib/fence2man.xsl .$@.tmp > $@
|
||||
-
|
||||
clean: generalclean
|
||||
- rm -f $(MANTARGET) .$(MANTARGET).tmp
|
||||
|
||||
-include $(OBJS1:.o=.d)
|
||||
-include $(OBJS2:.o=.d)
|
||||
--include $(OBJS3:.o=.d)
|
||||
--include $(SHAREDOBJS:.o=.d)
|
||||
--- a/fence/agents/xvm/fence_xvm.c
|
||||
+++ /dev/null
|
||||
@@ -1,380 +0,0 @@
|
||||
-/*
|
||||
- * @file fence_xvmd.c: Implementation of server daemon for Xen virtual
|
||||
- * machine fencing. This uses SA AIS CKPT b.1.0 checkpointing API to
|
||||
- * store virtual machine states.
|
||||
- *
|
||||
- * Author: Lon Hohberger <lhh at redhat.com>
|
||||
- */
|
||||
-#include <stdio.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <unistd.h>
|
||||
-#include <signal.h>
|
||||
-#include <sys/types.h>
|
||||
-#include <sys/stat.h>
|
||||
-#include <sys/wait.h>
|
||||
-#include <sys/un.h>
|
||||
-#include <sys/socket.h>
|
||||
-#include <sys/select.h>
|
||||
-#include <sys/ioctl.h>
|
||||
-#include <arpa/inet.h>
|
||||
-#include <net/if.h>
|
||||
-#include <netinet/in.h>
|
||||
-#include <netdb.h>
|
||||
-#include <sys/time.h>
|
||||
-#include <fcntl.h>
|
||||
-#include <errno.h>
|
||||
-#include <pthread.h>
|
||||
-#include <libgen.h>
|
||||
-#include <nss.h>
|
||||
-#include <liblogthread.h>
|
||||
-
|
||||
-/* Local includes */
|
||||
-#include "xvm.h"
|
||||
-#include "ip_lookup.h"
|
||||
-#include "simple_auth.h"
|
||||
-#include "options.h"
|
||||
-#include "tcp.h"
|
||||
-#include "mcast.h"
|
||||
-#include "debug.h"
|
||||
-
|
||||
-#define LOG_DAEMON_NAME "fence_xvm"
|
||||
-
|
||||
-static int
|
||||
-tcp_wait_connect(int lfd, int retry_tenths)
|
||||
-{
|
||||
- int fd;
|
||||
- fd_set rfds;
|
||||
- int n;
|
||||
- struct timeval tv;
|
||||
-
|
||||
- dbg_printf(3, "Waiting for connection from XVM host daemon.\n");
|
||||
- FD_ZERO(&rfds);
|
||||
- FD_SET(lfd, &rfds);
|
||||
- tv.tv_sec = retry_tenths / 10;
|
||||
- tv.tv_usec = (retry_tenths % 10) * 100000;
|
||||
-
|
||||
- n = select(lfd + 1, &rfds, NULL, NULL, &tv);
|
||||
- if (n == 0) {
|
||||
- errno = ETIMEDOUT;
|
||||
- return -1;
|
||||
- } else if (n < 0) {
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- fd = accept(lfd, NULL, 0);
|
||||
- if (fd < 0)
|
||||
- return -1;
|
||||
-
|
||||
- return fd;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static int
|
||||
-tcp_exchange(int fd, fence_auth_type_t auth, void *key,
|
||||
- size_t key_len, int timeout)
|
||||
-{
|
||||
- char ret;
|
||||
- fd_set rfds;
|
||||
- struct timeval tv;
|
||||
-
|
||||
- /* Ok, we're connected */
|
||||
- dbg_printf(3, "Issuing TCP challenge\n");
|
||||
- if (tcp_challenge(fd, auth, key, key_len, timeout) <= 0) {
|
||||
- /* Challenge failed */
|
||||
- logt_print(LOG_ERR, "Invalid response to challenge\n");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- /* Now they'll send us one, so we need to respond here */
|
||||
- dbg_printf(3, "Responding to TCP challenge\n");
|
||||
- if (tcp_response(fd, auth, key, key_len, timeout) <= 0) {
|
||||
- logt_print(LOG_ERR, "Invalid response to challenge\n");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- dbg_printf(2, "TCP Exchange + Authentication done... \n");
|
||||
-
|
||||
- FD_ZERO(&rfds);
|
||||
- FD_SET(fd, &rfds);
|
||||
- tv.tv_sec = timeout;
|
||||
- tv.tv_usec = 0;
|
||||
-
|
||||
- ret = 1;
|
||||
- dbg_printf(3, "Waiting for return value from XVM host\n");
|
||||
- if (select(fd + 1, &rfds, NULL, NULL, &tv) <= 0)
|
||||
- return -1;
|
||||
-
|
||||
- /* Read return code */
|
||||
- if (read(fd, &ret, 1) < 0)
|
||||
- return -1;
|
||||
-
|
||||
- close(fd);
|
||||
- if (ret == 0)
|
||||
- logt_print(LOG_INFO, "Remote: Operation was successful\n");
|
||||
- else
|
||||
- logt_print(LOG_INFO, "Remote: Operation failed\n");
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static int
|
||||
-send_multicast_packets(ip_list_t *ipl, fence_xvm_args_t *args, void *key,
|
||||
- size_t key_len)
|
||||
-{
|
||||
- fence_req_t freq;
|
||||
- int mc_sock;
|
||||
- ip_addr_t *ipa;
|
||||
- struct sockaddr_in tgt4;
|
||||
- struct sockaddr_in6 tgt6;
|
||||
- struct sockaddr *tgt;
|
||||
- socklen_t tgt_len;
|
||||
-
|
||||
- for (ipa = ipl->tqh_first; ipa; ipa = ipa->ipa_entries.tqe_next) {
|
||||
-
|
||||
- if (ipa->ipa_family != args->family) {
|
||||
- dbg_printf(2, "Ignoring %s: wrong family\n", ipa->ipa_address);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (args->family == PF_INET) {
|
||||
- mc_sock = ipv4_send_sk(ipa->ipa_address, args->addr,
|
||||
- args->port,
|
||||
- (struct sockaddr *)&tgt4,
|
||||
- sizeof(struct sockaddr_in),
|
||||
- args->ttl);
|
||||
- tgt = (struct sockaddr *)&tgt4;
|
||||
- tgt_len = sizeof(tgt4);
|
||||
-
|
||||
- } else if (args->family == PF_INET6) {
|
||||
- mc_sock = ipv6_send_sk(ipa->ipa_address, args->addr,
|
||||
- args->port,
|
||||
- (struct sockaddr *)&tgt6,
|
||||
- sizeof(struct sockaddr_in6),
|
||||
- args->ttl);
|
||||
- tgt = (struct sockaddr *)&tgt6;
|
||||
- tgt_len = sizeof(tgt6);
|
||||
- } else {
|
||||
- dbg_printf(2, "Unsupported family %d\n", args->family);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (mc_sock < 0)
|
||||
- continue;
|
||||
-
|
||||
- /* Build our packet */
|
||||
- memset(&freq, 0, sizeof(freq));
|
||||
- strncpy((char *)freq.domain, args->domain,
|
||||
- sizeof(freq.domain));
|
||||
- freq.request = args->op;
|
||||
- freq.hashtype = args->hash;
|
||||
-
|
||||
- /* Store source address */
|
||||
- if (ipa->ipa_family == PF_INET) {
|
||||
- freq.addrlen = sizeof(struct in_addr);
|
||||
- /* XXX Swap order for in_addr ? XXX */
|
||||
- inet_pton(PF_INET, ipa->ipa_address, freq.address);
|
||||
- } else if (ipa->ipa_family == PF_INET6) {
|
||||
- freq.addrlen = sizeof(struct in6_addr);
|
||||
- inet_pton(PF_INET6, ipa->ipa_address, freq.address);
|
||||
- }
|
||||
-
|
||||
- freq.flags = 0;
|
||||
- if (args->flags & F_USE_UUID)
|
||||
- freq.flags |= RF_UUID;
|
||||
- freq.family = ipa->ipa_family;
|
||||
- freq.port = args->port;
|
||||
-
|
||||
- sign_request(&freq, key, key_len);
|
||||
-
|
||||
- dbg_printf(3, "Sending to %s via %s\n", args->addr,
|
||||
- ipa->ipa_address);
|
||||
-
|
||||
- sendto(mc_sock, &freq, sizeof(freq), 0,
|
||||
- (struct sockaddr *)tgt, tgt_len);
|
||||
-
|
||||
- close(mc_sock);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* TODO: Clean this up!!! */
|
||||
-static int
|
||||
-fence_xen_domain(fence_xvm_args_t *args)
|
||||
-{
|
||||
- ip_list_t ipl;
|
||||
- char key[MAX_KEY_LEN];
|
||||
- int lfd, key_len = 0, fd;
|
||||
- int attempts = 0;
|
||||
-
|
||||
- if (args->auth != AUTH_NONE || args->hash != HASH_NONE) {
|
||||
- key_len = read_key_file(args->key_file, key, sizeof(key));
|
||||
- if (key_len < 0) {
|
||||
- logt_print(LOG_INFO,
|
||||
- "Could not read %s; trying without "
|
||||
- "authentication\n", args->key_file);
|
||||
- args->auth = AUTH_NONE;
|
||||
- args->hash = HASH_NONE;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Do the real work */
|
||||
- if (ip_build_list(&ipl) < 0) {
|
||||
- logt_print(LOG_ERR, "Error building IP address list\n");
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- switch (args->auth) {
|
||||
- case AUTH_NONE:
|
||||
- case AUTH_SHA1:
|
||||
- case AUTH_SHA256:
|
||||
- case AUTH_SHA512:
|
||||
- if (args->family == PF_INET) {
|
||||
- lfd = ipv4_listen(args->port, 10);
|
||||
- } else {
|
||||
- lfd = ipv6_listen(args->port, 10);
|
||||
- }
|
||||
- break;
|
||||
- /*case AUTH_X509:*/
|
||||
- /* XXX Setup SSL listener socket here */
|
||||
- default:
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- if (lfd < 0) {
|
||||
- logt_print(LOG_ERR, "Failed to listen: %s\n", strerror(errno));
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- attempts = args->timeout * 10 / args->retr_time;
|
||||
-
|
||||
- logt_print(LOG_INFO, "Sending fence request for %s\n",
|
||||
- args->domain);
|
||||
-
|
||||
- do {
|
||||
- if (send_multicast_packets(&ipl, args, key, key_len)) {
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- switch (args->auth) {
|
||||
- case AUTH_NONE:
|
||||
- case AUTH_SHA1:
|
||||
- case AUTH_SHA256:
|
||||
- case AUTH_SHA512:
|
||||
- fd = tcp_wait_connect(lfd, args->retr_time);
|
||||
- if (fd < 0 && (errno == ETIMEDOUT ||
|
||||
- errno == EINTR))
|
||||
- continue;
|
||||
- break;
|
||||
- /* case AUTH_X509:
|
||||
- ... = ssl_wait_connect... */
|
||||
- break;
|
||||
- default:
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- break;
|
||||
- } while (--attempts);
|
||||
-
|
||||
- if (fd < 0) {
|
||||
- if (attempts <= 0) {
|
||||
- logt_print(LOG_ERR,
|
||||
- "Timed out waiting for response\n");
|
||||
- return 1;
|
||||
- }
|
||||
- logt_print(LOG_ERR, "Fencing failed: %s\n", strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- switch (args->auth) {
|
||||
- case AUTH_NONE:
|
||||
- case AUTH_SHA1:
|
||||
- case AUTH_SHA256:
|
||||
- case AUTH_SHA512:
|
||||
- return tcp_exchange(fd, args->auth, key, key_len,
|
||||
- args->timeout);
|
||||
- break;
|
||||
- /* case AUTH_X509:
|
||||
- return ssl_exchange(...); */
|
||||
- default:
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-main(int argc, char **argv)
|
||||
-{
|
||||
- fence_xvm_args_t args;
|
||||
- const char *my_options = "di:a:p:T:r:C:c:k:H:uo:t:?hV";
|
||||
-
|
||||
- /* Print to stderr. Fenced will report our output for us */
|
||||
- logt_init(LOG_DAEMON_NAME, LOG_MODE_OUTPUT_STDERR,
|
||||
- SYSLOGFACILITY, SYSLOGLEVEL, SYSLOGLEVEL, NULL);
|
||||
-
|
||||
- args_init(&args);
|
||||
-
|
||||
- if (argc == 1) {
|
||||
- args_get_stdin(my_options, &args);
|
||||
- } else {
|
||||
- args_get_getopt(argc, argv, my_options, &args);
|
||||
- }
|
||||
-
|
||||
- if (args.flags & F_HELP) {
|
||||
- args_usage(argv[0], my_options, 0);
|
||||
-
|
||||
- printf("With no command line argument, arguments are "
|
||||
- "read from standard input.\n");
|
||||
- printf("Arguments read from standard input take "
|
||||
- "the form of:\n\n");
|
||||
- printf(" arg1=value1\n");
|
||||
- printf(" arg2=value2\n\n");
|
||||
-
|
||||
- args_usage(argv[0], my_options, 1);
|
||||
- exit(0);
|
||||
- }
|
||||
-
|
||||
- if (args.flags & F_METADATA) {
|
||||
- args_metadata(argv[0], my_options);
|
||||
- exit(0);
|
||||
- }
|
||||
-
|
||||
- if (args.flags & F_VERSION) {
|
||||
- printf("%s %s\n", basename(argv[0]), XVM_VERSION);
|
||||
- printf("fence release %s\n", RELEASE_VERSION);
|
||||
- exit(0);
|
||||
- }
|
||||
-
|
||||
- args_finalize(&args);
|
||||
- dset(args.debug);
|
||||
-
|
||||
- if (args.debug > 0) {
|
||||
- logt_conf(LOG_DAEMON_NAME, LOG_MODE_OUTPUT_STDERR,
|
||||
- SYSLOGFACILITY, LOG_DEBUG, LOG_DEBUG, NULL);
|
||||
- args_print(&args);
|
||||
- }
|
||||
-
|
||||
- /* Additional validation here */
|
||||
- if (!args.domain) {
|
||||
- logt_print(LOG_ERR, "No domain specified!\n");
|
||||
- args.flags |= F_ERR;
|
||||
- }
|
||||
-
|
||||
- if (args.flags & F_ERR) {
|
||||
- args_usage(argv[0], my_options, (argc == 1));
|
||||
- exit(1);
|
||||
- }
|
||||
-
|
||||
- /* Initialize NSS; required to do hashing, as silly as that
|
||||
- sounds... */
|
||||
- if (NSS_NoDB_Init(NULL) != SECSuccess) {
|
||||
- logt_print(LOG_ERR, "Could not initialize NSS\n");
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- return fence_xen_domain(&args);
|
||||
-}
|
||||
--- a/fence/agents/xvm/ip_lookup.c
|
||||
+++ /dev/null
|
||||
@@ -1,307 +0,0 @@
|
||||
-/** @file
|
||||
- * Build lists of IPs on the system, excepting loopback ipv6 link-local
|
||||
- */
|
||||
-#include <asm/types.h>
|
||||
-#include <sys/types.h>
|
||||
-#include <arpa/inet.h>
|
||||
-#include <sys/socket.h>
|
||||
-#include <linux/netlink.h>
|
||||
-#include <linux/rtnetlink.h>
|
||||
-#include <errno.h>
|
||||
-#include <stdio.h>
|
||||
-#include <string.h>
|
||||
-#include <unistd.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <netdb.h>
|
||||
-#include <liblogthread.h>
|
||||
-
|
||||
-#ifndef IFA_MAX
|
||||
-#include <linux/if_addr.h>
|
||||
-#endif
|
||||
-
|
||||
-/* Local includes */
|
||||
-#include "ip_lookup.h"
|
||||
-#include "debug.h"
|
||||
-
|
||||
-static int
|
||||
-send_addr_dump(int fd, int family)
|
||||
-{
|
||||
- struct nlmsghdr *nh;
|
||||
- struct rtgenmsg *g;
|
||||
- char buf[256];
|
||||
- struct sockaddr_nl addr;
|
||||
-
|
||||
- memset(&addr,0,sizeof(addr));
|
||||
- addr.nl_family = PF_NETLINK;
|
||||
-
|
||||
- memset(buf, 0, sizeof(buf));
|
||||
- nh = (struct nlmsghdr *)buf;
|
||||
- g = (struct rtgenmsg *)(buf + sizeof(struct nlmsghdr));
|
||||
-
|
||||
- nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
|
||||
- nh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
|
||||
- nh->nlmsg_type = RTM_GETADDR;
|
||||
- g->rtgen_family = family;
|
||||
-
|
||||
- return sendto(fd, buf, nh->nlmsg_len, 0, (struct sockaddr *)&addr,
|
||||
- sizeof(addr));
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static int
|
||||
-add_ip(ip_list_t *ipl, char *ipaddr, char family)
|
||||
-{
|
||||
- ip_addr_t *ipa;
|
||||
-
|
||||
- if (family == PF_INET6) {
|
||||
- /* Avoid loopback */
|
||||
- if (!strcmp(ipaddr, "::1"))
|
||||
- return -1;
|
||||
-
|
||||
- /* Avoid link-local addresses */
|
||||
- if (!strncmp(ipaddr, "fe80", 4))
|
||||
- return -1;
|
||||
- if (!strncmp(ipaddr, "fe90", 4))
|
||||
- return -1;
|
||||
- if (!strncmp(ipaddr, "fea0", 4))
|
||||
- return -1;
|
||||
- if (!strncmp(ipaddr, "feb0", 4))
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- dbg_printf(4, "Adding IP %s to list (family %d)\n", ipaddr, family);
|
||||
-
|
||||
- ipa = malloc(sizeof(*ipa));
|
||||
- if (!ipa)
|
||||
- return -1;
|
||||
- memset(ipa, 0, sizeof(*ipa));
|
||||
- ipa->ipa_family = family;
|
||||
- ipa->ipa_address = strdup(ipaddr);
|
||||
-
|
||||
- TAILQ_INSERT_TAIL(ipl, ipa, ipa_entries);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static int
|
||||
-add_ip_addresses(int family, ip_list_t *ipl)
|
||||
-{
|
||||
- /* List ipv4 addresses */
|
||||
- struct nlmsghdr *nh;
|
||||
- struct ifaddrmsg *ifa;
|
||||
- struct rtattr *rta, *nrta;
|
||||
- struct nlmsgerr *err;
|
||||
- char buf[10240];
|
||||
- char outbuf[256];
|
||||
- int x, fd, len;
|
||||
-
|
||||
- dbg_printf(5, "Connecting to Netlink...\n");
|
||||
- fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
||||
- if (fd < 0) {
|
||||
- perror("socket");
|
||||
- exit(1);
|
||||
- }
|
||||
-
|
||||
- dbg_printf(5, "Sending address dump request\n");
|
||||
- send_addr_dump(fd, family);
|
||||
- memset(buf, 0, sizeof(buf));
|
||||
-
|
||||
- dbg_printf(5, "Waiting for response\n");
|
||||
- x = recvfrom(fd, buf, sizeof(buf), 0, NULL, 0);
|
||||
- if (x < 0) {
|
||||
- perror("recvfrom");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- dbg_printf(5, "Received %d bytes\n", x);
|
||||
-
|
||||
- nh = (struct nlmsghdr *)buf;
|
||||
- while (NLMSG_OK(nh, x)) {
|
||||
-
|
||||
- switch(nh->nlmsg_type) {
|
||||
- case NLMSG_DONE:
|
||||
- close(fd);
|
||||
- return 0;
|
||||
-
|
||||
- case NLMSG_ERROR:
|
||||
- err = (struct nlmsgerr*)NLMSG_DATA(nh);
|
||||
- if (nh->nlmsg_len <
|
||||
- NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
|
||||
- fprintf(stderr, "ERROR truncated");
|
||||
- } else {
|
||||
- errno = -err->error;
|
||||
- perror("RTNETLINK answers");
|
||||
- }
|
||||
- close(fd);
|
||||
- return -1;
|
||||
-
|
||||
- case RTM_NEWADDR:
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- nh = NLMSG_NEXT(nh, x);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- /* RTM_NEWADDR */
|
||||
- len = NLMSG_PAYLOAD(nh,0);
|
||||
- ifa = NLMSG_DATA(nh);
|
||||
-
|
||||
- /* Make sure we got the type we expect back */
|
||||
- if (ifa->ifa_family != family) {
|
||||
- nh = NLMSG_NEXT(nh, x);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- rta = (struct rtattr *)((char *)ifa + sizeof(*ifa));
|
||||
- len -= sizeof(*ifa);
|
||||
- do {
|
||||
- /* Make sure we've got a valid rtaddr field */
|
||||
- if (!RTA_OK(rta, len)) {
|
||||
- dbg_printf(5, "!RTA_OK(rta, len)\n");
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (rta->rta_type == IFA_ADDRESS) {
|
||||
- inet_ntop(family, RTA_DATA(rta), outbuf,
|
||||
- sizeof(outbuf) );
|
||||
- add_ip(ipl, outbuf, family);
|
||||
- }
|
||||
-
|
||||
- if (rta->rta_type == IFA_LABEL) {
|
||||
- dbg_printf(5, "Skipping label: %s\n",
|
||||
- (char *)RTA_DATA(rta));
|
||||
- }
|
||||
-
|
||||
- nrta = RTA_NEXT(rta, len);
|
||||
- if (!nrta)
|
||||
- break;
|
||||
-
|
||||
- len -= ((char *)nrta - (char *)rta);
|
||||
- rta = nrta;
|
||||
- } while (RTA_OK(rta, len));
|
||||
-
|
||||
- nh = NLMSG_NEXT(nh, x);
|
||||
- }
|
||||
-
|
||||
- dbg_printf(5, "Closing Netlink connection\n");
|
||||
- close(fd);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-ip_search(ip_list_t *ipl, char *ip_name)
|
||||
-{
|
||||
- ip_addr_t *ipa;
|
||||
-
|
||||
- dbg_printf(5, "Looking for IP address %s in IP list %p...", ip_name, ipl);
|
||||
- ipa = ipl->tqh_first;
|
||||
- for (ipa = ipl->tqh_first; ipa; ipa = ipa->ipa_entries.tqe_next) {
|
||||
- if (!strcmp(ip_name, ipa->ipa_address)) {
|
||||
- dbg_printf(4,"Found\n");
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
- dbg_printf(5, "Not found\n");
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-ip_free_list(ip_list_t *ipl)
|
||||
-{
|
||||
- ip_addr_t *ipa;
|
||||
-
|
||||
- dbg_printf(5, "Tearing down IP list @ %p\n", ipl);
|
||||
- while ((ipa = ipl->tqh_first)) {
|
||||
- TAILQ_REMOVE(ipl, ipa, ipa_entries);
|
||||
- free(ipa->ipa_address);
|
||||
- free(ipa);
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-ip_build_list(ip_list_t *ipl)
|
||||
-{
|
||||
- dbg_printf(5, "Build IP address list\n");
|
||||
- TAILQ_INIT(ipl);
|
||||
- if (add_ip_addresses(PF_INET6, ipl) < 0) {
|
||||
- ip_free_list(ipl);
|
||||
- return -1;
|
||||
- }
|
||||
- if (add_ip_addresses(PF_INET, ipl) < 0) {
|
||||
- ip_free_list(ipl);
|
||||
- return -1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/**
|
||||
- Look up the interface name which corresponds to the given hostname and
|
||||
- return the list of matching attrinfo structures. We do this by looking
|
||||
- up all the possible physical and virtual network interfaces on the machine
|
||||
- and checking the hostname/IP mappings for each active IP address incurred.
|
||||
-
|
||||
- @param nodename Interface name
|
||||
- @param ret_ai Structure pointer to allocate & return.
|
||||
- @return -1 on failure or 0 on success.
|
||||
- */
|
||||
-int
|
||||
-ip_lookup(char *nodename, struct addrinfo **ret_ai)
|
||||
-{
|
||||
- char ip_name[256];
|
||||
- struct addrinfo *ai = NULL;
|
||||
- struct addrinfo *n;
|
||||
- void *p;
|
||||
- ip_list_t ipl;
|
||||
- int ret = -1;
|
||||
-
|
||||
- dbg_printf(5, "Looking for IP matching %s\n", nodename);
|
||||
- /* Build list of IP addresses configured locally */
|
||||
- if (ip_build_list(&ipl) < 0)
|
||||
- return -1;
|
||||
-
|
||||
- /* Get list of addresses for the host-name/ip */
|
||||
- if (getaddrinfo(nodename, NULL, NULL, &ai) != 0)
|
||||
- return -1;
|
||||
-
|
||||
-
|
||||
- /* Traverse list of addresses for given host-name/ip */
|
||||
- for (n = ai; n; n = n->ai_next) {
|
||||
- if (n->ai_family != PF_INET && n->ai_family != PF_INET6)
|
||||
- continue;
|
||||
-
|
||||
- if (n->ai_family == PF_INET)
|
||||
- p = &(((struct sockaddr_in *)n->ai_addr)->sin_addr);
|
||||
- else
|
||||
- p = &(((struct sockaddr_in6 *)n->ai_addr)->sin6_addr);
|
||||
-
|
||||
- if (!inet_ntop(n->ai_family, p, ip_name,
|
||||
- sizeof(ip_name)))
|
||||
- continue;
|
||||
-
|
||||
- /* Search local interfaces for this IP address */
|
||||
- if (ip_search(&ipl, ip_name) != 0)
|
||||
- continue;
|
||||
-
|
||||
- /* Found it */
|
||||
- ret = 0;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* Clean up */
|
||||
- if (!ret_ai)
|
||||
- freeaddrinfo(ai);
|
||||
- else
|
||||
- *ret_ai = ai;
|
||||
-
|
||||
- ip_free_list(&ipl);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
--- a/fence/agents/xvm/ip_lookup.h
|
||||
+++ /dev/null
|
||||
@@ -1,22 +0,0 @@
|
||||
-/** @file
|
||||
- * Header for ip_lookup.c
|
||||
- */
|
||||
-#ifndef _IP_LOOKUP_H
|
||||
-#define _IP_LOOKUP_H
|
||||
-
|
||||
-#include <sys/queue.h>
|
||||
-
|
||||
-typedef struct _ip_address {
|
||||
- TAILQ_ENTRY(_ip_address) ipa_entries;
|
||||
- char ipa_family;
|
||||
- char *ipa_address;
|
||||
-} ip_addr_t;
|
||||
-
|
||||
-typedef TAILQ_HEAD(_ip_list, _ip_address) ip_list_t;
|
||||
-
|
||||
-int ip_search(ip_list_t *ipl, char *ip_name);
|
||||
-int ip_free_list(ip_list_t *ipl);
|
||||
-int ip_build_list(ip_list_t *ipl);
|
||||
-int ip_lookup(char *, struct addrinfo **);
|
||||
-
|
||||
-#endif
|
Loading…
Reference in New Issue
Block a user