1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

merge from tridge

(This used to be ctdb commit eda3caa77be352967a41ff9bddda5296c94797a9)
This commit is contained in:
Ronnie Sahlberg 2007-09-13 14:28:18 +10:00
commit ab1c8c074e
13 changed files with 152 additions and 199 deletions

View File

@ -165,15 +165,11 @@ int ctdb_sys_send_tcp(int s,
we try to bind to it, and if that fails then we don't have that IP
on an interface
*/
bool ctdb_sys_have_ip(struct sockaddr_in ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname)
bool ctdb_sys_have_ip(struct sockaddr_in ip)
{
int s;
int ret;
if (is_loopback) {
DEBUG(0,(__location__ " NOT IMPLEMENTED YET: ctdb_sys_have_ip() does not yet support is_loopback on AIX. This needs to be implemented similar to system_linux.c\n"));
}
ip.sin_port = 0;
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == -1) {

View File

@ -241,100 +241,21 @@ int ctdb_sys_send_tcp(int s,
we try to bind to it, and if that fails then we don't have that IP
on an interface
if is_loopback is specified it will also return whether the ip address
is attached to the loopback interface or not
ifname, if non-NULL, will return the name of the interface this ip is tied to
*/
bool ctdb_sys_have_ip(struct sockaddr_in ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname)
bool ctdb_sys_have_ip(struct sockaddr_in ip)
{
struct ifreq *ifr = NULL;
struct ifconf ifc;
int s, i, num_ifs;
int s;
int ret;
if (is_loopback) {
*is_loopback = false;
}
if (*ifname) {
*ifname = NULL;
}
ip.sin_port = 0;
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == -1) {
return false;
}
ret = bind(s, (struct sockaddr *)&ip, sizeof(ip));
if (ret) {
goto finished;
}
/* find out how much space we need to store the interface details */
ifc.ifc_len = 0;
ifc.ifc_req = NULL;
ret = ioctl(s, SIOCGIFCONF, &ifc);
if (ret) {
DEBUG(0,(__location__ " ioctl to read interface list failed\n"));
goto finished;
}
ifr = talloc_size(mem_ctx, ifc.ifc_len);
/* get a list of all interface names and addresses */
ifc.ifc_req = ifr;
ret = ioctl(s, SIOCGIFCONF, &ifc);
if (ret) {
DEBUG(0,(__location__ " ioctl to read interface list failed\n"));
goto finished;
}
/* loop over all interfaces and search for the one matching ip */
num_ifs = ifc.ifc_len/sizeof(struct ifreq);
for (i=0; i<num_ifs;i++) {
struct sockaddr_in *sa;
/* we only care bout ipv4 addresses */
sa = (struct sockaddr_in *)&ifr[i].ifr_addr;
if (sa->sin_family != AF_INET) {
continue;
}
/* this is not the interface you are looking for */
if (!ctdb_same_ip(sa, &ip)) {
continue;
}
/* this is the ifr entry for this interface/address
read the interface flags so we can tell if it is
loopback or not
*/
ret = ioctl(s, SIOCGIFFLAGS, &ifr[i]);
if (ret) {
DEBUG(0,(__location__ " failed to read interface flags for interface %s\n", ifr[i].ifr_name));
goto finished;
}
/* was this ip tied to a loopback interface ? */
if (ifr[i].ifr_flags & IFF_LOOPBACK) {
if (is_loopback != NULL) {
*is_loopback = true;
}
}
if (ifname) {
*ifname = talloc_asprintf(mem_ctx, "%s", ifr[i].ifr_name);
}
/* if we got this far, we have found our interface so we can
exit the loop.
*/
break;
}
finished:
talloc_free(ifr);
close(s);
return ret == 0;
}

View File

@ -92,6 +92,8 @@ start() {
stop() {
echo -n $"Shutting down ctdbd service: "
ctdb shutdown
sleep 1
killall -q -9 ctdbd
RETVAL=$?
case $init_style in
suse)

View File

@ -16,22 +16,56 @@ shift
}
[ ! -f "$CTDB_PUBLIC_ADDRESSES" ] && {
echo "No public addresses file found. Nothing to do for 10.interfaces"
echo "`date` No public addresses file found. Nothing to do for 10.interfaces"
exit 0
}
################################################
# kill off any TCP connections with the given IP
kill_tcp_connections() {
_IP="$1"
_failed=0
_killcount=0
connfile="/etc/ctdb/state/connections.$_IP"
netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
while read dest src; do
srcip=`echo $src | cut -d: -f1`
srcport=`echo $src | cut -d: -f2`
destip=`echo $dest | cut -d: -f1`
destport=`echo $dest | cut -d: -f2`
ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
_killcount=`expr $_killcount + 1`
done < $connfile
/bin/rm -f $connfile
[ $_failed = 0 ] || {
echo "`date` Failed to send killtcp control"
return;
}
[ $_killcount -gt 0 ] || {
return;
}
_count=0
while netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" > /dev/null; do
sleep 1
_count=`expr $_count + 1`
[ $_count -gt 3 ] && {
echo "`date` Timed out killing tcp connections for IP $_IP"
return;
}
done
echo "`date` killed $_killcount TCP connections to released IP $_IP"
}
case $cmd in
#############################
# called when ctdbd starts up
startup)
# make sure that we only respond to ARP messages from the NIC where
# a particular ip address is associated.
echo 1 > /proc/sys/ipv4/conf/all/arp_filter
# move all public addresses onto loopback
cat $CTDB_PUBLIC_ADDRESSES | cut -d/ -f1 | while read ip; do
/sbin/ip addr add $ip/32 dev lo >/dev/null 2>/dev/null
done
[ -f /proc/sys/net/ipv4/conf/all/arp_filter ] && {
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
}
;;
@ -39,7 +73,7 @@ case $cmd in
# called when ctdbd wants to claim an IP address
takeip)
if [ $# != 3 ]; then
echo "must supply interface, IP and maskbits"
echo "`date` must supply interface, IP and maskbits"
exit 1
fi
iface=$1
@ -51,11 +85,12 @@ case $cmd in
echo "`/bin/date` Failed to bringup interface $iface"
exit 1
}
/sbin/ip addr del $ip/32 dev lo >/dev/null 2>/dev/null
/sbin/ip addr add $ip/$maskbits dev $iface || {
echo "`/bin/date` Failed to add $ip/$maskbits on dev $iface"
exit 1
}
# cope with the script being killed while we have the interface blocked
/sbin/iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
# flush our route cache
echo 1 > /proc/sys/net/ipv4/route/flush
@ -69,14 +104,32 @@ case $cmd in
echo "`/bin/date` must supply interface, IP and maskbits"
exit 1
fi
# releasing an IP is a bit more complex than it seems. Once the IP
# is released, any open tcp connections to that IP on this host will end
# up being stuck. Some of them (such as NFS connections) will be unkillable
# so we need to use the killtcp ctdb function to kill them off. We also
# need to make sure that no new connections get established while we are
# doing this! So what we do is this:
# 1) firewall this IP, so no new external packets arrive for it
# 2) use netstat -tn to find existing connections, and kill them
# 3) remove the IP from the interface
# 4) remove the firewall rule
iface=$1
ip=$2
maskbits=$3
/sbin/ip addr del $ip/$maskbits dev $iface || {
failed=0
# we do an extra delete to cope with the script being killed
/sbin/iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
/sbin/iptables -I INPUT -i $iface -d $ip -j DROP
kill_tcp_connections $ip
/sbin/ip addr del $ip/$maskbits dev $iface || failed=1
/sbin/iptables -D INPUT -i $iface -d $ip -j DROP
[ $failed = 0 ] || {
echo "`/bin/date` Failed to del $ip on dev $iface"
exit 1
}
/sbin/ip addr add $ip/32 dev lo >/dev/null 2>/dev/null
# flush our route cache
echo 1 > /proc/sys/net/ipv4/route/flush
@ -95,12 +148,21 @@ case $cmd in
monitor)
[ -x /usr/sbin/ethtool ] && {
cat $CTDB_PUBLIC_ADDRESSES | sed -e "s/^[^\t ]*[\t ]*//" -e "s/[\t ]*$//" | sort | uniq | while read IFACE; do
/usr/sbin/ethtool $IFACE | grep 'Link detected: yes' > /dev/null || {
echo "`date` ERROR: No link on the public network interface $IFACE"
exit 1
}
done
[ -z "$CTDB_PUBLIC_INTERFACE" ] || {
/usr/sbin/ethtool $CTDB_PUBLIC_INTERFACE | grep 'Link detected: yes' > /dev/null || {
echo "`date` ERROR: No link on the public network interface $CTDB_PUBLIC_INTERFACE"
exit 1
}
}
cat $CTDB_PUBLIC_ADDRESSES | sed -e "s/^[^\t ]*[\t ]*//" -e "s/[\t ]*$//" |
sort | uniq | while read IFACE; do
[ -z "$IFACE" ] || {
/usr/sbin/ethtool $IFACE | grep 'Link detected: yes' > /dev/null || {
echo "`date` ERROR: No link on the public network interface $IFACE"
exit 1
}
}
done
}
;;

