The branch, 1.2.27 has been updated
       via  a57f1c5f7c6fce6df3d9f773527983a49bee75c0 (commit)
       via  de276bbc1a3df26e560d0ba37029584f48a7e92b (commit)
       via  361d36677baeb4f22df1006e6f6b71c881ee7bf1 (commit)
       via  976e968ea75db31c0b90c8de71536304e85c6521 (commit)
       via  489e1d68bd7b83605ce8c1e2a978234a70f99a08 (commit)
      from  636e2f02e44803d789c2af5c605b55db3bd32d04 (commit)

http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=1.2.27


- Log -----------------------------------------------------------------
commit a57f1c5f7c6fce6df3d9f773527983a49bee75c0
Author: Ronnie Sahlberg <[email protected]>
Date:   Fri Jul 29 08:43:49 2011 +1000

    new version 1.2.27-204

commit de276bbc1a3df26e560d0ba37029584f48a7e92b
Author: Ronnie Sahlberg <[email protected]>
Date:   Fri Jul 29 08:41:35 2011 +1000

    Update the delip command
    Dont talloc_free(vnn) immediately but postphone it until later when
    the eventscript callback has completed.
    
    CQ S1026664

commit 361d36677baeb4f22df1006e6f6b71c881ee7bf1
Author: Ronnie Sahlberg <[email protected]>
Date:   Mon Jul 25 21:18:31 2011 +1000

    New version 1.2.27-203

commit 976e968ea75db31c0b90c8de71536304e85c6521
Author: Rusty Russell <[email protected]>
Date:   Mon Jul 25 17:56:06 2011 +0930

    eventscript: fix callback after free
    
    ctdb_event_script_callback() takes a mem_ctx arg which it doesn't use, but
    the implication is pretty clear, that when that mem_ctx is freed, the 
callback
    shouldn't happen.  Indeed, Ronnie reproduced a case where that callback
    refers to freed memory, in the ip reallocation code under stress.
    
    So attach the callback to the mem_ctx they give us, and remove it from the
    script state structure when that's freed.  It's a bit weird, but it works.
    
    CQ: S1026179
    Signed-off-by: Rusty Russell <[email protected]>

commit 489e1d68bd7b83605ce8c1e2a978234a70f99a08
Author: Ronnie Sahlberg <[email protected]>
Date:   Mon May 9 06:35:33 2011 +1000

    Remove logging of spam/errors from the 10.interfrace
    script if/when we have for example NATGW configured but no public addresses 
defined on that interface
    
    CQ S1023378

-----------------------------------------------------------------------

Summary of changes:
 config/events.d/10.interface |   19 +++++++--------
 packaging/RPM/ctdb.spec.in   |   10 +++++++-
 server/ctdb_takeover.c       |    8 ++++--
 server/eventscript.c         |   50 ++++++++++++++++++++++++++++++++---------
 tools/ctdb.c                 |   16 ++++++------
 5 files changed, 70 insertions(+), 33 deletions(-)


Changeset truncated at 500 lines:

diff --git a/config/events.d/10.interface b/config/events.d/10.interface
index b906e6a..f793673 100755
--- a/config/events.d/10.interface
+++ b/config/events.d/10.interface
@@ -13,7 +13,6 @@ loadconfig
 }
 
 [ ! -f "$CTDB_PUBLIC_ADDRESSES" ] && {
-       echo "No public addresses file found. Nothing to do for 10.interfaces"
        exit 0
 }
 
@@ -53,25 +52,25 @@ monitor_interfaces()
                grep -q 'Currently Active Slave: None' 
/proc/net/bonding/$REALIFACE && {
                        echo "ERROR: No active slaves for bond device 
$REALIFACE"
                        fail=1
-                       ctdb setifacelink $IFACE down
+                       ctdb setifacelink $IFACE down >/dev/null 2>/dev/null
                        continue;
                }
                grep -q '^MII Status: up' /proc/net/bonding/$REALIFACE || {
                        echo "ERROR: public network interface $REALIFACE is 
down"
                        fail=1
-                       ctdb setifacelink $IFACE down
+                       ctdb setifacelink $IFACE down >/dev/null 2>/dev/null
                        continue;
                }
                grep -q '^Bonding Mode: IEEE 802.3ad Dynamic link aggregation' 
/proc/net/bonding/$REALIFACE && {
                        grep 'MII Status:' /proc/net/bonding/$REALIFACE | tail 
-n +2 | grep -q '^MII Status: up' || {
                                echo No active slaves for 802.ad bond device 
$REALIFACE
-                               ctdb setifacelink $IFACE down
+                               ctdb setifacelink $IFACE down >/dev/null 
2>/dev/null
                                fail=1
                                continue
                        }
                }
                ok=1 # we only set ok for interfaces known to ctdbd
-               ctdb setifacelink $IFACE up
+               ctdb setifacelink $IFACE up >/dev/null 2>/dev/null
                continue;
            }
 
