]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_corosync: Change thread stack size
authorJan Friesse <jfriesse@redhat.com>
Thu, 30 Mar 2017 14:33:51 +0000 (16:33 +0200)
committerJan Friesse <jfriesse@redhat.com>
Fri, 16 Jun 2017 12:44:34 +0000 (14:44 +0200)
In Corosync 2.x libraries were changed to use LibQB IPC.
Sadly LibQB IPC doesn't support copy-free access to received buffer, so
Corosync libraries were rewritten to use stack as buffer. Mostly the
needed stack size is quite small, but for all *_dispatch functions, 1MiB
is needed.

Asterisk function ast_pthread_create_background set stack size for new
thread to much smaller AST_BACKGROUND_STACKSIZE (~500KiB).

This results in Asterisk crash when running with Corosync 2.x.

Patch solves this issue by creating it's own version of
ast_pthread_create_background which sets stack size to much higher value
(actually it's AST_BACKGROUND_STACKSIZE + 3MiB).

Another problem may appear when "corosync show members" netconsole
command is executed. It is also executed in thread and also has only
500KiB stack size. Sadly it calls corosync_cfg_get_node_addrs which
again needs at least 1MiB stack.

Solution is to use HAVE_COROSYNC_CFG_STATE_TRACK as a discriminator
between Corosync 1.x and 2.x. If 1.x is found, nothing changes. If 2.x
is found, NodeID is displayed instead of IP address.

ASTERISK-25370 #close
Reported by: mdu113

Change-Id: Id95b0d21ab6e708e7d74ad8786c587211676fa08

res/res_corosync.c

index 6bbbc34b97b050386fdd090e5e21d3b98f0cd4b7..ce94e4151f05ce2691a7e8a1d95a97590d2f8c10 100644 (file)
@@ -79,6 +79,15 @@ struct corosync_node {
        struct ast_sockaddr addr;
 };
 
+/*! \brief Corosync ipc dispatch/request and reply size */
+#define COROSYNC_IPC_BUFFER_SIZE                               (8192 * 128)
+
+/*! \brief Version of pthread_create to ensure stack is large enough */
+#define corosync_pthread_create_background(a, b, c, d)                         \
+       ast_pthread_create_stack(a, b, c, d,                                    \
+               (AST_BACKGROUND_STACKSIZE + (3 * COROSYNC_IPC_BUFFER_SIZE)),    \
+               __FILE__, __FUNCTION__, __LINE__, #c)
+
 static struct corosync_node *corosync_node_alloc(struct ast_event *event)
 {
        struct corosync_node *node;
@@ -810,10 +819,21 @@ static char *corosync_show_members(struct ast_cli_entry *e, int cmd, struct ast_
        for (i = 1, cs_err = cpg_iteration_next(cpg_iter, &cpg_desc);
                        cs_err == CS_OK;
                        cs_err = cpg_iteration_next(cpg_iter, &cpg_desc), i++) {
+#ifdef HAVE_COROSYNC_CFG_STATE_TRACK
                corosync_cfg_node_address_t addrs[8];
                int num_addrs = 0;
                unsigned int j;
+#endif
+
+               ast_cli(a->fd, "=== Node %u\n", i);
+               ast_cli(a->fd, "=== --> Group: %s\n", cpg_desc.group.value);
 
+#ifdef HAVE_COROSYNC_CFG_STATE_TRACK
+               /*
+                * Corosync 2.x cfg lib needs to allocate 1M on stack after calling
+                * corosync_cfg_get_node_addrs. netconsole thread has allocated only 0.5M
+                * resulting in crash.
+                */
                cs_err = corosync_cfg_get_node_addrs(cfg_handle, cpg_desc.nodeid,
                                ARRAY_LEN(addrs), &num_addrs, addrs);
                if (cs_err != CS_OK) {
@@ -821,9 +841,6 @@ static char *corosync_show_members(struct ast_cli_entry *e, int cmd, struct ast_
                        continue;
                }
 
-               ast_cli(a->fd, "=== Node %u\n", i);
-               ast_cli(a->fd, "=== --> Group: %s\n", cpg_desc.group.value);
-
                for (j = 0; j < num_addrs; j++) {
                        struct sockaddr *sa = (struct sockaddr *) addrs[j].address;
                        size_t sa_len = (size_t) addrs[j].address_length;
@@ -833,7 +850,9 @@ static char *corosync_show_members(struct ast_cli_entry *e, int cmd, struct ast_
 
                        ast_cli(a->fd, "=== --> Address %u: %s\n", j + 1, buf);
                }
-
+#else
+               ast_cli(a->fd, "=== --> Nodeid: %"PRIu32"\n", cpg_desc.nodeid);
+#endif
        }
 
        ast_cli(a->fd, "===\n"
@@ -1159,7 +1178,7 @@ static int load_module(void)
                goto failed;
        }
 
-       if (ast_pthread_create_background(&dispatch_thread.id, NULL,
+       if (corosync_pthread_create_background(&dispatch_thread.id, NULL,
                        dispatch_thread_handler, NULL)) {
                ast_log(LOG_ERROR, "Error starting CPG dispatch thread.\n");
                goto failed;