all: fix race on activate_peer

This commit is contained in:
Thomas Schoebel-Theuer 2020-11-20 07:08:08 +01:00 committed by Thomas Schoebel-Theuer
parent feb0540224
commit 78376caa1a
4 changed files with 76 additions and 12 deletions

View File

@ -614,13 +614,12 @@ int handler_thread(void *data)
cmd.cmd_str2,
&cmd.cmd_stamp);
if (status >= 0) {
wait_main_round();
if (!strncmp(cmd.cmd_str2,
"/mars/ips/ip-", 13))
activate_peer(cmd.cmd_str2 + 13,
NULL,
NULL,
false);
launch_peer(cmd.cmd_str2 + 13,
NULL,
NULL,
false);
}
break;
}
@ -631,7 +630,7 @@ int handler_thread(void *data)
status = mars_stat(cmd.cmd_str2, &probe, true);
if (status < 0) {
invalidate_user_cache();
activate_peer(cmd.cmd_str1, NULL, NULL, true);
launch_peer(cmd.cmd_str1, NULL, NULL, true);
}
status = 0;
break;

View File

@ -3771,6 +3771,67 @@ int kill_any(struct mars_dent *dent)
return 1;
}
/*********************************************************************/
/* launching peer threads from external, e.g. /proc */
struct launch_info {
struct list_head launch_head;
const char *peer_name;
const char *peer_ip;
const char *rebase_dir;
bool oneshot;
};
static DECLARE_RWSEM(launch_lock);
static
struct list_head launch_anchor = LIST_HEAD_INIT(launch_anchor);
void launch_peer(const char *peer_name,
const char *peer_ip,
const char *rebase_dir,
bool oneshot)
{
struct launch_info *launch;
if (!mars_net_is_alive)
return;
launch = brick_zmem_alloc(sizeof(struct launch_info));
INIT_LIST_HEAD(&launch->launch_head);
launch->peer_name = brick_strdup(peer_name);
if (peer_ip)
launch->peer_ip = brick_strdup(peer_ip);
if (rebase_dir)
launch->rebase_dir = brick_strdup(rebase_dir);
launch->oneshot = oneshot;
down_write(&launch_lock);
list_add_tail(&launch->launch_head, &launch_anchor);
up_write(&launch_lock);
}
static
void launch_all(bool cleanup)
{
down_write(&launch_lock);
while (!list_empty(&launch_anchor)) {
struct launch_info *launch;
launch = container_of(launch_anchor.next, struct launch_info, launch_head);
list_del_init(&launch->launch_head);
if (!cleanup && mars_net_is_alive)
activate_peer(launch->peer_name,
launch->peer_ip,
launch->rebase_dir,
launch->oneshot);
brick_string_free(launch->peer_name);
brick_string_free(launch->peer_ip);
brick_string_free(launch->rebase_dir);
brick_mem_free(launch);
}
up_write(&launch_lock);
}
///////////////////////////////////////////////////////////////////////
// handlers / helpers for logfile rotation
@ -7345,6 +7406,7 @@ static int _main_thread(void *data)
/* main_round point */
main_round++;
wake_up_interruptible_all(&main_round_event);
launch_all(false);
brick_msleep(100);
@ -7391,6 +7453,8 @@ done:
brick_string_free(_tmp_oneshot_peer);
brick_string_free(oneshot_peer);
launch_all(true);
MARS_INF("-------- done status = %d ----------\n", status);
//cleanup_mm();
return status;

View File

@ -151,7 +151,7 @@ void interpret_user_message(char *msg)
count = sscanf(rest, "%s %s %s",
peer_name, peer_ip, rebase_dir);
if (count == 3) {
activate_peer(peer_name, peer_ip, rebase_dir, true);
launch_peer(peer_name, peer_ip, rebase_dir, true);
wait_main_round();
} else {
MARS_ERR("Bad fetch syntax '%s'\n", rest);

View File

@ -39,8 +39,9 @@
* 2 = push operation available
* 3 = new alivelinks residing in /mars/actual-$host
* 4 = new join-cluster and random peer threads
* 5 = fix race on peer thread creation
*/
#define OPTIONAL_STRATEGY_VERSION 4
#define OPTIONAL_STRATEGY_VERSION 5
/* transient, to re-disappear */
extern int compat_deletions;
@ -87,10 +88,10 @@ extern char *my_id(void);
extern const char *my_uuid;
extern void wait_main_round(void);
extern void activate_peer(const char *peer_name,
const char *peer_ip,
const char *rebase_dir,
bool oneshot);
extern void launch_peer(const char *peer_name,
const char *peer_ip,
const char *rebase_dir,
bool oneshot);
struct mars_dent;
typedef void (*dent_skip_fn)(struct mars_dent *);