@@ -79,12 +78,12 @@ monitor_interfaces()
            lo*)
                # loopback is always working
                ok=1 # we only set ok for interfaces known to ctdbd
-               ctdb setifacelink $IFACE up
+               ctdb setifacelink $IFACE up >/dev/null 2>/dev/null
                ;;
            ib*)
                # we dont know how to test ib links
                ok=1 # we only set ok for interfaces known to ctdbd
-               ctdb setifacelink $IFACE up
+               ctdb setifacelink $IFACE up >/dev/null 2>/dev/null
                ;;
            *)
                [ -z "$IFACE" ] || {
@@ -98,12 +97,12 @@ monitor_interfaces()
                        ethtool $IFACE | grep -q 'Link detected: yes' || {
                            echo "ERROR: No link on the public network 
interface $IFACE"
                            fail=1
-                           ctdb setifacelink $IFACE down
+                           ctdb setifacelink $IFACE down >/dev/null 2>/dev/null
                            continue
                        }
                    }
                    ok=1 # we only set ok for interfaces known to ctdbd
-                   ctdb setifacelink $IFACE up
+                   ctdb setifacelink $IFACE up >/dev/null 2>/dev/null
                }
                ;;
            esac
@@ -140,7 +139,7 @@ case "$1" in
        INTERFACES=`for IFACE in $INTERFACES ; do echo $IFACE ; done | sort | 
uniq`
 
        for IFACE in $INTERFACES ; do
-               ctdb setifacelink $IFACE down
+               ctdb setifacelink $IFACE down >/dev/null 2>/dev/null
        done
        
        monitor_interfaces
diff --git a/packaging/RPM/ctdb.spec.in b/packaging/RPM/ctdb.spec.in
index fd83c4b..2ddfaae 100644
--- a/packaging/RPM/ctdb.spec.in
+++ b/packaging/RPM/ctdb.spec.in
@@ -4,7 +4,7 @@ Summary: Clustered TDB
 Vendor: Samba Team
 Packager: Samba Team <[email protected]>
 Version: 1.2.27
-Release: 202GITHASH
+Release: 204GITHASH
 Epoch: 0
 License: GNU GPL version 3
 Group: System Environment/Daemons
@@ -143,6 +143,14 @@ development libraries for ctdb
 %{_libdir}/libctdb.a
 
 %changelog
+* Fri Jul 29 2011 : Version 1.2.27-204
+ - ctdb delip updates.  CQ S1026664
+* Mon Jul 25 2011 : Version 1.2.27-203
+ - Fix a bug with the talloc hierarchy when running takeip/releaseip 
eventscripts
+   and talloc_free(vnn)-ing
+   S1026179
+ - Remove spam log messages from an eventscript
+   S1023378
 * Mon Jun 27 2011 : Version 1.2.27-202
  - Remove an annoying log message
    S1024495
diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c
index bed2ab9..bb9f05c 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -2875,12 +2875,16 @@ int32_t ctdb_control_del_public_address(struct 
ctdb_context *ctdb, TDB_DATA inda
                        TALLOC_CTX *mem_ctx;
 
                        DLIST_REMOVE(ctdb->vnn, vnn);
-                       if (vnn->iface == NULL) {
+                       if (vnn->iface != NULL) {
+                               ctdb_vnn_unassign_iface(ctdb, vnn);
+                       }
+                       if (vnn->pnn != ctdb->pnn) {
                                talloc_free(vnn);
                                return 0;
                        }
 
                        mem_ctx = talloc_new(ctdb);
+                       talloc_steal(mem_ctx, vnn);
                        ret = ctdb_event_script_callback(ctdb, 
                                         mem_ctx, delete_ip_callback, mem_ctx,
                                         false,
@@ -2889,8 +2893,6 @@ int32_t ctdb_control_del_public_address(struct 
ctdb_context *ctdb, TDB_DATA inda
                                         ctdb_vnn_iface_string(vnn),
                                         ctdb_addr_to_str(&vnn->public_address),
                                         vnn->public_netmask_bits);
-                       ctdb_vnn_unassign_iface(ctdb, vnn);
-                       talloc_free(vnn);
                        if (ret != 0) {
                                return -1;
                        }
diff --git a/server/eventscript.c b/server/eventscript.c
index dbe9598..3d1180d 100644
--- a/server/eventscript.c
+++ b/server/eventscript.c
@@ -39,13 +39,21 @@ static void sigterm(int sig)
        _exit(1);
 }
 
+/* This is attached to the event script state. */
+struct event_script_callback {
+       struct ctdb_event_script_state *state;
+
+       /* Warning: this can free us! */
+       void (*fn)(struct ctdb_context *, int, void *);
+       void *private_data;
+};
+       
+
 struct ctdb_event_script_state {
        struct ctdb_context *ctdb;
+       struct event_script_callback *callback;
        pid_t child;
-       /* Warning: this can free us! */
-       void (*callback)(struct ctdb_context *, int, void *);
        int fd[2];
-       void *private_data;
        bool from_user;
        enum ctdb_eventscript_call call;
        const char *options;
@@ -573,6 +581,7 @@ static void ctdb_event_script_timeout(struct event_context 
*ev, struct timed_eve
 static int event_script_destructor(struct ctdb_event_script_state *state)
 {
        int status;
+       struct event_script_callback *callback;
 
        if (state->child) {
                DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child 
pid:%d\n", state->child));
@@ -606,8 +615,13 @@ static int event_script_destructor(struct 
ctdb_event_script_state *state)
 
        /* This is allowed to free us; talloc will prevent double free anyway,
         * but beware if you call this outside the destructor! */
-       if (state->callback) {
-               state->callback(state->ctdb, status, state->private_data);
+       callback = state->callback;
+
+       if (callback) {
+               /* Make sure destructor doesn't free itself! */
+               talloc_steal(NULL, callback);
+               callback->fn(state->ctdb, status, callback->private_data);
+               talloc_free(callback);
        }
 
        return 0;
@@ -656,11 +670,19 @@ static bool check_options(enum ctdb_eventscript_call 
call, const char *options)
        }
 }
 
+static int remove_callback(struct event_script_callback *callback)
+{
+       /* Detach ourselves from the running script state */
+       callback->state->callback = NULL;
+       return 0;
+}
+
 /*
   run the event script in the background, calling the callback when 
   finished
  */
-static int ctdb_event_script_callback_v(struct ctdb_context *ctdb, 
+static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
+                                       const void *mem_ctx,
                                        void (*callback)(struct ctdb_context *, 
int, void *),
                                        void *private_data,
                                        bool from_user,
@@ -672,9 +694,15 @@ static int ctdb_event_script_callback_v(struct 
ctdb_context *ctdb,
        state = talloc(ctdb->event_script_ctx, struct ctdb_event_script_state);
        CTDB_NO_MEMORY(ctdb, state);
 
+       /* The callback isn't done if the context is freed. */
+       state->callback = talloc(mem_ctx, struct event_script_callback);
+       CTDB_NO_MEMORY(ctdb, state->callback);
+       talloc_set_destructor(state->callback, remove_callback);
+       state->callback->state = state;
+       state->callback->fn = callback;
+       state->callback->private_data = private_data;
+
        state->ctdb = ctdb;
-       state->callback = callback;
-       state->private_data = private_data;
        state->from_user = from_user;
        state->call = call;
        state->options = talloc_vasprintf(state, fmt, ap);
@@ -770,7 +798,7 @@ static int ctdb_event_script_callback_v(struct ctdb_context 
*ctdb,
 
 /*
   run the event script in the background, calling the callback when 
-  finished
+  finished.  If mem_ctx is freed, callback will never be called.
  */
 int ctdb_event_script_callback(struct ctdb_context *ctdb, 
                               TALLOC_CTX *mem_ctx,
@@ -784,7 +812,7 @@ int ctdb_event_script_callback(struct ctdb_context *ctdb,
        int ret;
 
        va_start(ap, fmt);
-       ret = ctdb_event_script_callback_v(ctdb, callback, private_data, 
from_user, call, fmt, ap);
+       ret = ctdb_event_script_callback_v(ctdb, mem_ctx, callback, 
private_data, from_user, call, fmt, ap);
        va_end(ap);
 
        return ret;
@@ -818,7 +846,7 @@ int ctdb_event_script_args(struct ctdb_context *ctdb, enum 
ctdb_eventscript_call
        struct callback_status status;
 
        va_start(ap, fmt);
-       ret = ctdb_event_script_callback_v(ctdb,
+       ret = ctdb_event_script_callback_v(ctdb, ctdb,
                        event_script_callback, &status, false, call, fmt, ap);
        if (ret != 0) {
                return ret;
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 674622a..652d24e 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -1827,6 +1827,13 @@ static int control_delip(struct ctdb_context *ctdb, int 
argc, const char **argv)
                return -1;
        }
 
+       ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", 
options.pnn));
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
        if (ips->ips[i].pnn == options.pnn) {
                ret = find_other_host_for_public_ip(ctdb, &addr);
                if (ret != -1) {
@@ -1840,18 +1847,11 @@ static int control_delip(struct ctdb_context *ctdb, int 
argc, const char **argv)
                        } while (retries < 5 && ret != 0);
                        if (ret != 0) {
                                DEBUG(DEBUG_ERR,("Failed to move ip to node %d. 
Giving up.\n", options.pnn));
-                               return -1;
+                               return 0;
                        }
                }
        }
 
-       ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
-       if (ret != 0) {
-               DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", 
options.pnn));
-               talloc_free(tmp_ctx);
-               return ret;
-       }
-
        talloc_free(tmp_ctx);
        return 0;
 }


-- 
CTDB repository

Reply via email to