View File

@ -55,37 +55,7 @@ case $cmd in
maskbits=$3
echo $ip >> /etc/ctdb/state/statd/restart
/bin/rm -f /etc/ctdb/state/statd/ip/$ip
# RST all tcp connections to the lockmanager
[ ! -z "$LOCKD_TCPPORT" ] && {
# RST all tcp connections used for NLM to ensure that they do
# not survive in ESTABLISHED state across a failover/failback
# and create an ack storm
netstat -tn |egrep "^tcp.*\s+$ip:${LOCKD_TCPPORT}\s+.*ESTABLISHED" | awk '{print $4" "$5}' | while read dest src; do
srcip=`echo $src | cut -d: -f1`
srcport=`echo $src | cut -d: -f2`
destip=`echo $dest | cut -d: -f1`
destport=`echo $dest | cut -d: -f2`
ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1
# ctdb killtcp $destip:$destport $srcip:$srcport >/dev/null 2>&1
done
} > /dev/null 2>&1
# RST the local side for all tcp connections used for NFS to ensure
# that they do not survive in ESTABLISHED state across a
# failover/failback and create an ack storm
netstat -tn |egrep "^tcp.*\s+$ip:2049\s+.*ESTABLISHED" | awk '{print $4" "$5}' | while read dest src; do
srcip=`echo $src | cut -d: -f1`
srcport=`echo $src | cut -d: -f2`
destip=`echo $dest | cut -d: -f1`
destport=`echo $dest | cut -d: -f2`
ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1
# ctdb killtcp $destip:$destport $srcip:$srcport >/dev/null 2>&1
done
exit 0
;;

