diff --git a/README b/README index 183e7d2b..0f78dbbd 100644 --- a/README +++ b/README @@ -654,6 +654,16 @@ The list of requests - a (*) means it requires privileged access - and replies a highest priority (the pool is also enabled) The Msg includes the pool URL + enablepool|N (*) + none There is no reply section just the STATUS section + stating the results of enabling pool N + The Msg includes the pool URL + + disablepool|N (*) + none There is no reply section just the STATUS section + stating the results of disabling pool N + The Msg includes the pool URL + gpuenable|N (*) none There is no reply section just the STATUS section stating the results of the enable request diff --git a/api.c b/api.c index 60d1871a..7141848c 100644 --- a/api.c +++ b/api.c @@ -259,6 +259,11 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_SAVED 44 #define MSG_ACCDENY 45 #define MSG_ACCOK 46 +#define MSG_ENAPOOL 47 +#define MSG_DISPOOL 48 +#define MSG_ALRENAP 49 +#define MSG_ALRDISP 50 +#define MSG_DISLASTP 51 enum code_severity { SEVERITY_ERR, @@ -346,6 +351,11 @@ struct CODES { { SEVERITY_ERR, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" }, { SEVERITY_ERR, MSG_ACCDENY, PARAM_STR, "Access denied to '%s' command" }, { SEVERITY_SUCC, MSG_ACCOK, PARAM_NONE, "Privileged access OK" }, + { SEVERITY_SUCC, MSG_ENAPOOL, PARAM_POOL, "Enabling pool %d:'%s'" }, + { SEVERITY_SUCC, MSG_DISPOOL, PARAM_POOL, "Disabling pool %d:'%s'" }, + { SEVERITY_INFO, MSG_ALRENAP, PARAM_POOL, "Pool %d:'%s' already enabled" }, + { SEVERITY_INFO, MSG_ALRDISP, PARAM_POOL, "Pool %d:'%s' already disabled" }, + { SEVERITY_ERR, MSG_DISLASTP,PARAM_POOL, "Cannot disable last active pool %d:'%s'" }, { SEVERITY_FAIL, 0, 0, NULL } }; @@ -976,6 +986,79 @@ static void switchpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson) strcpy(io_buffer, message(MSG_SWITCHP, id, NULL, isjson)); } +static void enablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson) +{ + struct pool *pool; + int id; + + if (total_pools == 0) { + strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + return; + } + + if (param == NULL || *param == '\0') { + strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson)); + return; + } + + id = atoi(param); + if (id < 0 || id >= total_pools) { + strcpy(io_buffer, message(MSG_INVPID, id, NULL, isjson)); + return; + } + + pool = pools[id]; + if (pool->enabled == true) { + strcpy(io_buffer, message(MSG_ALRENAP, id, NULL, isjson)); + return; + } + + pool->enabled = true; + if (pool->prio < current_pool()->prio) + switch_pools(pool); + + strcpy(io_buffer, message(MSG_ENAPOOL, id, NULL, isjson)); +} + +static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson) +{ + struct pool *pool; + int id; + + if (total_pools == 0) { + strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + return; + } + + if (param == NULL || *param == '\0') { + strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson)); + return; + } + + id = atoi(param); + if (id < 0 || id >= total_pools) { + strcpy(io_buffer, message(MSG_INVPID, id, NULL, isjson)); + return; + } + + pool = pools[id]; + if (pool->enabled == false) { + strcpy(io_buffer, message(MSG_ALRDISP, id, NULL, isjson)); + return; + } + + if (active_pools() <= 1) { + strcpy(io_buffer, message(MSG_DISLASTP, id, NULL, isjson)); + return; + } + + pool->enabled = false; + if (pool == current_pool()) + switch_pools(NULL); + + strcpy(io_buffer, message(MSG_DISPOOL, id, NULL, isjson)); +} + static bool splitgpuvalue(char *param, int *gpu, char **value, bool isjson) { int id; @@ -1188,6 +1271,9 @@ struct CMDS { { "gpucount", gpucount, false }, { "cpucount", cpucount, false }, { "switchpool", switchpool, true }, +// { "addpool", addpool, true }, Not yet ... + { "enablepool", enablepool, true }, + { "disablepool", disablepool, true }, { "gpuintensity", gpuintensity, true }, { "gpumem", gpumem, true }, { "gpuengine", gpuengine, true }, diff --git a/cgminer.c b/cgminer.c index d9d9f11c..6a79ccc4 100644 --- a/cgminer.c +++ b/cgminer.c @@ -360,7 +360,7 @@ static bool pool_isset(struct pool *pool, bool *var) return ret; } -static struct pool *current_pool(void) +struct pool *current_pool(void) { struct pool *pool; @@ -2272,7 +2272,7 @@ int curses_int(const char *query) static bool input_pool(bool live); -static int active_pools(void) +int active_pools(void) { int ret = 0; int i; @@ -4053,10 +4053,43 @@ char *curses_input(const char *query) return input; } +int add_pool_details(bool live, char *url, char *user, char *pass) +{ + struct pool *pool = NULL; + + if (total_pools == MAX_POOLS) + return ADD_POOL_MAXIMUM; + + pool = calloc(sizeof(struct pool), 1); + if (!pool) + quit(1, "Failed to realloc pools in add_pool_details"); + pool->pool_no = total_pools; + pool->prio = total_pools; + if (unlikely(pthread_mutex_init(&pool->pool_lock, NULL))) + quit (1, "Failed to pthread_mutex_init in input_pool"); + pool->rpc_url = url; + pool->rpc_user = user; + pool->rpc_pass = pass; + pool->rpc_userpass = malloc(strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2); + if (!pool->rpc_userpass) + quit(1, "Failed to malloc userpass"); + sprintf(pool->rpc_userpass, "%s:%s", pool->rpc_user, pool->rpc_pass); + + pool->tv_idle.tv_sec = ~0UL; + + /* Test the pool is not idle if we're live running, otherwise + * it will be tested separately */ + pool->enabled = true; + if (live && !pool_active(pool, false)) + pool->idle = true; + pools[total_pools++] = pool; + + return ADD_POOL_OK; +} + static bool input_pool(bool live) { char *url = NULL, *user = NULL, *pass = NULL; - struct pool *pool = NULL; bool ret = false; immedok(logwin, true); @@ -4091,30 +4124,7 @@ static bool input_pool(bool live) if (!pass) goto out; - pool = calloc(sizeof(struct pool), 1); - if (!pool) - quit(1, "Failed to realloc pools in input_pool"); - pool->pool_no = total_pools; - pool->prio = total_pools; - if (unlikely(pthread_mutex_init(&pool->pool_lock, NULL))) - quit (1, "Failed to pthread_mutex_init in input_pool"); - pool->rpc_url = url; - pool->rpc_user = user; - pool->rpc_pass = pass; - pool->rpc_userpass = malloc(strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2); - if (!pool->rpc_userpass) - quit(1, "Failed to malloc userpass"); - sprintf(pool->rpc_userpass, "%s:%s", pool->rpc_user, pool->rpc_pass); - - pool->tv_idle.tv_sec = ~0UL; - - /* Test the pool is not idle if we're live running, otherwise - * it will be tested separately */ - ret = true; - pool->enabled = true; - if (live && !pool_active(pool, false)) - pool->idle = true; - pools[total_pools++] = pool; + ret = (add_pool_details(live, url, user, pass) == ADD_POOL_OK); out: immedok(logwin, false); @@ -4125,8 +4135,6 @@ out: free(user); if (pass) free(pass); - if (pool) - free(pool); } return ret; } diff --git a/miner.h b/miner.h index 23e91ec4..5f5fd68d 100644 --- a/miner.h +++ b/miner.h @@ -465,6 +465,13 @@ extern int set_memoryclock(int gpu, int iMemoryClock); extern void api(int thr_id); +extern struct pool *current_pool(void); +extern int active_pools(void); +extern int add_pool_details(bool live, char *url, char *user, char *pass); + +#define ADD_POOL_MAXIMUM 1 +#define ADD_POOL_OK 0 + #define MAX_GPUDEVICES 16 #define MAX_DEVICES 32 #define MAX_POOLS (32)