diff --git a/src/ckpool.c b/src/ckpool.c index 52275a6c..46cddf6a 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -276,6 +276,7 @@ static void parse_config(ckpool_t *ckp) json_get_string(&ckp->serverurl, json_conf, "serverurl"); json_get_int(&ckp->mindiff, json_conf, "mindiff"); json_get_int(&ckp->startdiff, json_conf, "startdiff"); + json_get_string(&ckp->logdir, json_conf, "logdir"); json_decref(json_conf); } @@ -432,6 +433,15 @@ int main(int argc, char **argv) ckp.mindiff = 1; if (!ckp.startdiff) ckp.startdiff = 42; + if (!ckp.logdir) + ckp.logdir = strdup("logs"); + + len = strlen(ckp.logdir); + if (memcmp(&ckp.logdir[len], "/", 1)) + realloc_strcat(&ckp.logdir, "/"); + ret = mkdir(ckp.logdir, 0700); + if (ret && errno != EEXIST) + quit(1, "Failed to make log directory %s", ckp.logdir); ckp.main.ckp = &ckp; ckp.main.processname = strdup("main"); diff --git a/src/ckpool.h b/src/ckpool.h index 327e63eb..bd650828 100644 --- a/src/ckpool.h +++ b/src/ckpool.h @@ -37,6 +37,8 @@ struct ckpool_instance { char *name; /* Directory where sockets are created */ char *socket_dir; + /* Directory where logs are written */ + char *logdir; /* Process instance data of parent/child processes */ proc_instance_t main; diff --git a/src/stratifier.c b/src/stratifier.c index 9b38e976..6f50b611 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -123,6 +123,8 @@ struct workbase { /* Cached header binary */ char headerbin[112]; + + char *logdir; }; typedef struct workbase workbase_t; @@ -344,6 +346,7 @@ static void clear_workbase(workbase_t *wb) { free(wb->flags); free(wb->txn_data); + free(wb->logdir); json_decref(wb->merkle_array); free(wb); } @@ -374,6 +377,7 @@ static void update_base(ckpool_t *ckp) { workbase_t *wb, *tmp, *tmpa; bool new_block = false; + int len, ret; json_t *val; char *buf; @@ -423,14 +427,29 @@ static void update_base(ckpool_t *ckp) generate_coinbase(ckp, wb); wb->gentime = time(NULL); + len = strlen(ckp->logdir) + 8 + 1 + 16; + wb->logdir = ckalloc(len); + ck_wlock(&workbase_lock); wb->id = workbase_id++; + if (strncmp(wb->prevhash, lasthash, 64)) { new_block = true; memcpy(lasthash, wb->prevhash, 65); blockchange_id = wb->id; } + if (new_block) { + sprintf(wb->logdir, "%s%08x/", ckp->logdir, wb->height); + ret = mkdir(wb->logdir, 0700); + if (unlikely(ret && errno != EEXIST)) + quit(1, "Failed to create log directory %s", wb->logdir); + } sprintf(wb->idstring, "%016lx", wb->id); + /* Do not store the trailing slash for the subdir */ + sprintf(wb->logdir, "%s%08x/%s", ckp->logdir, wb->height, wb->idstring); + ret = mkdir(wb->logdir, 0700); + if (unlikely(ret && errno != EEXIST)) + quit(1, "Failed to create log directory %s", wb->logdir); HASH_ITER(hh, workbases, tmp, tmpa) { if (HASH_COUNT(workbases) < 3) break; @@ -917,8 +936,9 @@ static void add_submit(stratum_instance_t *client, int diff, bool valid) stratum_send_diff(client); } -static void add_submit_success(stratum_instance_t *client, char *idstring, - const char *nonce2, uint32_t ntime, int diff, +static void add_submit_success(stratum_instance_t *client, const char *logdir, + const char *idstring, const char *nonce2, + const uint32_t ntime, const int diff, double sdiff, const char *hash) { char *fname, *s; @@ -930,9 +950,11 @@ static void add_submit_success(stratum_instance_t *client, char *idstring, tv_time(&client->first_share); client->diff_shares += diff; add_submit(client, diff, true); - len = strlen(client->workername) + 10; + len = strlen(logdir) + strlen(client->workername) + 12; fname = alloca(len); - sprintf(fname, "%s.sharelog", client->workername); + + /* First write to the user's sharelog */ + sprintf(fname, "%s/%s.sharelog", logdir, client->workername); fp = fopen(fname, "a"); if (unlikely(!fp < 0)) { LOGERR("Failed to fopen %s", fname); @@ -947,13 +969,30 @@ static void add_submit_success(stratum_instance_t *client, char *idstring, json_set_double(val, "sdiff", sdiff); json_set_string(val, "hash", hash); s = json_dumps(val, 0); - json_decref(val); len = strlen(s); len = fprintf(fp, "%s\n", s); free(s); fclose(fp); if (unlikely(len < 0)) LOGERR("Failed to fwrite to %s", fname); + + /* Now write to the pool's sharelog, adding workername to json */ + sprintf(fname, "%s.sharelog", logdir); + fp = fopen(fname, "a"); + if (unlikely(!fp < 0)) { + LOGERR("Failed to fopen %s", fname); + return; + } + json_set_string(val, "worker", client->workername); + s = json_dumps(val, 0); + len = strlen(s); + len = fprintf(fp, "%s\n", s); + free(s); + fclose(fp); + if (unlikely(len < 0)) + LOGERR("Failed to fwrite to %s", fname); + + json_decref(val); } static void add_submit_fail(stratum_instance_t *client, int diff, bool share) @@ -1088,7 +1127,7 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, json_t *params_val, json_t **err_val) { const char *user, *job_id, *nonce2, *ntime, *nonce; - char hexhash[68], sharehash[32]; + char hexhash[68], sharehash[32], *logdir; bool share = false, ret = false; uint64_t wb_id = 0, id; double sdiff = -1; @@ -1164,6 +1203,7 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, sdiff = submission_diff(client, wb, nonce2, ntime32, nonce, hash); wb_id = wb->id; strcpy(idstring, wb->idstring); + logdir = strdupa(wb->logdir); out_unlock: ck_runlock(&workbase_lock); @@ -1177,7 +1217,7 @@ out_unlock: __bin2hex(hexhash, sharehash, 32); if (new_share(hash, wb_id)) { LOGINFO("Accepted client %d share diff %.1f/%d: %s", client->id, sdiff, diff, hexhash); - add_submit_success(client, idstring, nonce2, ntime32, diff, sdiff, hexhash); + add_submit_success(client, logdir, idstring, nonce2, ntime32, diff, sdiff, hexhash); ret = true; } else { add_submit_fail(client, diff, share);