Browse Source

Properly drop subclients when the parent dies by testing whether the parent exists instead of the masked subclient id.

master
Con Kolivas 8 years ago
parent
commit
7d8417774f
  1. 7
      src/ckpool.h
  2. 20
      src/connector.c
  3. 21
      src/stratifier.c

7
src/ckpool.h

@ -390,4 +390,11 @@ static inline json_t *json_encode_errormsg(json_error_t __maybe_unused *err_val)
static inline json_t *json_errormsg(const char __maybe_unused *fmt, ...) { return NULL; }; static inline json_t *json_errormsg(const char __maybe_unused *fmt, ...) { return NULL; };
static inline void send_api_response(json_t __maybe_unused *val, const int __maybe_unused sockd) {}; static inline void send_api_response(json_t __maybe_unused *val, const int __maybe_unused sockd) {};
/* Subclients have client_ids in the high bits. Returns the value of the parent
* client if one exists. */
static inline int64_t subclient(const int64_t client_id)
{
return (client_id >> 32);
}
#endif /* CKPOOL_H */ #endif /* CKPOOL_H */

20
src/connector.c

@ -958,6 +958,7 @@ static void send_client(ckpool_t *ckp, cdata_t *cdata, const int64_t id, char *b
sender_send_t *sender_send; sender_send_t *sender_send;
client_instance_t *client; client_instance_t *client;
bool redirect = false; bool redirect = false;
int64_t pass_id;
int len; int len;
if (unlikely(!buf)) { if (unlikely(!buf)) {
@ -980,11 +981,9 @@ static void send_client(ckpool_t *ckp, cdata_t *cdata, const int64_t id, char *b
/* Grab a reference to this client until the sender_send has /* Grab a reference to this client until the sender_send has
* completed processing. Is this a passthrough subclient ? */ * completed processing. Is this a passthrough subclient ? */
if (id > 0xffffffffll) { if ((pass_id = subclient(id))) {
int64_t client_id, pass_id; int64_t client_id = id & 0xffffffffll;
client_id = id & 0xffffffffll;
pass_id = id >> 32;
/* Make sure the passthrough exists for passthrough subclients */ /* Make sure the passthrough exists for passthrough subclients */
client = ref_client_by_id(cdata, pass_id); client = ref_client_by_id(cdata, pass_id);
if (unlikely(!client)) { if (unlikely(!client)) {
@ -1057,10 +1056,16 @@ static void send_client_json(ckpool_t *ckp, cdata_t *cdata, int64_t client_id, j
json_decref(json_msg); json_decref(json_msg);
} }
static bool client_exists(cdata_t *cdata, const int64_t id) /* When testing if a client exists, passthrough clients don't exist when their
* parent no longer exists. */
static bool client_exists(cdata_t *cdata, int64_t id)
{ {
int64_t parent_id = subclient(id);
client_instance_t *client; client_instance_t *client;
if (parent_id)
id = parent_id;
ck_rlock(&cdata->lock); ck_rlock(&cdata->lock);
HASH_FIND_I64(cdata->clients, &id, client); HASH_FIND_I64(cdata->clients, &id, client);
ck_runlock(&cdata->lock); ck_runlock(&cdata->lock);
@ -1300,7 +1305,7 @@ static void client_message_processor(ckpool_t *ckp, json_t *json_msg)
json_object_del(json_msg, "client_id"); json_object_del(json_msg, "client_id");
/* Put client_id back in for a passthrough subclient, passing its /* Put client_id back in for a passthrough subclient, passing its
* upstream client_id instead of the passthrough's. */ * upstream client_id instead of the passthrough's. */
if (client_id > 0xffffffffll) if (subclient(client_id))
json_object_set_new_nocheck(json_msg, "client_id", json_integer(client_id & 0xffffffffll)); json_object_set_new_nocheck(json_msg, "client_id", json_integer(client_id & 0xffffffffll));
/* Flag redirector clients once they've been authorised */ /* Flag redirector clients once they've been authorised */
@ -1455,7 +1460,7 @@ retry:
goto retry; goto retry;
} }
/* A passthrough client */ /* A passthrough client */
if (client_id > 0xffffffffll) { if (subclient(client_id)) {
drop_passthrough_client(ckp, cdata, client_id); drop_passthrough_client(ckp, cdata, client_id);
goto retry; goto retry;
} }
@ -1474,7 +1479,6 @@ retry:
LOGDEBUG("Connector failed to parse testclient command: %s", buf); LOGDEBUG("Connector failed to parse testclient command: %s", buf);
goto retry; goto retry;
} }
client_id &= 0xffffffffll;
if (client_exists(cdata, client_id)) if (client_exists(cdata, client_id))
goto retry; goto retry;
LOGINFO("Connector detected non-existent client id: %"PRId64, client_id); LOGINFO("Connector detected non-existent client id: %"PRId64, client_id);

21
src/stratifier.c

@ -1938,13 +1938,6 @@ share_diff(char *coinbase, const uchar *enonce1bin, const workbase_t *wb, const
return diff_from_target(hash); return diff_from_target(hash);
} }
/* Subclients have client_ids in the high bits. Returns the value of the parent
* client if one exists. */
static inline int64_t subclient(const int64_t client_id)
{
return (client_id >> 32);
}
/* Note recursive lock here - entered with workbase lock held, grabs instance lock */ /* Note recursive lock here - entered with workbase lock held, grabs instance lock */
static void send_node_block(sdata_t *sdata, const char *enonce1, const char *nonce, static void send_node_block(sdata_t *sdata, const char *enonce1, const char *nonce,
const char *nonce2, const uint32_t ntime32, const int64_t jobid, const char *nonce2, const uint32_t ntime32, const int64_t jobid,
@ -3160,18 +3153,6 @@ static void __drop_client(sdata_t *sdata, stratum_instance_t *client, bool lazil
} else if (unlikely(client->passthrough)) } else if (unlikely(client->passthrough))
parent = true; parent = true;
/* Tag any subclients of this parent to be dropped lazily */
if (parent) {
stratum_instance_t *tmp;
for (tmp = sdata->stratum_instances; tmp; tmp = tmp->hh.next) {
int64_t subid = subclient(tmp->id);
if (subid && subid == client->id)
tmp->dropped = true;
}
}
if (client->workername) { if (client->workername) {
if (user) { if (user) {
ASPRINTF(msg, "Dropped client %s %s %suser %s worker %s %s", ASPRINTF(msg, "Dropped client %s %s %suser %s worker %s %s",
@ -3183,7 +3164,7 @@ static void __drop_client(sdata_t *sdata, stratum_instance_t *client, bool lazil
lazily ? "lazily" : ""); lazily ? "lazily" : "");
} }
} else { } else {
ASPRINTF(msg, "Dropped workerless client %s %s %s", ASPRINTF(msg, "Dropped %sworkerless client %s %s %s", parent ? "parent " : "",
client->identity, client->address, lazily ? "lazily" : ""); client->identity, client->address, lazily ? "lazily" : "");
} }
__del_client(sdata, client); __del_client(sdata, client);

Loading…
Cancel
Save