View File

@ -66,11 +66,11 @@ ctdb_wait_tcp_ports() {
all_ok=1
for p in $wait_ports; do
if [ -x /usr/bin/netcat ]; then
/usr/bin/netcat -z 127.0.0.1 $p || all_ok=0
/usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
elif [ -x /usr/bin/nc ]; then
/usr/bin/nc -z 127.0.0.1 $p || all_ok=0
/usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
elif [ -x /usr/bin/netstat ]; then
(/usr/bin/netstat -a -n | egrep "0.0.0.0:$p .*LISTEN") || all_ok=0
(/usr/bin/netstat -a -n | egrep "0.0.0.0:$p\s*LISTEN" > /dev/null) || all_ok=0
else
echo "`date` - No tool to check tcp ports availabe. can not check in ctdb_wait_tcp_ports"
return
@ -157,11 +157,11 @@ ctdb_check_tcp_ports() {
for p in $wait_ports; do
all_ok=1
if [ -x /usr/bin/netcat ]; then
/usr/bin/netcat -z 127.0.0.1 $p || all_ok=0
/usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
elif [ -x /usr/bin/nc ]; then
/usr/bin/nc -z 127.0.0.1 $p || all_ok=0
/usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
elif [ -x /usr/bin/netstat ]; then
(/usr/bin/netstat -a -n | egrep "0.0.0.0:$p .*LISTEN") || all_ok=0
(/usr/bin/netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
fi
[ $all_ok -eq 1 ] || {
echo "`date` ERROR: $service_name tcp port $p is not responding"

View File

@ -1062,7 +1062,7 @@ int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
/* from takeover/system.c */
int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface);
bool ctdb_sys_have_ip(struct sockaddr_in ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname);
bool ctdb_sys_have_ip(struct sockaddr_in ip);
int ctdb_sys_send_tcp(int fd,
const struct sockaddr_in *dest,
const struct sockaddr_in *src,

View File

@ -210,7 +210,7 @@ int daemon_register_message_handler(struct ctdb_context *ctdb, uint32_t client_i
DEBUG(0,(__location__ " Failed to register handler %llu in daemon\n",
(unsigned long long)srvid));
} else {
DEBUG(2,(__location__ " Registered message handler for srvid=%llu\n",
DEBUG(1,(__location__ " Registered message handler for srvid=%llu\n",
(unsigned long long)srvid));
}
@ -218,7 +218,7 @@ int daemon_register_message_handler(struct ctdb_context *ctdb, uint32_t client_i
if ((srvid & 0xFFFFFFFF) == srvid &&
kill(srvid, 0) == 0) {
client->pid = srvid;
DEBUG(3,(__location__ " Registered PID %u for client %u\n",
DEBUG(1,(__location__ " Registered PID %u for client %u\n",
(unsigned)client->pid, client_id));
}
return res;

View File

@ -42,6 +42,7 @@ struct ctdb_recoverd {
struct timeval first_recover_time;
struct ban_state **banned_nodes;
struct timeval priority_time;
bool need_takeover_run;
};
#define CONTROL_TIMEOUT() timeval_current_ofs(ctdb->tunable.recover_timeout, 0)
@ -904,6 +905,7 @@ static int do_recovery(struct ctdb_recoverd *rec,
if enabled, tell nodes to takeover their public IPs
*/
if (ctdb->vnn) {
rec->need_takeover_run = false;
ret = ctdb_takeover_run(ctdb, nodemap);
if (ret != 0) {
DEBUG(0, (__location__ " Unable to setup public takeover addresses\n"));
@ -1154,6 +1156,7 @@ static void monitor_handler(struct ctdb_context *ctdb, uint64_t srvid,
TALLOC_CTX *tmp_ctx;
uint32_t changed_flags;
int i;
struct ctdb_recoverd *rec = talloc_get_type(private_data, struct ctdb_recoverd);
if (data.dsize != sizeof(*c)) {
DEBUG(0,(__location__ "Invalid data in ctdb_node_flag_change\n"));
@ -1212,13 +1215,7 @@ static void monitor_handler(struct ctdb_context *ctdb, uint64_t srvid,
during recovery
*/
if (changed_flags & NODE_FLAGS_DISABLED) {
ret = ctdb_takeover_run(ctdb, nodemap);
if (ret != 0) {
DEBUG(0, (__location__ " Unable to setup public takeover addresses\n"));
}
/* send a message to all clients telling them that the
cluster has been reconfigured */
ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_RECONFIGURE, tdb_null);
rec->need_takeover_run = true;
}
}
@ -1419,7 +1416,6 @@ static void monitor_cluster(struct ctdb_context *ctdb)
struct ctdb_vnn_map *vnnmap=NULL;
struct ctdb_vnn_map *remote_vnnmap=NULL;
int i, j, ret;
bool need_takeover_run;
struct ctdb_recoverd *rec;
rec = talloc_zero(ctdb, struct ctdb_recoverd);
@ -1444,8 +1440,6 @@ static void monitor_cluster(struct ctdb_context *ctdb)
ctdb_set_message_handler(ctdb, CTDB_SRVID_UNBAN_NODE, unban_handler, rec);
again:
need_takeover_run = false;
if (mem_ctx) {
talloc_free(mem_ctx);
mem_ctx = NULL;
@ -1538,7 +1532,7 @@ again:
/* if we are not the recmaster then we do not need to check
if recovery is needed
*/
if (pnn!=recmaster) {
if (pnn != recmaster) {
goto again;
}
@ -1658,7 +1652,7 @@ again:
matches in this code) */
if (nodemap->nodes[j].flags != remote_nodemap->nodes[j].flags) {
nodemap->nodes[j].flags = remote_nodemap->nodes[j].flags;
need_takeover_run = true;
rec->need_takeover_run = true;
}
}
@ -1746,10 +1740,13 @@ again:
}
/* we might need to change who has what IP assigned */
if (need_takeover_run && ctdb->vnn) {
if (rec->need_takeover_run) {
rec->need_takeover_run = false;
ret = ctdb_takeover_run(ctdb, nodemap);
if (ret != 0) {
DEBUG(0, (__location__ " Unable to setup public takeover addresses\n"));
DEBUG(0, (__location__ " Unable to setup public takeover addresses - starting recovery\n"));
do_recovery(rec, mem_ctx, pnn, num_active, nodemap,
vnnmap, nodemap->nodes[j].pnn);
}
}

View File

@ -205,29 +205,22 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
TDB_DATA indata,
bool *async_reply)
{
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
int ret;
struct takeover_callback_state *state;
struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
struct ctdb_vnn *vnn;
bool have_ip, is_loopback;
char *ifname = NULL;
/* update out vnn list */
vnn = find_public_ip_vnn(ctdb, pip->sin);
if (vnn == NULL) {
DEBUG(0,("takeoverip called for an ip '%s' that is not a public address\n",
inet_ntoa(pip->sin.sin_addr)));
talloc_free(tmp_ctx);
return 0;
}
vnn->pnn = pip->pnn;
/* if our kernel already has this IP, do nothing */
have_ip = ctdb_sys_have_ip(pip->sin, &is_loopback, tmp_ctx, &ifname);
/* if we have the ip and it is not set to a loopback address */
if (have_ip && !is_loopback) {
talloc_free(tmp_ctx);
if (ctdb_sys_have_ip(pip->sin)) {
return 0;
}
@ -257,7 +250,6 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
if (ret != 0) {
DEBUG(0,(__location__ " Failed to takeover IP %s on interface %s\n",
inet_ntoa(pip->sin.sin_addr), vnn->iface));
talloc_free(tmp_ctx);
talloc_free(state);
return -1;
}
@ -265,7 +257,6 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
/* tell ctdb_control.c that we will be replying asynchronously */
*async_reply = true;
talloc_free(tmp_ctx);
return 0;
}
@ -276,11 +267,17 @@ static void release_kill_clients(struct ctdb_context *ctdb, struct sockaddr_in i
{
struct ctdb_client_ip *ip;
DEBUG(1,("release_kill_clients for ip %s\n", inet_ntoa(in.sin_addr)));
for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
DEBUG(2,("checking for client %u with IP %s\n",
ip->client_id, inet_ntoa(ip->ip.sin_addr)));
if (ctdb_same_ip(&ip->ip, &in)) {
struct ctdb_client *client = ctdb_reqid_find(ctdb,
ip->client_id,
struct ctdb_client);
DEBUG(1,("matched client %u with IP %s and pid %u\n",
ip->client_id, inet_ntoa(ip->ip.sin_addr), client->pid));
if (client->pid != 0) {
DEBUG(0,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
(unsigned)client->pid, inet_ntoa(in.sin_addr),
@ -328,30 +325,28 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
TDB_DATA indata,
bool *async_reply)
{
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
int ret;
struct takeover_callback_state *state;
struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
struct ctdb_vnn *vnn;
bool have_ip, is_loopback;
char *ifname = NULL;
/* update our vnn list */
vnn = find_public_ip_vnn(ctdb, pip->sin);
if (vnn == NULL) {
DEBUG(0,("releaseip called for an ip '%s' that is not a public address\n",
inet_ntoa(pip->sin.sin_addr)));
talloc_free(tmp_ctx);
return 0;
}
vnn->pnn = pip->pnn;
have_ip = ctdb_sys_have_ip(pip->sin, &is_loopback, tmp_ctx, &ifname);
if ( (!have_ip) || is_loopback) {
DEBUG(0,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
/* stop any previous arps */
talloc_free(vnn->takeover_ctx);
vnn->takeover_ctx = NULL;
if (!ctdb_sys_have_ip(pip->sin)) {
DEBUG(2,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
vnn->iface));
talloc_free(tmp_ctx);
return 0;
}
@ -359,10 +354,6 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
vnn->iface));
/* stop any previous arps */
talloc_free(vnn->takeover_ctx);
vnn->takeover_ctx = NULL;
state = talloc(ctdb, struct takeover_callback_state);
CTDB_NO_MEMORY(ctdb, state);
@ -385,15 +376,12 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
if (ret != 0) {
DEBUG(0,(__location__ " Failed to release IP %s on interface %s\n",
inet_ntoa(pip->sin.sin_addr), vnn->iface));
talloc_free(tmp_ctx);
talloc_free(state);
return -1;
}
/* tell the control that we will be reply asynchronously */
*async_reply = true;
talloc_free(tmp_ctx);
return 0;
}
@ -767,7 +755,7 @@ try_again:
}
}
if (maxnode == -1) {
DEBUG(0,(__location__ " Could not find maxnode. May not be able to server ip '%s'\n", inet_ntoa(tmp_ip->sin.sin_addr)));
DEBUG(0,(__location__ " Could not find maxnode. May not be able to serve ip '%s'\n", inet_ntoa(tmp_ip->sin.sin_addr)));
continue;
}
@ -845,8 +833,8 @@ try_again:
ip.sin.sin_addr = tmp_ip->sin.sin_addr;
ret = ctdb_ctrl_takeover_ip(ctdb, TAKEOVER_TIMEOUT(),
tmp_ip->pnn,
&ip);
tmp_ip->pnn,
&ip);
if (ret != 0) {
DEBUG(0,("Failed asking vnn %u to take over IP %s\n",
tmp_ip->pnn,
@ -866,6 +854,8 @@ try_again:
*/
static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
{
DEBUG(3,("destroying client tcp for %s:%u (client_id %u)\n",
inet_ntoa(ip->ip.sin_addr), ntohs(ip->ip.sin_port), ip->client_id));
DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
return 0;
}
@ -888,10 +878,21 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
vnn = find_public_ip_vnn(ctdb, p->dest);
if (vnn == NULL) {
DEBUG(3,("Could not add client IP %s. This is not a public address.\n", inet_ntoa(p->dest.sin_addr)));
if (ntohl(p->dest.sin_addr.s_addr) != INADDR_LOOPBACK) {
DEBUG(0,("Could not add client IP %s. This is not a public address.\n",
inet_ntoa(p->dest.sin_addr)));
}
return 0;
}
if (vnn->pnn != ctdb->pnn) {
DEBUG(0,("Attempt to register tcp client for IP %s we don't hold - failing (client_id %u pid %u)\n",
inet_ntoa(p->dest.sin_addr),
client_id, client->pid));
/* failing this call will tell smbd to die */
return -1;
}
ip = talloc(client, struct ctdb_client_ip);
CTDB_NO_MEMORY(ctdb, ip);
@ -915,10 +916,10 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
data.dptr = (uint8_t *)&t;
data.dsize = sizeof(t);
DEBUG(2,("registered tcp client for %u->%s:%u\n",
DEBUG(1,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
(unsigned)ntohs(p->dest.sin_port),
inet_ntoa(p->src.sin_addr),
(unsigned)ntohs(p->src.sin_port)));
(unsigned)ntohs(p->src.sin_port), client_id, client->pid));
/* tell all nodes about this tcp connection */
ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
@ -1128,21 +1129,17 @@ void ctdb_takeover_client_destructor_hook(struct ctdb_client *client)
void ctdb_release_all_ips(struct ctdb_context *ctdb)
{
struct ctdb_vnn *vnn;
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
bool have_ip, is_loopback;
char *ifname = NULL;
for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
have_ip = ctdb_sys_have_ip(vnn->public_address, &is_loopback, tmp_ctx, &ifname);
if (have_ip && !is_loopback) {
ctdb_event_script(ctdb, "releaseip %s %s %u",
vnn->iface,
inet_ntoa(vnn->public_address.sin_addr),
vnn->public_netmask_bits);
release_kill_clients(ctdb, vnn->public_address);
if (!ctdb_sys_have_ip(vnn->public_address)) {
continue;
}
ctdb_event_script(ctdb, "releaseip %s %s %u",
vnn->iface,
inet_ntoa(vnn->public_address.sin_addr),
vnn->public_netmask_bits);
release_kill_clients(ctdb, vnn->public_address);
}
talloc_free(tmp_ctx);
}

View File

@ -46,6 +46,7 @@ static struct {
const char *logfile;
const char *recovery_lock_file;
const char *db_dir;
const char *public_interface;
int no_setsched;
} options = {
.nlist = ETCDIR "/ctdb/nodes",
@ -100,6 +101,7 @@ int main(int argc, const char *argv[])
POPT_CTDB_CMDLINE
{ "interactive", 'i', POPT_ARG_NONE, &interactive, 0, "don't fork", NULL },
{ "public-addresses", 0, POPT_ARG_STRING, &options.public_address_list, 0, "public address list file", "filename" },
{ "public-interface", 0, POPT_ARG_STRING, &options.public_interface, 0, "public interface", "interface"},
{ "event-script-dir", 0, POPT_ARG_STRING, &options.event_script_dir, 0, "event script directory", "dirname" },
{ "logfile", 0, POPT_ARG_STRING, &options.logfile, 0, "log file location", "filename" },
{ "nlist", 0, POPT_ARG_STRING, &options.nlist, 0, "node list file", "filename" },
@ -198,6 +200,11 @@ int main(int argc, const char *argv[])
}
}
if (options.public_interface) {
ctdb->default_public_interface = talloc_strdup(ctdb, options.public_interface);
CTDB_NO_MEMORY(ctdb, ctdb->default_public_interface);
}
if (options.public_address_list) {
ret = ctdb_set_public_addresses(ctdb, options.public_address_list);
if (ret == -1) {

View File

@ -375,7 +375,7 @@ static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
return ret;
}
return -1;
return 0;
}

View File

@ -123,6 +123,7 @@ show_all "/sbin/ip addr list"
show_all "/sbin/route -n"
show_all "crontab -l"
show_all "sysctl -a"
show_all "/sbin/iptables -L -n"
[ -d /usr/lpp/mmfs ] && {
cat <<EOF