infra: new push_check operation

This commit is contained in:
Thomas Schoebel-Theuer 2020-10-19 11:01:38 +02:00 committed by Thomas Schoebel-Theuer
parent a4a2034be5
commit d8e641a40e
5 changed files with 111 additions and 26 deletions

View File

@ -119,6 +119,7 @@ enum {
CMD_MREF,
CMD_CB,
CMD_PUSH_LINK,
CMD_PUSH_CHECK,
/* keep last element */
CMD_LAST
};

View File

@ -617,10 +617,22 @@ int handler_thread(void *data)
if (!strncmp(cmd.cmd_str2,
"/mars/ips/ip-", 13))
activate_peer(cmd.cmd_str2 + 13,
NULL,
false);
}
break;
}
case CMD_PUSH_CHECK:
{
struct kstat probe;
status = mars_stat(cmd.cmd_str2, &probe, true);
if (status < 0) {
activate_peer(cmd.cmd_str1, NULL, true);
}
status = 0;
break;
}
default:
MARS_ERR("#%d unknown command %d\n", sock->s_debug_nr, cmd.cmd_code);
}

View File

@ -2018,6 +2018,7 @@ struct push_info {
struct list_head push_head;
const char *src;
const char *dst;
int cmd_code;
};
static DECLARE_RWSEM(peer_list_lock);
@ -2028,6 +2029,7 @@ struct list_head peer_anchor = LIST_HEAD_INIT(peer_anchor);
struct mars_peerinfo {
struct mars_global *remote_global;
char *peer;
char *peer_ip;
char *peer_dir_list;
struct mars_socket socket;
struct task_struct *peer_thread;
@ -2067,16 +2069,19 @@ char *make_peer_dir_list(const char *mypeer)
}
static
struct mars_peerinfo *new_peer(const char *mypeer)
struct mars_peerinfo *new_peer(const char *peer_name, const char *peer_ip)
{
struct mars_peerinfo *peer;
peer = brick_zmem_alloc(sizeof(struct mars_peerinfo));
peer->peer = brick_strdup(mypeer);
peer->peer = brick_strdup(peer_name);
if (peer_ip)
peer->peer_ip = brick_strdup(peer_ip);
peer->peer_dir_list = make_peer_dir_list(peer_name);
peer->maxdepth = 2;
peer->peer_dir_list = make_peer_dir_list(mypeer);
peer->features_version = 0;
peer->strategy_version = 0;
peer->available_mask = 0;
@ -2202,14 +2207,11 @@ int start_peer(struct mars_peerinfo *peer)
static
void peer_destruct(void *_peer);
/* Please use this only for _initialization_ of new memberships etc,
* but never for ordinary operations.
* Normally, the PULL PRINCIPLE is the prefered one.
* TODO: more security considerations beyond port firewalling.
*/
bool push_link(const char *peer_name,
bool _push_info(const char *peer_name,
const char *peer_ip,
const char *src,
const char *dst)
const char *dst,
int cmd_code)
{
struct mars_dent *peer_dent;
struct mars_peerinfo *peer;
@ -2230,7 +2232,7 @@ bool push_link(const char *peer_name,
}
peer = peer_dent->d_private;
if (!peer) {
peer = new_peer(peer_name);
peer = new_peer(peer_name, peer_ip);
peer_dent->d_private = peer;
peer_dent->d_private_destruct = peer_destruct;
MARS_DBG("new peer %p\n", peer);
@ -2240,6 +2242,7 @@ bool push_link(const char *peer_name,
INIT_LIST_HEAD(&push->push_head);
push->src = brick_strdup(src);
push->dst = brick_strdup(dst);
push->cmd_code = cmd_code;
mutex_lock(&peer->peer_lock);
list_add_tail(&push->push_head, &peer->push_anchor);
mutex_unlock(&peer->peer_lock);
@ -2247,6 +2250,27 @@ bool push_link(const char *peer_name,
return true;
}
/* Please use this only for _initialization_ of new memberships etc,
* but never for ordinary operations.
* Normally, the PULL PRINCIPLE is the prefered one.
* TODO: more security considerations beyond port firewalling.
*/
bool push_link(const char *peer_name,
const char *src,
const char *dst)
{
return _push_info(peer_name, NULL,
src, dst, CMD_PUSH_LINK);
}
bool push_check(const char *peer_name,
const char *peer_ip,
const char *path)
{
return _push_info(peer_name, peer_ip,
my_id(), path, CMD_PUSH_CHECK);
}
static
bool _is_usable_dir(const char *name)
{
@ -3015,7 +3039,7 @@ int peer_thread(void *data)
struct push_info *push;
push = container_of(tmp_push_list.next, struct push_info, push_head);
cmd.cmd_code = CMD_PUSH_LINK;
cmd.cmd_code = push->cmd_code;
cmd.cmd_str1 = push->src;
cmd.cmd_str2 = push->dst;
status = mars_send_cmd(&peer->socket, &cmd, false);
@ -3231,6 +3255,7 @@ bool is_shutdown(void)
void _activate_peer(struct mars_dent *peer_dent,
const char *peer_name,
const char *peer_ip,
bool oneshot)
{
struct mars_peerinfo *peer;
@ -3240,7 +3265,7 @@ void _activate_peer(struct mars_dent *peer_dent,
peer = peer_dent->d_private;
if (!peer) {
peer = new_peer(peer_name);
peer = new_peer(peer_name, peer_ip);
if (oneshot) {
mars_running_additional_peers++;
peer->need_destruct = true;
@ -3253,6 +3278,12 @@ void _activate_peer(struct mars_dent *peer_dent,
peer->oneshot = oneshot;
peer->do_entire_once = oneshot;
peer->silent = oneshot;
} else if (oneshot && !peer->oneshot && !peer_ip) {
MARS_DBG("reuse existing peer %p '%s'\n",
peer, peer_name);
peer->do_entire_once = true;
peer->from_remote_trigger = true;
peer->to_remote_trigger = true;
} else if (peer->oneshot != oneshot) {
MARS_DBG("peer %p '%s' oneshot %d -> %d\n",
peer, peer_name,
@ -3265,7 +3296,7 @@ void _activate_peer(struct mars_dent *peer_dent,
start_peer(peer);
}
void activate_peer(const char *peer_name, bool oneshot)
void activate_peer(const char *peer_name, const char *peer_ip, bool oneshot)
{
struct mars_dent *peer_dent;
@ -3277,12 +3308,28 @@ void activate_peer(const char *peer_name, bool oneshot)
return;
peer_dent = find_peer_dent(peer_name);
/* When the IP is given, create a floating peer.
*/
if (peer_ip && !peer_dent) {
struct mars_peerinfo *peer;
peer = new_peer(peer_name, peer_ip);
MARS_DBG("new FLOATING peer %p '%s' '%s'\n",
peer, peer_name, peer_ip);
mars_running_additional_peers++;
peer->need_destruct = true;
peer->oneshot = true;
peer->do_entire_once = true;
peer->silent = true;
start_peer(peer);
return;
}
if (unlikely(!peer_dent)) {
MARS_ERR("peer '%s' does not exist in /mars/ips/\n",
peer_name);
return;
}
_activate_peer(peer_dent, peer_name, oneshot);
_activate_peer(peer_dent, peer_name, peer_ip, oneshot);
}
static int _kill_peer(struct mars_peerinfo *peer)
@ -3382,12 +3429,12 @@ int _make_peer(struct mars_dent *dent)
*/
if (oneshot_code < 0)
return 0;
_activate_peer(dent, mypeer, oneshot_code > 0);
_activate_peer(dent, mypeer, NULL, oneshot_code > 0);
peer = dent->d_private;
if (unlikely(!peer))
return 0;
} else if (oneshot_code > 0) {
_activate_peer(dent, mypeer, true);
_activate_peer(dent, mypeer, NULL, true);
}
if (tmp_full_fetch) {
@ -3483,7 +3530,7 @@ static int make_scan(struct mars_dent *dent)
MARS_DBG("HACK status=%d peer=%p\n", status, peer);
if (!peer) {
activate_peer(dent->d_rest, false);
activate_peer(dent->d_rest, NULL, false);
} else {
const char *dst;
const char *src;
@ -3898,7 +3945,7 @@ int make_log_init(struct mars_dent *dent)
rot->has_error = false;
brick_string_free(rot->preferred_peer);
activate_peer(dent->d_rest, false);
activate_peer(dent->d_rest, NULL, false);
if (dent->new_link)
sscanf(dent->new_link, "%lld", &rot->dev_size);
@ -5315,7 +5362,7 @@ int make_bio(struct mars_dent *dent)
_show_actual(rot->parent_path, "is-attached", rot->is_attached);
if (rot->rot_activated)
activate_peer(dent->d_rest, false);
activate_peer(dent->d_rest, NULL, false);
if (strcmp(dent->d_rest, my_id()))
goto done;
@ -5468,7 +5515,7 @@ int make_dev(struct mars_dent *dent)
MARS_DBG("no rot '%s'\n", dent->d_rest);
goto err;
}
activate_peer(dent->d_rest, false);
activate_peer(dent->d_rest, NULL, false);
if (strcmp(dent->d_rest, my_id())) {
MARS_DBG("nothing to do\n");
goto err;

View File

@ -91,7 +91,7 @@ void interpret_user_message(char *msg)
if (count == 3) {
push_link(peer_name, src, dst);
} else {
MARS_ERR("Bad link syntax '%s'\n", rest);
MARS_ERR("Bad push link syntax '%s'\n", rest);
}
brick_string_free(peer_name);
brick_string_free(src);
@ -99,6 +99,26 @@ void interpret_user_message(char *msg)
break;
}
case 'c': /* check target path + fetch when nececessary (best effort) */
{
char *peer_name = brick_strdup(rest);
char *peer_ip = brick_strdup(rest);
char *path = brick_strdup(rest);
int count;
count = sscanf(rest, "%s %s %s",
peer_name, peer_ip, path);
if (count == 3) {
push_check(peer_name, peer_ip, path);
} else {
MARS_ERR("Bad check link syntax '%s'\n", rest);
}
brick_string_free(peer_name);
brick_string_free(peer_ip);
brick_string_free(path);
break;
}
case 't': /* new trigger code conventions */
{
int code = 0;

View File

@ -76,7 +76,9 @@ extern char *my_id(void);
extern const char *my_uuid;
extern void wait_main_round(void);
extern void activate_peer(const char *peer_name, bool oneshot);
extern void activate_peer(const char *peer_name,
const char *peer_ip,
bool oneshot);
struct mars_dent;
typedef void (*dent_skip_fn)(struct mars_dent *);
@ -280,6 +282,9 @@ bool is_deleted_link(const char *str)
bool push_link(const char *peer_name,
const char *src,
const char *dst);
bool push_check(const char *peer_name,
const char *peer_ip,
const char *path);
/* General fs wrappers (for abstraction)
*/