From 3047ee5c8fe36e25449595066e547a5fe80d84a2 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Feb 2015 20:18:42 +1100 Subject: [PATCH 1/3] Use the more generic ckmsg_t for the json_lists --- src/stratifier.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 859edc6e..7c0ab397 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -366,14 +366,6 @@ struct stratifier_data { typedef struct stratifier_data sdata_t; -typedef struct json_entry json_entry_t; - -struct json_entry { - json_entry_t *next; - json_entry_t *prev; - json_t *val; -}; - /* Priority levels for generator messages */ #define GEN_LAX 0 #define GEN_NORMAL 1 @@ -3860,7 +3852,7 @@ out: * avoid floods of stat data coming at once. */ static void update_workerstats(ckpool_t *ckp, sdata_t *sdata) { - json_entry_t *json_list = NULL, *entry, *tmpentry; + ckmsg_t *json_list = NULL, *entry, *tmpentry; user_instance_t *user, *tmp; char cdfield[64]; time_t now_t; @@ -3921,8 +3913,8 @@ static void update_workerstats(ckpool_t *ckp, sdata_t *sdata) "createcode", __func__, "createinet", ckp->serverurl[0]); worker->notified_idle = worker->idle; - entry = ckalloc(sizeof(json_entry_t)); - entry->val = val; + entry = ckalloc(sizeof(ckmsg_t)); + entry->data = val; DL_APPEND(json_list, entry); } } @@ -3930,7 +3922,7 @@ static void update_workerstats(ckpool_t *ckp, sdata_t *sdata) /* Add all entries outside of the instance lock */ DL_FOREACH_SAFE(json_list, entry, tmpentry) { - ckdbq_add(ckp, ID_WORKERSTATS, entry->val); + ckdbq_add(ckp, ID_WORKERSTATS, (json_t *)entry->data); DL_DELETE(json_list, entry); free(entry); } From ca5c7da81b01d6cc77494756034c9db42a70b16c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Feb 2015 20:39:00 +1100 Subject: [PATCH 2/3] Provide helper functions for storing log text and their associated filenames to be written to in unlocked code --- src/ckpool.h | 9 +++++++++ src/stratifier.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/ckpool.h b/src/ckpool.h index 771ac692..86b8ff3f 100644 --- a/src/ckpool.h +++ b/src/ckpool.h @@ -73,6 +73,15 @@ struct char_entry { char *buf; }; +typedef struct log_entry log_entry_t; + +struct log_entry { + log_entry_t *next; + log_entry_t *prev; + char *fname; + char *buf; +}; + struct server_instance { /* Hash table data */ UT_hash_handle hh; diff --git a/src/stratifier.c b/src/stratifier.c index 7c0ab397..be512f82 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -366,6 +366,14 @@ struct stratifier_data { typedef struct stratifier_data sdata_t; +typedef struct json_entry json_entry_t; + +struct json_entry { + json_entry_t *next; + json_entry_t *prev; + json_t *val; +}; + /* Priority levels for generator messages */ #define GEN_LAX 0 #define GEN_NORMAL 1 @@ -3852,7 +3860,7 @@ out: * avoid floods of stat data coming at once. */ static void update_workerstats(ckpool_t *ckp, sdata_t *sdata) { - ckmsg_t *json_list = NULL, *entry, *tmpentry; + json_entry_t *json_list = NULL, *entry, *tmpentry; user_instance_t *user, *tmp; char cdfield[64]; time_t now_t; @@ -3913,8 +3921,8 @@ static void update_workerstats(ckpool_t *ckp, sdata_t *sdata) "createcode", __func__, "createinet", ckp->serverurl[0]); worker->notified_idle = worker->idle; - entry = ckalloc(sizeof(ckmsg_t)); - entry->data = val; + entry = ckalloc(sizeof(json_entry_t)); + entry->val = val; DL_APPEND(json_list, entry); } } @@ -3922,12 +3930,42 @@ static void update_workerstats(ckpool_t *ckp, sdata_t *sdata) /* Add all entries outside of the instance lock */ DL_FOREACH_SAFE(json_list, entry, tmpentry) { - ckdbq_add(ckp, ID_WORKERSTATS, (json_t *)entry->data); + ckdbq_add(ckp, ID_WORKERSTATS, entry->val); DL_DELETE(json_list, entry); free(entry); } } +static void add_log_entry(log_entry_t *entries, char **fname, char **buf) +{ + log_entry_t *entry = ckalloc(sizeof(log_entry_t)); + + entry->fname = *fname; + *fname = NULL; + entry->buf = *buf; + *buf = NULL; + DL_APPEND(entries, entry); +} + +static void dump_log_entries(log_entry_t *entries) +{ + log_entry_t *entry, *tmpentry; + FILE *fp; + + DL_FOREACH_SAFE(entries, entry, tmpentry) { + DL_DELETE(entries, entry); + fp = fopen(entry->fname, "we"); + if (likely(!fp)) { + fprintf(fp, "%s", entry->buf); + fclose(fp); + } else + LOGERR("Failed to fopen %s in dump_log_entries", entry->fname); + free(entry->fname); + free(entry->buf); + free(entry); + } +} + static void *statsupdate(void *arg) { ckpool_t *ckp = (ckpool_t *)arg; From 1b077f2a051bb071dd944d0a92a91230cb41b74c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Feb 2015 21:09:31 +1100 Subject: [PATCH 3/3] Log to files outside of instance lock --- src/stratifier.c | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index be512f82..97fb1083 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -3936,7 +3936,7 @@ static void update_workerstats(ckpool_t *ckp, sdata_t *sdata) } } -static void add_log_entry(log_entry_t *entries, char **fname, char **buf) +static void add_log_entry(log_entry_t **entries, char **fname, char **buf) { log_entry_t *entry = ckalloc(sizeof(log_entry_t)); @@ -3944,18 +3944,18 @@ static void add_log_entry(log_entry_t *entries, char **fname, char **buf) *fname = NULL; entry->buf = *buf; *buf = NULL; - DL_APPEND(entries, entry); + DL_APPEND(*entries, entry); } -static void dump_log_entries(log_entry_t *entries) +static void dump_log_entries(log_entry_t **entries) { log_entry_t *entry, *tmpentry; FILE *fp; - DL_FOREACH_SAFE(entries, entry, tmpentry) { - DL_DELETE(entries, entry); + DL_FOREACH_SAFE(*entries, entry, tmpentry) { + DL_DELETE(*entries, entry); fp = fopen(entry->fname, "we"); - if (likely(!fp)) { + if (likely(fp)) { fprintf(fp, "%s", entry->buf); fclose(fp); } else @@ -3985,14 +3985,14 @@ static void *statsupdate(void *arg) char suffix360[16], suffix1440[16], suffix10080[16]; char_entry_t *char_list = NULL, *char_t, *chartmp_t; stratum_instance_t *client, *tmp; + log_entry_t *log_entries = NULL; user_instance_t *user, *tmpuser; int idle_workers = 0; - char fname[512] = {}; + char *fname, *s; tv_t now, diff; ts_t ts_now; json_t *val; FILE *fp; - char *s; int i; tv_time(&now); @@ -4058,17 +4058,10 @@ static void *statsupdate(void *arg) "lastupdate", now.tv_sec, "bestshare", worker->best_diff); - snprintf(fname, 511, "%s/workers/%s", ckp->logdir, worker->workername); - fp = fopen(fname, "we"); - if (unlikely(!fp)) { - LOGERR("Failed to fopen %s", fname); - continue; - } + ASPRINTF(&fname, "%s/workers/%s", ckp->logdir, worker->workername); s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER | JSON_EOL); - fprintf(fp, "%s", s); - dealloc(s); + add_log_entry(&log_entries, &fname, &s); json_decref(val); - fclose(fp); } /* Decay times per user */ @@ -4108,25 +4101,22 @@ static void *statsupdate(void *arg) "workers", user->workers, "bestshare", user->best_diff); - snprintf(fname, 511, "%s/users/%s", ckp->logdir, user->username); - fp = fopen(fname, "we"); - if (unlikely(!fp)) { - LOGERR("Failed to fopen %s", fname); - continue; - } - s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); - fprintf(fp, "%s\n", s); + ASPRINTF(&fname, "%s/users/%s", ckp->logdir, user->username); + s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER | JSON_EOL); + add_log_entry(&log_entries, &fname, &s); if (!idle) { char_t = ckalloc(sizeof(char_entry_t)); + s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); ASPRINTF(&char_t->buf, "User %s:%s", user->username, s); DL_APPEND(char_list, char_t); } - dealloc(s); json_decref(val); - fclose(fp); } ck_runlock(&sdata->instance_lock); + /* Dump log entries out of instance_lock */ + dump_log_entries(&log_entries); + DL_FOREACH_SAFE(char_list, char_t, chartmp_t) { LOGNOTICE("%s", char_t->buf); DL_DELETE(char_list, char_t); @@ -4155,10 +4145,11 @@ static void *statsupdate(void *arg) ghs10080 = stats->dsps10080 * nonces; suffix_string(ghs10080, suffix10080, 16, 0); - snprintf(fname, 511, "%s/pool/pool.status", ckp->logdir); + ASPRINTF(&fname, "%s/pool/pool.status", ckp->logdir); fp = fopen(fname, "we"); if (unlikely(!fp)) LOGERR("Failed to fopen %s", fname); + dealloc(fname); JSON_CPACK(val, "{si,si,si,si,si,si}", "runtime", diff.tv_sec,