The branch, master has been updated via a07af1b ctdb-tests: Need to drop public IPs in kill-failover tests via 7f3f3b1 ctdb-daemon: Gratuitous ARP equivalent for IPv6 is neighbor advertisement via 3a2c8bb ctdb-tests: More debug on SSH failure via 49449f6 ctdb-tests: Make tcpdump output more verbose via a7e7d95 ctdb-tests: Use ip neigh command instead of arp via 0f3d975 ctdb-tests: Generalise the gratarp and tickle sniffing code for IPv6 via 3135a8c ctdb-tests: Match IPv6 connections in netstat output via 255705c ctdb-tests: Use ping_wrapper to do relevant ping or ping6 via 62acf59 ctdb-tests: Extend regexps to handle IPv6 address matching via 62164ec ctdb-tests: Bracket IP addresses in NFS mounts and scp command (for IPv6) via d9d07ff ctdb-tests: Try to handle IPv6 addresses for local daemons via 2a83b74 ctdb-tests: Extend regexp to match IPv6 addresses via 2d48079 ctdb-tools: Bracket IP addresses in onnode (for IPv6) via e3c59d8 ctdb-daemon: Fix IP address comparisons for IPv6 addresses via d0b2375 ctdb-scripts: Wait until IPv6 addresses are not "tentative" via d4212bd ctdb-eventscripts: Specify broadcast optionally to ip addr add via 108b1be ctdb-daemon: Trust vnn->interface for an IP when releasing it via 6471541 ctdb-scripts: Make 10.interface IPv6-safe via c314ae0 ctdb-scripts: New functions ip6tables() and iptables_wrapper() via ed029ae ctdb-scripts: Add IPv6 addresses support in ip_maskbits_iface() via b41c1bd ctdb-utils: Update Nagios code to use ctdb -X via 0d61b61 ctdb-doc: Update examples to use ctdb -X via 550fb8c ctdb-tool: Fix "ctdb -Y ifaces" output to have trailing delimiters via 2c4de75 ctdb-tests: Update integration tests to use ctdb -X via 55df9c8 ctdb-tools: Update onnode and ctdb-diagnostics to use ctdb -X via 4940f19 ctdb-scripts: Update eventscripts to use ctdb -X instead of ctdb -Y via 7428f80 ctdb-tools: Add -X option for machine parsable output with separator '|' via 3b90e45 ctdb-tools: Add -x option to specify delimiter for machine readable output via fbacbb9 ctdb-tools: Produce machine readable output with new function printm() from abf867d inotify: Properly handle cross-dir renames
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit a07af1bb56a76d1a7ab856547c801499fc17b21b Author: Martin Schwenke <mar...@meltin.net> Date: Wed Dec 3 12:10:07 2014 +1100 ctdb-tests: Need to drop public IPs in kill-failover tests These tests simulate a dead node rather than a CTDB failure, so drop IP addresses when killing a "node" to avoid problems with duplicates. To cope with a CTDB failure a watchdog would be needed to ensure that the public IPs are dropped when CTDB dies. Let's not do that now. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> Autobuild-User(master): Martin Schwenke <mart...@samba.org> Autobuild-Date(master): Fri Dec 5 23:29:39 CET 2014 on sn-devel-104 commit 7f3f3b15d52c4047cbcb1c3e81f65675c8708f5f Author: Martin Schwenke <mar...@meltin.net> Date: Tue Dec 2 10:57:12 2014 +1100 ctdb-daemon: Gratuitous ARP equivalent for IPv6 is neighbor advertisement Not neighbour solicitation. See: https://tools.ietf.org/html/rfc4861#section-4.4 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 3a2c8bb906fac4e2611a28ead6b4290ddc93de54 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Dec 3 12:09:12 2014 +1100 ctdb-tests: More debug on SSH failure Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 49449f66fca52d5044d2e486570562df866adf57 Author: Martin Schwenke <mar...@meltin.net> Date: Mon Dec 1 13:30:29 2014 +1100 ctdb-tests: Make tcpdump output more verbose This helps with debugging. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit a7e7d95de9cf09652cef63d65484bbb0faa42e1c Author: Martin Schwenke <mar...@meltin.net> Date: Sat Nov 29 20:01:20 2014 +1100 ctdb-tests: Use ip neigh command instead of arp Extend select_test_node_and_ips() to set $test_prefix in addition to $test_ip. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 0f3d9752c4677b2f3b5ee47a0b8f973b4260ef57 Author: Martin Schwenke <mar...@meltin.net> Date: Mon Dec 1 14:07:57 2014 +1100 ctdb-tests: Generalise the gratarp and tickle sniffing code for IPv6 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> Pair-programmed-with: Amitay Isaacs <ami...@gmail.com> commit 3135a8c62551e09a3abada86335882a91d398747 Author: Martin Schwenke <mar...@meltin.net> Date: Mon Dec 1 13:51:47 2014 +1100 ctdb-tests: Match IPv6 connections in netstat output Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 255705c030135bd54a1f7a7dc40cbf00c2fb39c9 Author: Martin Schwenke <mar...@meltin.net> Date: Mon Dec 1 13:50:42 2014 +1100 ctdb-tests: Use ping_wrapper to do relevant ping or ping6 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 62acf5986f52a3118ed4e3638c5ac8b1f9c0adf8 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Dec 3 15:58:20 2014 +1100 ctdb-tests: Extend regexps to handle IPv6 address matching Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 62164ec52fd1082863bf5017a5170f74f18a07c3 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Dec 3 15:57:35 2014 +1100 ctdb-tests: Bracket IP addresses in NFS mounts and scp command (for IPv6) Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit d9d07fff34143d251b4987cdb1cff1e8b3384e64 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 26 21:32:22 2014 +1100 ctdb-tests: Try to handle IPv6 addresses for local daemons If CTDB_USE_IPV6 is set then use IPv6 addresses for nodes and public IPs. This can be useful for some simple tests. However, the node address actually needs to be on lo so that ctdbd can bind to the port on that address, so they actually need to be added as root before running tests, like this: for i in $(seq 1 10) ; do ip addr add "fc00:10::${i}/64" dev lo ; done IPv4 127.0.0.0/8 addresses are somehow magic and only one needs to be on lo so that many can be bound to. Also change the IPv4 node addresses to be (slightly) more exotic. For both IPv4 and IPv6, choose addresses that are compatible with socket wrapper. Signed-off-by: Martin Schwenke <mar...@meltin.net> Signed-off-by: Amitay Isaacs <ami...@gmail.com> (socket wrapper fixes) Reviewed-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> (socket wrapper fixes) commit 2a83b74597a3366536e1935e2e8ff23493503117 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 26 21:31:42 2014 +1100 ctdb-tests: Extend regexp to match IPv6 addresses Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 2d480792e7d0b3f6628186dc77f54b708e315dd1 Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 28 21:49:08 2014 +1100 ctdb-tools: Bracket IP addresses in onnode (for IPv6) Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit e3c59d83d0ace9d7421d40d33fe917fb82bb38d8 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 25 12:38:23 2014 +1100 ctdb-daemon: Fix IP address comparisons for IPv6 addresses Before storing node IP address, convert into the correct abbreviated string form for IPv6 addresses. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit d0b2375c3d754da3cd68e34617ab3edd36e9317b Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 17:33:21 2014 +1100 ctdb-scripts: Wait until IPv6 addresses are not "tentative" There are a few potential failure modes when adding an IPv6 address. It takes a little while of duplicate address detection to complete, so wait for a while. After a timeout, also need to check to see if duplicate address detection failed - if it did then actually drop the IP address. This really needs some careful thinking. If CTDB disappears on a node but the node's IP addresses are still on interfaces then the above failure mode could cause the takeover nodes to become banned. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit d4212bd6a533b4b54b56e376a9246f2396cba253 Author: Amitay Isaacs <ami...@gmail.com> Date: Thu Nov 20 21:58:31 2014 +1100 ctdb-eventscripts: Specify broadcast optionally to ip addr add Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 108b1be0ee62af7ecb3c775f45c540dd07a527bf Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 14:52:47 2014 +1100 ctdb-daemon: Trust vnn->interface for an IP when releasing it ctdb_sys_find_ifname() doesn't work for IPv6 addresses so don't use it. Trust the eventscript to do sanity checking on the interface. Current warnings are replaced with equivalents generated by the eventscript. The unlikely message: Public IP %s is hosted on interface %s but we have no VNN will be replaced by: WARNING: Public IP %s hosted on interface %s but VNN says __none__ which is clear enough. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 6471541d6d2bc9f2af0ff92b280abbd1d933cf88 Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 14:46:00 2014 +1100 ctdb-scripts: Make 10.interface IPv6-safe Add checking to "releaseip" and "updateip" to ensure that the given IP address is really on the given interface with the given netmask. If reality doesn't match the given arguments then believe reality. Use new function iptables_wrapper() instead of calling iptables() directly. Use new function flush_route_cache() instead of doing IPv4-specific /proc magic. Remove setting of otherwise unused variable "failed". Fix a test for which the error message has changed. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit c314ae0b2af4a902cdd003ec6d663fe5b62b003b Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 14:39:43 2014 +1100 ctdb-scripts: New functions ip6tables() and iptables_wrapper() ip6tables() uses the same lock as iptables(). This is done on suspicion. iptables_wrapper() takes 1st argument "inet" or "inet6", and the rest is passed to the correct iptables variant. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit ed029ae0a1faa56bf882a71d10828e2a90ab0bc7 Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 14:37:54 2014 +1100 ctdb-scripts: Add IPv6 addresses support in ip_maskbits_iface() It also prints a third word, the address family. This is either "inet" or "inet6". Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit b41c1bdaa1df92ee6c510ae6749d0524b88ef828 Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 10:48:25 2014 +1100 ctdb-utils: Update Nagios code to use ctdb -X Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 0d61b6137306ee0eab2981e3c213023c332da550 Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 10:47:22 2014 +1100 ctdb-doc: Update examples to use ctdb -X Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 550fb8ce877cf980b4fd3be4f964449b369cf61e Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 21 10:45:57 2014 +1100 ctdb-tool: Fix "ctdb -Y ifaces" output to have trailing delimiters In the CTDB CLI tool source code and the documentation example. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 2c4de75d8754616891e97222cfb2ec58fdd8eac2 Author: Martin Schwenke <mar...@meltin.net> Date: Thu Nov 20 15:03:25 2014 +1100 ctdb-tests: Update integration tests to use ctdb -X Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 55df9c86c19e261a2a384ffc4b77c596c84e53a0 Author: Martin Schwenke <mar...@meltin.net> Date: Thu Nov 20 14:39:59 2014 +1100 ctdb-tools: Update onnode and ctdb-diagnostics to use ctdb -X Also update onnode unit tests. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 4940f191d37b5deadc8b1edf0cd516674e5d5d64 Author: Martin Schwenke <mar...@meltin.net> Date: Thu Nov 20 14:32:46 2014 +1100 ctdb-scripts: Update eventscripts to use ctdb -X instead of ctdb -Y Also update associated eventscript unit tests and ctdb stub. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 7428f809a76044fcbc98fd5f718e331ce183941d Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 19 18:19:50 2014 +1100 ctdb-tools: Add -X option for machine parsable output with separator '|' Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 3b90e45bae555cc4a47fe9958b86628d41084868 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 19 17:15:21 2014 +1100 ctdb-tools: Add -x option to specify delimiter for machine readable output To support this, update printm() to replace ':' in format string with options.machineseparator, which is a string but must contain a single character. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit fbacbb9c7868e22c04980af3602bae59dd5fe34d Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 19 16:35:35 2014 +1100 ctdb-tools: Produce machine readable output with new function printm() printm() is a printf(3) replacement and must be used to printing any machine readable output. It currently just calls vprintf(3). Later it will change the field delimiter. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> ----------------------------------------------------------------------- Summary of changes: ctdb/common/ctdb_util.c | 12 +- ctdb/common/system_linux.c | 49 +++-- ctdb/config/events.d/10.interface | 87 +++++--- ctdb/config/events.d/13.per_ip_routing | 6 +- ctdb/config/events.d/62.cnfs | 2 +- ctdb/config/events.d/70.iscsi | 2 +- ctdb/config/functions | 83 ++++++-- ctdb/config/statd-callout | 8 +- ctdb/doc/ctdb.1.xml | 66 ++++-- ctdb/server/ctdb_takeover.c | 25 +-- ctdb/tests/complex/11_ctdb_delip_removes_ip.sh | 4 +- ctdb/tests/complex/18_ctdb_reloadips.sh | 4 +- ctdb/tests/complex/31_nfs_tickle.sh | 7 +- ctdb/tests/complex/33_gratuitous_arp.sh | 12 +- ctdb/tests/complex/34_nfs_tickle_restart.sh | 4 +- ctdb/tests/complex/41_failover_ping_discrete.sh | 12 +- ctdb/tests/complex/42_failover_ssh_hostname.sh | 17 +- ctdb/tests/complex/44_failover_nfs_oneway.sh | 2 +- ctdb/tests/complex/45_failover_nfs_kill.sh | 7 +- ctdb/tests/complex/scripts/local.bash | 91 ++++++++- ctdb/tests/events.d/00.test | 4 +- .../eventscripts/10.interface.releaseip.002.sh | 5 +- ctdb/tests/eventscripts/scripts/local.sh | 6 +- ctdb/tests/eventscripts/stubs/ctdb | 22 +- ctdb/tests/onnode/0070.sh | 10 +- ctdb/tests/onnode/0071.sh | 10 +- ctdb/tests/onnode/0072.sh | 10 +- ctdb/tests/onnode/0075.sh | 10 +- ctdb/tests/onnode/stubs/onnode-buggy-001 | 12 +- ctdb/tests/scripts/integration.bash | 79 ++++++-- ctdb/tests/simple/05_ctdb_listnodes.sh | 4 +- ctdb/tests/simple/11_ctdb_ip.sh | 8 +- ctdb/tests/simple/12_ctdb_getdebug.sh | 12 +- ctdb/tests/simple/20_delip_iface_gc.sh | 18 +- ctdb/tests/simple/27_ctdb_detach.sh | 2 +- ctdb/tests/simple/75_readonly_records_basic.sh | 4 +- ctdb/tests/simple/scripts/local_daemons.bash | 14 +- ctdb/tools/ctdb.c | 223 +++++++++++++-------- ctdb/tools/ctdb_diagnostics | 2 +- ctdb/tools/onnode | 10 +- ctdb/utils/nagios/check_ctdb | 4 +- 41 files changed, 637 insertions(+), 332 deletions(-) mode change 100644 => 100755 ctdb/utils/nagios/check_ctdb Changeset truncated at 500 lines: diff --git a/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c index bdff425..137e0a8 100644 --- a/ctdb/common/ctdb_util.c +++ b/ctdb/common/ctdb_util.c @@ -100,12 +100,20 @@ int ctdb_parse_address(struct ctdb_context *ctdb, struct ctdb_address *address) { struct servent *se; + ctdb_sock_addr addr; setservent(0); se = getservbyname("ctdb", "tcp"); endservent(); - - address->address = talloc_strdup(mem_ctx, str); + + /* Parse IP address and re-convert to string. This ensure correct + * string form for IPv6 addresses. + */ + if (! parse_ip(str, NULL, 0, &addr)) { + return -1; + } + + address->address = talloc_strdup(mem_ctx, ctdb_addr_to_str(&addr)); CTDB_NO_MEMORY(ctdb, address->address); if (se == NULL) { diff --git a/ctdb/common/system_linux.c b/ctdb/common/system_linux.c index 9aaa1fd..97a57ac 100644 --- a/ctdb/common/system_linux.c +++ b/ctdb/common/system_linux.c @@ -75,9 +75,14 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface) struct ether_header *eh; struct arphdr *ah; struct ip6_hdr *ip6; - struct nd_neighbor_solicit *nd_ns; + struct nd_neighbor_advert *nd_na; + struct nd_opt_hdr *nd_oh; struct ifreq if_hwaddr; - unsigned char buffer[78]; /* ipv6 neigh solicitation size */ + /* Size of IPv6 neighbor advertisement (with option) */ + unsigned char buffer[sizeof(struct ether_header) + + sizeof(struct ip6_hdr) + + sizeof(struct nd_neighbor_advert) + + sizeof(struct nd_opt_hdr) + ETH_ALEN]; char *ptr; char bdcast[] = {0xff,0xff,0xff,0xff,0xff,0xff}; struct ifreq ifr; @@ -219,31 +224,45 @@ int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface) memset(buffer, 0 , sizeof(buffer)); eh = (struct ether_header *)buffer; - memset(eh->ether_dhost, 0xff, ETH_ALEN); + /* Ethernet multicast: 33:33:00:00:00:01 (see RFC2464, + * section 7) - note zeroes above! */ + eh->ether_dhost[0] = eh->ether_dhost[1] = 0x33; + eh->ether_dhost[5] = 0x01; memcpy(eh->ether_shost, if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN); eh->ether_type = htons(ETHERTYPE_IP6); ip6 = (struct ip6_hdr *)(eh+1); ip6->ip6_vfc = 0x60; - ip6->ip6_plen = htons(sizeof(*nd_ns)); + ip6->ip6_plen = htons(sizeof(*nd_na) + + sizeof(struct nd_opt_hdr) + + ETH_ALEN); ip6->ip6_nxt = IPPROTO_ICMPV6; ip6->ip6_hlim = 255; - ip6->ip6_dst = addr->ip6.sin6_addr; - - nd_ns = (struct nd_neighbor_solicit *)(ip6+1); - nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT; - nd_ns->nd_ns_code = 0; - nd_ns->nd_ns_reserved = 0; - nd_ns->nd_ns_target = addr->ip6.sin6_addr; - - nd_ns->nd_ns_cksum = tcp_checksum6((uint16_t *)nd_ns, ntohs(ip6->ip6_plen), ip6); + ip6->ip6_src = addr->ip6.sin6_addr; + /* all-nodes multicast */ + inet_pton(AF_INET6, "ff02::1", &ip6->ip6_dst); + + nd_na = (struct nd_neighbor_advert *)(ip6+1); + nd_na->nd_na_type = ND_NEIGHBOR_ADVERT; + nd_na->nd_na_code = 0; + nd_na->nd_na_flags_reserved = ND_NA_FLAG_OVERRIDE; + nd_na->nd_na_target = addr->ip6.sin6_addr; + /* Option: Target link-layer address */ + nd_oh = (struct nd_opt_hdr *)(nd_na+1); + nd_oh->nd_opt_type = ND_OPT_TARGET_LINKADDR; + nd_oh->nd_opt_len = 1; + memcpy(&(nd_oh+1)[0], if_hwaddr.ifr_hwaddr.sa_data, ETH_ALEN); + + nd_na->nd_na_cksum = tcp_checksum6((uint16_t *)nd_na, + ntohs(ip6->ip6_plen), ip6); sall.sll_family = AF_PACKET; sall.sll_halen = 6; - memcpy(&sall.sll_addr[0], bdcast, sall.sll_halen); + memcpy(&sall.sll_addr[0], &eh->ether_dhost[0], sall.sll_halen); sall.sll_protocol = htons(ETH_P_ALL); sall.sll_ifindex = ifr.ifr_ifindex; - ret = sendto(s, buffer, 78, 0, (struct sockaddr *)&sall, sizeof(sall)); + ret = sendto(s, buffer, sizeof(buffer), + 0, (struct sockaddr *)&sall, sizeof(sall)); if (ret < 0 ){ close(s); DEBUG(DEBUG_CRIT,(__location__ " failed sendto\n")); diff --git a/ctdb/config/events.d/10.interface b/ctdb/config/events.d/10.interface index 018f767..51d1b97 100755 --- a/ctdb/config/events.d/10.interface +++ b/ctdb/config/events.d/10.interface @@ -46,7 +46,7 @@ get_all_interfaces () # Get the interfaces for which CTDB has public IPs configured. # That is, for all but the 1st line, get the 1st field. - ctdb_ifaces=$(ctdb -Y ifaces | sed -e '1d' -e 's@^:@@' -e 's@:.*@@') + ctdb_ifaces=$(ctdb -X ifaces | sed -e '1d' -e 's@^|@@' -e 's@|.*@@') # Add $ctdb_interfaces and uniquify all_interfaces=$(echo $all_interfaces $ctdb_ifaces | tr ' ' '\n' | sort -u) @@ -137,6 +137,34 @@ monitor_interfaces() return 1 } +# Sets: iface, ip, maskbits, family +get_iface_ip_maskbits_family () +{ + _iface_in="$1" + ip="$2" + _maskbits_in="$3" + + set -- $(ip_maskbits_iface "$ip") + if [ -n "$1" ] ; then + maskbits="$1" + iface="$2" + family="$3" + + if [ "$iface" != "$_iface_in" ] ; then + printf \ + 'WARNING: Public IP %s hosted on interface %s but VNN says %s\n' \ + "$ip" "$iface" "$_iface_in" + fi + if [ "$maskbits" != "$_maskbits_in" ] ; then + printf \ + 'WARNING: Public IP %s has %s bit netmask but VNN says %s\n' \ + "$ip" "$maskbits" "$_maskbits_in" + fi + else + die "ERROR: Unable to determine interface for IP ${ip}" + fi +} + ctdb_check_args "$@" case "$1" in @@ -174,10 +202,13 @@ case "$1" in } # cope with the script being killed while we have the interface blocked - iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null + case "$ip" in + *:*) family="inet6" ;; + *) family="inet" ;; + esac + iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null - # flush our route cache - set_proc sys/net/ipv4/route/flush 1 + flush_route_cache ;; @@ -194,25 +225,23 @@ case "$1" in # 2) use netstat -tn to find existing connections, and kill them # 3) remove the IP from the interface # 4) remove the firewall rule - iface=$2 - ip=$3 - maskbits=$4 + shift + get_iface_ip_maskbits_family "$@" - failed=0 # we do an extra delete to cope with the script being killed - iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null - iptables -I INPUT -i $iface -d $ip -j DROP + iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null + iptables_wrapper $family -I INPUT -i $iface -d $ip -j DROP kill_tcp_connections $ip delete_ip_from_iface $iface $ip $maskbits || { - iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null - exit 1; + iptables_wrapper $family \ + -D INPUT -i $iface -d $ip -j DROP 2> /dev/null + exit 1 } - iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null + iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null - # flush our route cache - set_proc sys/net/ipv4/route/flush 1 + flush_route_cache ;; ################################################## @@ -224,34 +253,36 @@ case "$1" in # we finally remove it from the old interface. # # 1) firewall this IP, so no new external packets arrive for it - # 2) add the IP to the new interface - # 3) remove the IP from the old interface + # 2) remove the IP from the old interface (and new interface, to be sure) + # 3) add the IP to the new interface # 4) remove the firewall rule # 5) use ctdb gratiousarp to propagate the new mac address # 6) use netstat -tn to find existing connections, and tickle them - oiface=$2 + _oiface=$2 niface=$3 - ip=$4 - maskbits=$5 + _ip=$4 + _maskbits=$5 + + get_iface_ip_maskbits_family "$_oiface" "$ip" "$maskbits" + oiface="$iface" - failed=0 # we do an extra delete to cope with the script being killed - iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null - iptables -I INPUT -i $oiface -d $ip -j DROP + iptables_wrapper $family -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null + iptables_wrapper $family -I INPUT -i $oiface -d $ip -j DROP delete_ip_from_iface $oiface $ip $maskbits 2>/dev/null delete_ip_from_iface $niface $ip $maskbits 2>/dev/null add_ip_to_iface $niface $ip $maskbits || { - iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null - exit 1; + iptables_wrapper $family \ + -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null + exit 1 } # cope with the script being killed while we have the interface blocked - iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null + iptables_wrapper $family -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null - # flush our route cache - set_proc sys/net/ipv4/route/flush 1 + flush_route_cache # propagate the new mac address ctdb gratiousarp $ip $niface diff --git a/ctdb/config/events.d/13.per_ip_routing b/ctdb/config/events.d/13.per_ip_routing index ee83632..cd0020e 100755 --- a/ctdb/config/events.d/13.per_ip_routing +++ b/ctdb/config/events.d/13.per_ip_routing @@ -290,7 +290,7 @@ flush_rules_and_routes () # routes. add_missing_routes () { - ctdb ip -v -Y | { + ctdb ip -v -X | { read _x # skip header line # Read the rest of the lines. We're only interested in the @@ -299,7 +299,7 @@ add_missing_routes () # non-local addresses. For each IP local address we check if # the relevant routing table is populated and populate it if # not. - while IFS=":" read _x _ip _x _iface _x ; do + while IFS="|" read _x _ip _x _iface _x ; do [ -n "$_iface" ] || continue _table_id="${table_id_prefix}${_ip}" @@ -317,7 +317,7 @@ add_missing_routes () remove_bogus_routes () { # Get a IPs current hosted by this node, each anchored with '@'. - _ips=$(ctdb ip -v -Y | awk -F: 'NR > 1 && $4 != "" {printf "@%s@\n", $2}') + _ips=$(ctdb ip -v -X | awk -F'|' 'NR > 1 && $4 != "" {printf "@%s@\n", $2}') ip rule show | while read _p _x _i _x _t ; do diff --git a/ctdb/config/events.d/62.cnfs b/ctdb/config/events.d/62.cnfs index da02acc..a6ca0c4 100755 --- a/ctdb/config/events.d/62.cnfs +++ b/ctdb/config/events.d/62.cnfs @@ -53,7 +53,7 @@ case "$1" in # Wait until we no longer serve any ip addresses at all PNN=`ctdb pnn | cut -d: -f2` - while `ctdb -Y ip | cut -d: -f3 | egrep "^$PNN$" >/dev/null`; do + while `ctdb -X ip | cut -d'|' -f3 | egrep "^$PNN$" >/dev/null`; do sleep 1 done ;; diff --git a/ctdb/config/events.d/70.iscsi b/ctdb/config/events.d/70.iscsi index cedaf40..4627822 100755 --- a/ctdb/config/events.d/70.iscsi +++ b/ctdb/config/events.d/70.iscsi @@ -36,7 +36,7 @@ case "$1" in # start the iscsi daemon tgtd >/dev/null 2>/dev/null - ips=$(ctdb -Y ip | awk -F: -v pnn=$this_node '$3 == pnn {print $2}') + ips=$(ctdb -X ip | awk -F'|' -v pnn=$this_node '$3 == pnn {print $2}') for ip in $ips ; do script="${CTDB_START_ISCSI_SCRIPTS}/${ip}.sh" if [ -x "$script" ] ; then diff --git a/ctdb/config/functions b/ctdb/config/functions index 77c3ffb..23cb236 100755 --- a/ctdb/config/functions +++ b/ctdb/config/functions @@ -859,10 +859,39 @@ add_ip_to_iface () ip link set "$_iface" up || \ die "Failed to bringup interface $_iface" - ip addr add "$_ip/$_maskbits" brd + dev "$_iface" || { + # Only need to define broadcast for IPv4 + case "$ip" in + *:*) _bcast="" ;; + *) _bcast="brd +" ;; + esac + + ip addr add "$_ip/$_maskbits" $_bcast dev "$_iface" || { echo "Failed to add $_ip/$_maskbits on dev $_iface" return 1 } + + # Wait 5 seconds for IPv6 addresses to stop being tentative... + if [ -z "$_bcast" ] ; then + for _x in $(seq 1 10) ; do + ip addr show to "${_ip}/128" | grep -q "tentative" || break + sleep 0.5 + done + + # If the address was a duplicate then it won't be on the + # interface so flag an error. + _t=$(ip addr show to "${_ip}/128") + case "$_t" in + "") + echo "Failed to add $_ip/$_maskbits on dev $_iface" + return 1 + ;; + *tentative*|*dadfailed*) + echo "Failed to add $_ip/$_maskbits on dev $_iface" + ip addr del "$_ip/$_maskbits" dev "$_iface" + return 1 + ;; + esac + fi } delete_ip_from_iface() @@ -889,8 +918,15 @@ ip_maskbits_iface () { _addr="$1" - ip addr show to "${_addr}/32" 2>/dev/null | \ - awk '$1 == "inet" { print gensub(".*/", "", 1, $2), $NF }' + case "$_addr" in + *:*) _family="inet6" ; _bits=128 ;; + *) _family="inet" ; _bits=32 ;; + esac + + ip addr show to "${_addr}/${_bits}" 2>/dev/null | \ + awk -v family="${_family}" \ + 'NR == 1 { iface = gensub(":$", "", 1, $2) } \ + $1 ~ /inet/ { print gensub(".*/", "", 1, $2), iface, family }' } drop_ip () @@ -913,6 +949,12 @@ drop_all_public_ips () done <"${CTDB_PUBLIC_ADDRESSES:-/dev/null}" } +flush_route_cache () +{ + set_proc sys/net/ipv4/route/flush 1 + set_proc sys/net/ipv6/route/flush 1 +} + ######################################################## # Simple counters _ctdb_counter_common () { @@ -1120,19 +1162,19 @@ ctdb_reconfigure_release_lock () ctdb_replay_monitor_status () { echo "Replaying previous status for this script due to reconfigure..." - # Leading colon (':') is missing in some versions... - _out=$(ctdb scriptstatus -Y | grep -E "^:?monitor:${script_name}:") + # Leading separator ('|') is missing in some versions... + _out=$(ctdb scriptstatus -X | grep -E "^\|?monitor\|${script_name}\|") # Output looks like this: - # :monitor:60.nfs:1:ERROR:1314764004.030861:1314764004.035514:foo bar: + # |monitor|60.nfs|1|ERROR|1314764004.030861|1314764004.035514|foo bar| # This is the cheapest way of getting fields in the middle. - set -- $(IFS=":" ; echo $_out) + set -- $(IFS="|" ; echo $_out) _code="$3" _status="$4" # The error output field can include colons so we'll try to # preserve them. The weak checking at the beginning tries to make - # this work for both broken (no leading ':') and fixed output. - _out="${_out%:}" - _err_out="${_out#*monitor:${script_name}:*:*:*:*:}" + # this work for both broken (no leading '|') and fixed output. + _out="${_out%|}" + _err_out="${_out#*monitor|${script_name}|*|*|*|*|}" case "$_status" in OK) : ;; # Do nothing special. TIMEDOUT) @@ -1349,10 +1391,23 @@ ctdb_standard_event_handler () } # iptables doesn't like being re-entered, so flock-wrap it. -iptables() +iptables () { flock -w 30 $CTDB_VARDIR/iptables-ctdb.flock /sbin/iptables "$@" } +ip6tables () +{ + flock -w 30 $CTDB_VARDIR/iptables-ctdb.flock /sbin/ip6tables "$@" +} +iptables_wrapper () +{ + _family="$1" ; shift + if [ "$_family" = "inet6" ] ; then + ip6tables "$@" + else + iptables "$@" + fi +} # AIX (and perhaps others?) doesn't have mktemp if ! which mktemp >/dev/null 2>&1 ; then @@ -1395,7 +1450,7 @@ update_tickles () _pnn=$(ctdb pnn) ; _pnn=${_pnn#PNN:} # What public IPs do I hold? - _ips=$(ctdb -Y ip | awk -F: -v pnn=$_pnn '$3 == pnn {print $2}') + _ips=$(ctdb -X ip | awk -F'|' -v pnn=$_pnn '$3 == pnn {print $2}') # IPs as a regexp choice _ipschoice="($(echo $_ips | sed -e 's/ /|/g' -e 's/\./\\\\./g'))" @@ -1412,8 +1467,8 @@ update_tickles () _my_tickles="${tickledir}/${_port}.tickles" rm -f "$_my_tickles" for _i in $_ips ; do - ctdb -Y gettickles $_i $_port | - awk -F: 'NR > 1 { printf "%s:%s %s:%s\n", $2, $3, $4, $5 }' + ctdb -X gettickles $_i $_port | + awk -F'|' 'NR > 1 { printf "%s:%s %s:%s\n", $2, $3, $4, $5 }' done | sort >"$_my_tickles" diff --git a/ctdb/config/statd-callout b/ctdb/config/statd-callout index 53b408d..5e8eb0e 100755 --- a/ctdb/config/statd-callout +++ b/ctdb/config/statd-callout @@ -37,12 +37,12 @@ case "$1" in cip="$2" pnn=$(ctdb xpnn | sed -e 's/.*://') date=$(date '+%s') - ctdb ip -Y | + ctdb ip -X | tail -n +2 | { # This all needs to be in the end of the pipe so it # doesn't get lost items="" - while IFS=":" read x sip node x ; do + while IFS="|" read x sip node x ; do [ "$node" = "$pnn" ] || continue # not us key="statd-state@${sip}@${cip}" item="\"${key}\" \"${date}\"" @@ -58,12 +58,12 @@ case "$1" in # so we must add it to all the IPs that we serve cip="$2" pnn=$(ctdb xpnn | sed -e 's/.*://') - ctdb ip -Y | + ctdb ip -X | tail -n +2 | { # This all needs to be in the end of the pipe so it # doesn't get lost items="" - while IFS=":" read x sip node x ; do + while IFS="|" read x sip node x ; do [ "$node" = "$pnn" ] || continue # not us key="statd-state@${sip}@${cip}" item="\"${key}\" \"\"" diff --git a/ctdb/doc/ctdb.1.xml b/ctdb/doc/ctdb.1.xml index 170d05a..07df43b 100644 --- a/ctdb/doc/ctdb.1.xml +++ b/ctdb/doc/ctdb.1.xml -- Samba Shared Repository