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

Merge commit 'origin/master'

(This used to be ctdb commit 19523fbb12db1ec1e5ee38de1b2d3b99a74c6ca4)
This commit is contained in:
Martin Schwenke 2010-02-10 20:24:28 +11:00
commit d25ab9eca0
4 changed files with 133 additions and 94 deletions

View File

@ -194,8 +194,7 @@ static void queue_io_write(struct ctdb_queue *queue)
if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
if (pkt->length != pkt->full_length) {
/* partial packet sent - we have to drop it */
TLIST_REMOVE(queue->out_queue, queue->out_queue_tail,
pkt);
DLIST_REMOVE(queue->out_queue, pkt);
queue->out_queue_length--;
talloc_free(pkt);
}
@ -214,7 +213,7 @@ static void queue_io_write(struct ctdb_queue *queue)
return;
}
TLIST_REMOVE(queue->out_queue, queue->out_queue_tail, pkt);
DLIST_REMOVE(queue->out_queue, pkt);
queue->out_queue_length--;
talloc_free(pkt);
}
@ -295,7 +294,7 @@ int ctdb_queue_send(struct ctdb_queue *queue, uint8_t *data, uint32_t length)
EVENT_FD_WRITEABLE(queue->fde);
}
TLIST_ADD_END(queue->out_queue, queue->out_queue_tail, pkt);
DLIST_ADD_END(queue->out_queue, pkt, NULL);
queue->out_queue_length++;

View File

@ -29,11 +29,21 @@ case "$1" in
;;
monitor)
# We should never enter swap, so SwapTotal == SwapFree.
if [ -n "`grep '^Swap\(Total\|Free\)' /proc/meminfo | uniq -s 10 -u`" ]; then
echo We are swapping:
cat /proc/meminfo
ps auxfww
fi
# monitor that we are not running out of memory
[ -z "$CTDB_MONITOR_FREE_MEMORY" ] || {
FREE_MEM=`free -m | grep "buffers/cache" | while read A B C D ;do /bin/echo -n $D ; done`
[ `expr "$FREE_MEM" "<" "$CTDB_MONITOR_FREE_MEMORY"` != "0" ] && {
echo "OOM. Free:$FREE_MEM while CTDB treshold is $CTDB_MONITOR_FREE_MEMORY"
cat /proc/meminfo
ps auxfww
echo m > /proc/sysrq-trigger
ctdb disable
sleep 3
ctdb shutdown

View File

@ -1,7 +1,8 @@
/*
Unix SMB/CIFS implementation.
some simple double linked list macros
Copyright (C) Andrew Tridgell 1998
Copyright (C) Andrew Tridgell 1998-2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -14,7 +15,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* To use these macros you must have a structure containing a next and
@ -23,55 +24,94 @@
#ifndef _DLINKLIST_H
#define _DLINKLIST_H
/*
February 2010 - changed list format to have a prev pointer from the
list head. This makes DLIST_ADD_END() O(1) even though we only have
one list pointer.
/* hook into the front of the list */
The scheme is as follows:
1) with no entries in the list:
list_head == NULL
2) with 1 entry in the list:
list_head->next == NULL
list_head->prev == list_head
3) with 2 entries in the list:
list_head->next == element2
list_head->prev == element2
element2->prev == list_head
element2->next == NULL
4) with N entries in the list:
list_head->next == element2
list_head->prev == elementN
elementN->prev == element{N-1}
elementN->next == NULL
This allows us to find the tail of the list by using
list_head->prev, which means we can add to the end of the list in
O(1) time
Note that the 'type' arguments below are no longer needed, but
are kept for now to prevent an incompatible argument change
*/
/*
add an element at the front of a list
*/
#define DLIST_ADD(list, p) \
do { \
if (!(list)) { \
(list) = (p); \
(p)->next = (p)->prev = NULL; \
(p)->prev = (list) = (p); \
(p)->next = NULL; \
} else { \
(p)->prev = (list)->prev; \
(list)->prev = (p); \
(p)->next = (list); \
(p)->prev = NULL; \
(list) = (p); \
}\
} \
} while (0)
/* remove an element from a list - element doesn't have to be in list. */
/*
remove an element from a list
Note that the element doesn't have to be in the list. If it
isn't then this is a no-op
*/
#define DLIST_REMOVE(list, p) \
do { \
if ((p) == (list)) { \
if ((p)->next) (p)->next->prev = (p)->prev; \
(list) = (p)->next; \
if (list) (list)->prev = NULL; \
} else if ((list) && (p) == (list)->prev) { \
(p)->prev->next = NULL; \
(list)->prev = (p)->prev; \
} else { \
if ((p)->prev) (p)->prev->next = (p)->next; \
if ((p)->next) (p)->next->prev = (p)->prev; \
} \
if ((p) != (list)) (p)->next = (p)->prev = NULL; \
if ((p) != (list)) (p)->next = (p)->prev = NULL; \
} while (0)
/* promote an element to the top of the list */
#define DLIST_PROMOTE(list, p) \
/*
find the head of the list given any element in it.
Note that this costs O(N), so you should avoid this macro
if at all possible!
*/
#define DLIST_HEAD(p, result_head) \
do { \
DLIST_REMOVE(list, p); \
DLIST_ADD(list, p); \
} while (0)
(result_head) = (p); \
while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \
} while(0)
/* hook into the end of the list - needs a tmp pointer */
#define DLIST_ADD_END(list, p, type) \
do { \
if (!(list)) { \
(list) = (p); \
(p)->next = (p)->prev = NULL; \
} else { \
type tmp; \
for (tmp = (list); tmp->next; tmp = tmp->next) ; \
tmp->next = (p); \
(p)->next = NULL; \
(p)->prev = tmp; \
} \
} while (0)
/* return the last element in the list */
#define DLIST_TAIL(list) ((list)?(list)->prev:NULL)
/* return the previous element in the list. */
#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL)
/* insert 'p' after the given element 'el' in a list. If el is NULL then
this is the same as a DLIST_ADD() */
@ -80,80 +120,62 @@ do { \
if (!(list) || !(el)) { \
DLIST_ADD(list, p); \
} else { \
p->prev = el; \
p->next = el->next; \
el->next = p; \
if (p->next) p->next->prev = p; \
(p)->prev = (el); \
(p)->next = (el)->next; \
(el)->next = (p); \
if ((p)->next) (p)->next->prev = (p); \
if ((list)->prev == (el)) (list)->prev = (p); \
}\
} while (0)
/* demote an element to the end of the list, needs a tmp pointer */
#define DLIST_DEMOTE(list, p, tmp) \
/*
add to the end of a list.
Note that 'type' is ignored
*/
#define DLIST_ADD_END(list, p, type) \
do { \
DLIST_REMOVE(list, p); \
DLIST_ADD_END(list, p, tmp); \
if (!(list)) { \
DLIST_ADD(list, p); \
} else { \
DLIST_ADD_AFTER(list, p, (list)->prev); \
} \
} while (0)
/* concatenate two lists - putting all elements of the 2nd list at the
end of the first list */
#define DLIST_CONCATENATE(list1, list2, type) \
/* promote an element to the from of a list */
#define DLIST_PROMOTE(list, p) \
do { \
if (!(list1)) { \
(list1) = (list2); \
} else { \
type tmp; \
for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
tmp->next = (list2); \
if (list2) { \
(list2)->prev = tmp; \
} \
} \
DLIST_REMOVE(list, p); \
DLIST_ADD(list, p); \
} while (0)
/*
The TLIST_*() macros are meant for when you have two list pointers,
one pointing at the head of the list and one pointing at the tail
of the list. This makes the common case of adding to the end of the
list and removing from the front of the list efficient
TLIST stands for "tailed list"
Note: When initialising the structure containing your lists, make
sure that you set both head and tail to NULL
Also, do not mix the TLIST_*() macros with the DLIST_* macros!
demote an element to the end of a list.
Note that 'type' is ignored
*/
/* TLIST_ADD_FRONT adds elements to the front of the list. */
#define TLIST_ADD_FRONT(listhead, listtail, p) \
#define DLIST_DEMOTE(list, p, type) \
do { \
DLIST_ADD(listhead, p); \
if (NULL == (listtail)) { \
(listtail) = (p); \
} \
DLIST_REMOVE(list, p); \
DLIST_ADD_END(list, p, NULL); \
} while (0)
/* TLIST_ADD_END adds elements to the end of the list. */
#define TLIST_ADD_END(listhead, listtail, p) \
/*
concatenate two lists - putting all elements of the 2nd list at the
end of the first list.
Note that 'type' is ignored
*/
#define DLIST_CONCATENATE(list1, list2, type) \
do { \
if ((listtail) == NULL) { \
DLIST_ADD(listhead, p); \
(listtail) = (listhead); \
if (!(list1)) { \
(list1) = (list2); \
} else { \
(listtail)->next = (p); \
(p)->prev = (listtail); \
(p)->next = NULL; \
(listtail) = (p); \
(list1)->prev->next = (list2); \
if (list2) { \
void *_tmplist = (void *)(list1)->prev; \
(list1)->prev = (list2)->prev; \
(list2)->prev = _tmplist; \
} \
} \
} while (0)
/* TLIST_REMOVE removes an element from the list */
#define TLIST_REMOVE(listhead, listtail, p) \
do { \
if ((p) == (listtail)) { \
(listtail) = (p)->prev; \
} \
DLIST_REMOVE(listhead, p); \
} while (0)
#endif /* _DLINKLIST_H */

View File

@ -45,6 +45,7 @@ static struct {
} options;
#define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
#define LONGTIMELIMIT() timeval_current_ofs(options.timelimit*10, 0)
#ifdef CTDB_VERS
static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
@ -996,7 +997,6 @@ static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char *
}
static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
{
struct ctdb_all_public_ips *ips;
@ -1055,7 +1055,7 @@ static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn
nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
nodes, 0,
TIMELIMIT(),
LONGTIMELIMIT(),
false, data,
NULL, NULL,
NULL);
@ -1065,7 +1065,7 @@ static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn
return -1;
}
ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
ret = ctdb_ctrl_takeover_ip(ctdb, LONGTIMELIMIT(), pnn, &ip);
if (ret != 0) {
DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
talloc_free(tmp_ctx);
@ -1939,13 +1939,15 @@ static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv
return 0;
}
static uint32_t ipreallocate_finished;
/*
handler for receiving the response to ipreallocate
*/
static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
TDB_DATA data, void *private_data)
{
exit(0);
ipreallocate_finished = 1;
}
static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
@ -2056,6 +2058,7 @@ again:
goto again;
}
ipreallocate_finished = 0;
ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
if (ret != 0) {
DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
@ -2067,6 +2070,9 @@ again:
while (timeval_elapsed(&tv) < 3.0) {
event_loop_once(ctdb->ev);
}
if (ipreallocate_finished == 1) {
return 0;
}
DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
retries++;
@ -2129,6 +2135,7 @@ static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv
struct ctdb_node_map *nodemap=NULL;
/* check if the node is already enabled */
if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
@ -2155,6 +2162,7 @@ static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv
}
} while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
ret = control_ipreallocate(ctdb, argc, argv);
if (ret != 0) {
DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));