Browse Source

Updated API functionality

Fixed addpool to specify a profile or algorithm and sets defaults if
nothing specified. Also added a new API function to change multipool
strategy.

Conflicts (resolved):
	sgminer.c
djm34
Noel Maersk 11 years ago
parent
commit
832ac82bf6
  1. 2
      Makefile.am
  2. 546
      api.c
  3. 436
      api.h
  4. 2862
      config_parser.c
  5. 63
      config_parser.h
  6. 11
      doc/API.md
  7. 0
      doc/GPU.md
  8. 6
      miner.h
  9. 57
      sgminer.c

2
Makefile.am

@ -32,7 +32,7 @@ sgminer_CPPFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\" @@ -32,7 +32,7 @@ sgminer_CPPFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
endif
sgminer_SOURCES := sgminer.c
sgminer_SOURCES += api.c
sgminer_SOURCES += api.c api.h
sgminer_SOURCES += elist.h miner.h compat.h bench_block.h
sgminer_SOURCES += util.c util.h uthash.h
sgminer_SOURCES += logging.c logging.h

546
api.c

@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
#include <sys/types.h>
#include "compat.h"
#include "api.h"
#include "miner.h"
#include "pool.h"
#include "util.h"
@ -33,72 +34,9 @@ @@ -33,72 +34,9 @@
#include "config_parser.h"
// BUFSIZ varies on Windows and Linux
#define TMPBUFSIZ 8192
// Number of requests to queue - normally would be small
#define QUEUE 100
#if defined WIN32
#ifdef WIN32
static char WSAbuf[1024];
struct WSAERRORS {
int id;
char *code;
} WSAErrors[] = {
{ 0, "No error" },
{ WSAEINTR, "Interrupted system call" },
{ WSAEBADF, "Bad file number" },
{ WSAEACCES, "Permission denied" },
{ WSAEFAULT, "Bad address" },
{ WSAEINVAL, "Invalid argument" },
{ WSAEMFILE, "Too many open sockets" },
{ WSAEWOULDBLOCK, "Operation would block" },
{ WSAEINPROGRESS, "Operation now in progress" },
{ WSAEALREADY, "Operation already in progress" },
{ WSAENOTSOCK, "Socket operation on non-socket" },
{ WSAEDESTADDRREQ, "Destination address required" },
{ WSAEMSGSIZE, "Message too long" },
{ WSAEPROTOTYPE, "Protocol wrong type for socket" },
{ WSAENOPROTOOPT, "Bad protocol option" },
{ WSAEPROTONOSUPPORT, "Protocol not supported" },
{ WSAESOCKTNOSUPPORT, "Socket type not supported" },
{ WSAEOPNOTSUPP, "Operation not supported on socket" },
{ WSAEPFNOSUPPORT, "Protocol family not supported" },
{ WSAEAFNOSUPPORT, "Address family not supported" },
{ WSAEADDRINUSE, "Address already in use" },
{ WSAEADDRNOTAVAIL, "Can't assign requested address" },
{ WSAENETDOWN, "Network is down" },
{ WSAENETUNREACH, "Network is unreachable" },
{ WSAENETRESET, "Net connection reset" },
{ WSAECONNABORTED, "Software caused connection abort" },
{ WSAECONNRESET, "Connection reset by peer" },
{ WSAENOBUFS, "No buffer space available" },
{ WSAEISCONN, "Socket is already connected" },
{ WSAENOTCONN, "Socket is not connected" },
{ WSAESHUTDOWN, "Can't send after socket shutdown" },
{ WSAETOOMANYREFS, "Too many references, can't splice" },
{ WSAETIMEDOUT, "Connection timed out" },
{ WSAECONNREFUSED, "Connection refused" },
{ WSAELOOP, "Too many levels of symbolic links" },
{ WSAENAMETOOLONG, "File name too long" },
{ WSAEHOSTDOWN, "Host is down" },
{ WSAEHOSTUNREACH, "No route to host" },
{ WSAENOTEMPTY, "Directory not empty" },
{ WSAEPROCLIM, "Too many processes" },
{ WSAEUSERS, "Too many users" },
{ WSAEDQUOT, "Disc quota exceeded" },
{ WSAESTALE, "Stale NFS file handle" },
{ WSAEREMOTE, "Too many levels of remote in path" },
{ WSASYSNOTREADY, "Network system is unavailable" },
{ WSAVERNOTSUPPORTED, "Winsock version out of range" },
{ WSANOTINITIALISED, "WSAStartup not yet called" },
{ WSAEDISCON, "Graceful shutdown in progress" },
{ WSAHOST_NOT_FOUND, "Host not found" },
{ WSANO_DATA, "No host data of that type was found" },
{ -1, "Unknown error code" }
};
char *WSAErrorMsg(void) {
int i;
int id = WSAGetLastError();
@ -114,21 +52,15 @@ char *WSAErrorMsg(void) { @@ -114,21 +52,15 @@ char *WSAErrorMsg(void) {
}
#endif
static const char *UNAVAILABLE = " - API will not be available";
static const char *MUNAVAILABLE = " - API multicast listener will not be available";
static const char *BLANK = "";
static const char *COMMA = ",";
#define COMSTR ","
static const char SEPARATOR = '|';
#define SEPSTR "|"
static const char GPUSEP = ',';
#define CMDJOIN '+'
#define JOIN_CMD "CMD="
#define BETWEEN_JOIN SEPSTR
static const char *APIVERSION = "3.2";
static const char *APIVERSION = "4.0";
static const char *DEAD = "Dead";
static const char *SICK = "Sick";
static const char *NOSTART = "NoStart";
@ -137,7 +69,6 @@ static const char *DISABLED = "Disabled"; @@ -137,7 +69,6 @@ static const char *DISABLED = "Disabled";
static const char *ALIVE = "Alive";
static const char *REJECTING = "Rejecting";
static const char *UNKNOWN = "Unknown";
#define _DYNAMIC "D"
static const char *DYNAMIC = _DYNAMIC;
static __maybe_unused const char *NONE = "None";
@ -166,270 +97,9 @@ static const char *OSINFO = @@ -166,270 +97,9 @@ static const char *OSINFO =
"Unknown";
#endif
#define _DEVS "DEVS"
#define _POOLS "POOLS"
#define _SUMMARY "SUMMARY"
#define _STATUS "STATUS"
#define _VERSION "VERSION"
#define _MINECONFIG "CONFIG"
#define _GPU "GPU"
#define _GPUS "GPUS"
#define _NOTIFY "NOTIFY"
#define _DEVDETAILS "DEVDETAILS"
#define _BYE "BYE"
#define _RESTART "RESTART"
#define _MINESTATS "STATS"
#define _CHECK "CHECK"
#define _MINECOIN "COIN"
#define _DEBUGSET "DEBUG"
#define _SETCONFIG "SETCONFIG"
static const char ISJSON = '{';
#define JSON0 "{"
#define JSON1 "\""
#define JSON2 "\":["
#define JSON3 "]"
#define JSON4 ",\"id\":1"
// If anyone cares, id=0 for truncated output
#define JSON4_TRUNCATED ",\"id\":0"
#define JSON5 "}"
#define JSON_START JSON0
#define JSON_DEVS JSON1 _DEVS JSON2
#define JSON_POOLS JSON1 _POOLS JSON2
#define JSON_SUMMARY JSON1 _SUMMARY JSON2
#define JSON_STATUS JSON1 _STATUS JSON2
#define JSON_VERSION JSON1 _VERSION JSON2
#define JSON_MINECONFIG JSON1 _MINECONFIG JSON2
#define JSON_GPU JSON1 _GPU JSON2
#define JSON_GPUS JSON1 _GPUS JSON2
#define JSON_NOTIFY JSON1 _NOTIFY JSON2
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2
#define JSON_CLOSE JSON3
#define JSON_MINESTATS JSON1 _MINESTATS JSON2
#define JSON_CHECK JSON1 _CHECK JSON2
#define JSON_MINECOIN JSON1 _MINECOIN JSON2
#define JSON_DEBUGSET JSON1 _DEBUGSET JSON2
#define JSON_SETCONFIG JSON1 _SETCONFIG JSON2
#define JSON_END JSON4 JSON5
#define JSON_END_TRUNCATED JSON4_TRUNCATED JSON5
#define JSON_BETWEEN_JOIN ","
static const char *JSON_COMMAND = "command";
static const char *JSON_PARAMETER = "parameter";
#define MSG_INVGPU 1
#define MSG_ALRENA 2
#define MSG_ALRDIS 3
#define MSG_GPUMRE 4
#define MSG_GPUREN 5
#define MSG_GPUNON 6
#define MSG_POOL 7
#define MSG_NOPOOL 8
#define MSG_DEVS 9
#define MSG_NODEVS 10
#define MSG_SUMM 11
#define MSG_GPUDIS 12
#define MSG_GPUREI 13
#define MSG_INVCMD 14
#define MSG_MISID 15
#define MSG_GPUDEV 17
#define MSG_NUMGPU 20
#define MSG_VERSION 22
#define MSG_INVJSON 23
#define MSG_MISCMD 24
#define MSG_MISPID 25
#define MSG_INVPID 26
#define MSG_SWITCHP 27
#define MSG_MISVAL 28
#define MSG_NOADL 29
#define MSG_NOGPUADL 30
#define MSG_INVINT 31
#define MSG_GPUINT 32
#define MSG_MINECONFIG 33
#define MSG_GPUMERR 34
#define MSG_GPUMEM 35
#define MSG_GPUEERR 36
#define MSG_GPUENG 37
#define MSG_GPUVERR 38
#define MSG_GPUVDDC 39
#define MSG_GPUFERR 40
#define MSG_GPUFAN 41
#define MSG_MISFN 42
#define MSG_BADFN 43
#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_MISPDP 52
#define MSG_INVPDP 53
#define MSG_TOOMANYP 54
#define MSG_ADDPOOL 55
#define MSG_NOTIFY 60
#define MSG_REMLASTP 66
#define MSG_ACTPOOL 67
#define MSG_REMPOOL 68
#define MSG_DEVDETAILS 69
#define MSG_MINESTATS 70
#define MSG_MISCHK 71
#define MSG_CHECK 72
#define MSG_POOLPRIO 73
#define MSG_DUPPID 74
#define MSG_MISBOOL 75
#define MSG_INVBOOL 76
#define MSG_FOO 77
#define MSG_MINECOIN 78
#define MSG_DEBUGSET 79
#define MSG_SETCONFIG 82
#define MSG_UNKCON 83
#define MSG_INVNUM 84
#define MSG_CONPAR 85
#define MSG_CONVAL 86
#define MSG_NOUSTA 88
#define MSG_ZERMIS 94
#define MSG_ZERINV 95
#define MSG_ZERSUM 96
#define MSG_ZERNOSUM 97
#define MSG_BYE 0x101
#define MSG_INVNEG 121
#define MSG_SETQUOTA 122
#define MSG_LOCKOK 123
#define MSG_LOCKDIS 124
enum code_severity {
SEVERITY_ERR,
SEVERITY_WARN,
SEVERITY_INFO,
SEVERITY_SUCC,
SEVERITY_FAIL
};
enum code_parameters {
PARAM_GPU,
PARAM_PID,
PARAM_GPUMAX,
PARAM_PMAX,
PARAM_POOLMAX,
// Single generic case: have the code resolve it - see below
PARAM_DMAX,
PARAM_CMD,
PARAM_POOL,
PARAM_STR,
PARAM_BOTH,
PARAM_BOOL,
PARAM_SET,
PARAM_INT,
PARAM_NONE
};
struct CODES {
const enum code_severity severity;
const int code;
const enum code_parameters params;
const char *description;
} codes[] = {
{ SEVERITY_ERR, MSG_INVGPU, PARAM_GPUMAX, "Invalid GPU id %d - range is 0 - %d" },
{ SEVERITY_INFO, MSG_ALRENA, PARAM_GPU, "GPU %d already enabled" },
{ SEVERITY_INFO, MSG_ALRDIS, PARAM_GPU, "GPU %d already disabled" },
{ SEVERITY_WARN, MSG_GPUMRE, PARAM_GPU, "GPU %d must be restarted first" },
{ SEVERITY_INFO, MSG_GPUREN, PARAM_GPU, "GPU %d sent enable message" },
{ SEVERITY_ERR, MSG_GPUNON, PARAM_NONE, "No GPUs" },
{ SEVERITY_SUCC, MSG_POOL, PARAM_PMAX, "%d Pool(s)" },
{ SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" },
{ SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)" },
{ SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs"
},
{ SEVERITY_SUCC, MSG_SUMM, PARAM_NONE, "Summary" },
{ SEVERITY_INFO, MSG_GPUDIS, PARAM_GPU, "GPU %d set disable flag" },
{ SEVERITY_INFO, MSG_GPUREI, PARAM_GPU, "GPU %d restart attempted" },
{ SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" },
{ SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" },
{ SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" },
{ SEVERITY_SUCC, MSG_NUMGPU, PARAM_NONE, "GPU count" },
{ SEVERITY_SUCC, MSG_VERSION, PARAM_NONE, "SGMiner versions" },
{ SEVERITY_ERR, MSG_INVJSON, PARAM_NONE, "Invalid JSON" },
{ SEVERITY_ERR, MSG_MISCMD, PARAM_CMD, "Missing JSON '%s'" },
{ SEVERITY_ERR, MSG_MISPID, PARAM_NONE, "Missing pool id parameter" },
{ SEVERITY_ERR, MSG_INVPID, PARAM_POOLMAX, "Invalid pool id %d - range is 0 - %d" },
{ SEVERITY_SUCC, MSG_SWITCHP, PARAM_POOL, "Switching to pool %d:'%s'" },
{ SEVERITY_ERR, MSG_MISVAL, PARAM_NONE, "Missing comma after GPU number" },
{ SEVERITY_ERR, MSG_NOADL, PARAM_NONE, "ADL is not available" },
{ SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" },
{ SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " MIN_INTENSITY_STR " - " MAX_INTENSITY_STR },
{ SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" },
{ SEVERITY_SUCC, MSG_MINECONFIG,PARAM_NONE, "sgminer config" },
{ SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" },
{ SEVERITY_ERR, MSG_GPUEERR, PARAM_BOTH, "Setting GPU %d clock to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUENG, PARAM_BOTH, "Setting GPU %d clock to (%s) reported success" },
{ SEVERITY_ERR, MSG_GPUVERR, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUVDDC, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported success" },
{ SEVERITY_ERR, MSG_GPUFERR, PARAM_BOTH, "Setting GPU %d fan to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUFAN, PARAM_BOTH, "Setting GPU %d fan to (%s) reported success" },
{ SEVERITY_ERR, MSG_MISFN, PARAM_NONE, "Missing save filename parameter" },
{ SEVERITY_ERR, MSG_BADFN, PARAM_STR, "Can't open or create save file '%s'" },
{ SEVERITY_SUCC, 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_POOLPRIO,PARAM_NONE, "Changed pool priorities" },
{ SEVERITY_ERR, MSG_DUPPID, PARAM_PID, "Duplicate pool specified %d" },
{ 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_MISPDP, PARAM_NONE, "Missing addpool details" },
{ SEVERITY_ERR, MSG_INVPDP, PARAM_STR, "Invalid addpool details '%s'" },
{ SEVERITY_ERR, MSG_TOOMANYP,PARAM_NONE, "Reached maximum number of pools (%d)" },
{ SEVERITY_SUCC, MSG_ADDPOOL, PARAM_STR, "Added pool '%s'" },
{ SEVERITY_ERR, MSG_REMLASTP,PARAM_POOL, "Cannot remove last pool %d:'%s'" },
{ SEVERITY_ERR, MSG_ACTPOOL, PARAM_POOL, "Cannot remove active pool %d:'%s'" },
{ SEVERITY_SUCC, MSG_REMPOOL, PARAM_BOTH, "Removed pool %d:'%s'" },
{ SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
{ SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" },
{ SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "sgminer stats" },
{ SEVERITY_ERR, MSG_MISCHK, PARAM_NONE, "Missing check cmd" },
{ SEVERITY_SUCC, MSG_CHECK, PARAM_NONE, "Check command" },
{ SEVERITY_ERR, MSG_MISBOOL, PARAM_NONE, "Missing parameter: true/false" },
{ SEVERITY_ERR, MSG_INVBOOL, PARAM_NONE, "Invalid parameter should be true or false" },
{ SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" },
{ SEVERITY_SUCC, MSG_MINECOIN,PARAM_NONE, "sgminer coin" },
{ SEVERITY_SUCC, MSG_DEBUGSET,PARAM_NONE, "Debug settings" },
{ SEVERITY_SUCC, MSG_SETCONFIG,PARAM_SET, "Set config '%s' to %d" },
{ SEVERITY_ERR, MSG_UNKCON, PARAM_STR, "Unknown config '%s'" },
{ SEVERITY_ERR, MSG_INVNUM, PARAM_BOTH, "Invalid number (%d) for '%s' range is 0-9999" },
{ SEVERITY_ERR, MSG_INVNEG, PARAM_BOTH, "Invalid negative number (%d) for '%s'" },
{ SEVERITY_SUCC, MSG_SETQUOTA,PARAM_SET, "Set pool '%s' to quota %d'" },
{ SEVERITY_ERR, MSG_CONPAR, PARAM_NONE, "Missing config parameters 'name,N'" },
{ SEVERITY_ERR, MSG_CONVAL, PARAM_STR, "Missing config value N for '%s,N'" },
{ SEVERITY_INFO, MSG_NOUSTA, PARAM_NONE, "No USB Statistics" },
{ SEVERITY_ERR, MSG_ZERMIS, PARAM_NONE, "Missing zero parameters" },
{ SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" },
{ SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" },
{ SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" },
{ SEVERITY_SUCC, MSG_LOCKOK, PARAM_NONE, "Lock stats created" },
{ SEVERITY_WARN, MSG_LOCKDIS, PARAM_NONE, "Lock stats not enabled" },
{ SEVERITY_SUCC, MSG_BYE, PARAM_STR, "%s" },
{ SEVERITY_FAIL, 0, (enum code_parameters)0, NULL }
};
static const char ISJSON = '{';
static const char *localaddr = "127.0.0.1";
static int my_thr_id = 0;
@ -443,50 +113,11 @@ static bool do_a_restart; @@ -443,50 +113,11 @@ static bool do_a_restart;
static time_t when = 0; // when the request occurred
struct IP4ACCESS {
in_addr_t ip;
in_addr_t mask;
char group;
};
#define GROUP(g) (toupper(g))
#define PRIVGROUP GROUP('W')
#define NOPRIVGROUP GROUP('R')
#define ISPRIVGROUP(g) (GROUP(g) == PRIVGROUP)
#define GROUPOFFSET(g) (GROUP(g) - GROUP('A'))
#define VALIDGROUP(g) (GROUP(g) >= GROUP('A') && GROUP(g) <= GROUP('Z'))
#define COMMANDS(g) (apigroups[GROUPOFFSET(g)].commands)
#define DEFINEDGROUP(g) (ISPRIVGROUP(g) || COMMANDS(g) != NULL)
struct APIGROUPS {
// This becomes a string like: "|cmd1|cmd2|cmd3|" so it's quick to search
char *commands;
} apigroups['Z' - 'A' + 1]; // only A=0 to Z=25 (R: noprivs, W: allprivs)
static struct IP4ACCESS *ipaccess = NULL;
static int ips = 0;
struct io_data {
size_t siz;
char *ptr;
char *cur;
bool sock;
bool close;
};
struct io_list {
struct io_data *io_data;
struct io_list *prev;
struct io_list *next;
};
static struct io_list *io_head = NULL;
#define SOCKBUFALLOCSIZ 65536
#define io_new(init) _io_new(init, false)
#define sock_io_new() _io_new(SOCKBUFALLOCSIZ, true)
static void io_reinit(struct io_data *io_data)
{
io_data->cur = io_data->ptr;
@ -1047,7 +678,7 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson @@ -1047,7 +678,7 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
// All replies (except BYE and RESTART) start with a message
// thus for JSON, message() inserts JSON_START at the front
// and send_result() adds JSON_END at the end
static void message(struct io_data *io_data, int messageid, int paramid, char *param2, bool isjson)
void message(struct io_data *io_data, int messageid, int paramid, char *param2, bool isjson)
{
struct api_data *root = NULL;
char buf[TMPBUFSIZ];
@ -1149,49 +780,6 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p @@ -1149,49 +780,6 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p
#if LOCK_TRACKING
#define LOCK_FMT_FFL " - called from %s %s():%d"
#define LOCKMSG(fmt, ...) fprintf(stderr, "APILOCK: " fmt "\n", ##__VA_ARGS__)
#define LOCKMSGMORE(fmt, ...) fprintf(stderr, " " fmt "\n", ##__VA_ARGS__)
#define LOCKMSGFFL(fmt, ...) fprintf(stderr, "APILOCK: " fmt LOCK_FMT_FFL "\n", ##__VA_ARGS__, file, func, linenum)
#define LOCKMSGFLUSH() fflush(stderr)
typedef struct lockstat {
uint64_t lock_id;
const char *file;
const char *func;
int linenum;
struct timeval tv;
} LOCKSTAT;
typedef struct lockline {
struct lockline *prev;
struct lockstat *stat;
struct lockline *next;
} LOCKLINE;
typedef struct lockinfo {
void *lock;
enum cglock_typ typ;
const char *file;
const char *func;
int linenum;
uint64_t gets;
uint64_t gots;
uint64_t tries;
uint64_t dids;
uint64_t didnts; // should be tries - dids
uint64_t unlocks;
LOCKSTAT lastgot;
LOCKLINE *lockgets;
LOCKLINE *locktries;
} LOCKINFO;
typedef struct locklist {
LOCKINFO *info;
struct locklist *next;
} LOCKLIST;
static uint64_t lock_id = 1;
static LOCKLIST *lockhead;
@ -1534,6 +1122,23 @@ void show_locks() @@ -1534,6 +1122,23 @@ void show_locks()
}
#endif
static void copyadvanceafter(char ch, char **param, char **buf)
{
#define src_p (*param)
#define dst_b (*buf)
while (*src_p && *src_p != ch) {
if (*src_p == '\\' && *(src_p+1) != '\0')
src_p++;
*(dst_b++) = *(src_p++);
}
if (*src_p)
src_p++;
*(dst_b++) = '\0';
}
static void lockstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
{
#if LOCK_TRACKING
@ -1824,6 +1429,7 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m @@ -1824,6 +1429,7 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
root = api_add_string(root, "Name", get_pool_name(pool), true);
mutex_unlock(&pool->stratum_lock);
root = api_add_escape(root, "URL", pool->rpc_url, false);
root = api_add_string(root, "Profile", pool->profile, false);
root = api_add_string(root, "Algorithm", pool->algorithm.name, false);
root = api_add_string(root, "Description", pool->description, false);
root = api_add_string(root, "Status", status, false);
@ -2101,25 +1707,74 @@ static void switchpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, cha @@ -2101,25 +1707,74 @@ static void switchpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, cha
message(io_data, MSG_SWITCHP, id, NULL, isjson);
}
static void copyadvanceafter(char ch, char **param, char **buf)
static void api_pool_strategy(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{
#define src_p (*param)
#define dst_b (*buf)
char *p;
int strategy;
if (total_pools == 0)
{
message(io_data, MSG_NOPOOL, 0, NULL, isjson);
return;
}
while (*src_p && *src_p != ch) {
if (*src_p == '\\' && *(src_p+1) != '\0')
src_p++;
if (param == NULL || *param == '\0')
{
message(io_data, MSG_MISSTRAT, 0, NULL, isjson);
return;
}
*(dst_b++) = *(src_p++);
//get strategy in parameter 1
if(!(p = strtok(param, ",")))
{
message(io_data, MSG_MISSTRAT, 0, NULL, isjson);
return;
}
if (*src_p)
src_p++;
strategy = atoi(p);
*(dst_b++) = '\0';
//invalid strategy
if(strategy < 0 || strategy > TOP_STRATEGY)
{
message(io_data, MSG_INVSTRAT, strategy, NULL, isjson);
return;
}
//if set to rotate, get second param
if(strategy == POOL_ROTATE)
{
//if second param is missing then invalid
if(!(p = strtok(NULL, ",")))
{
message(io_data, MSG_MISSTRATINT, 0, NULL, isjson);
return;
}
//get interval in parameter 2
int interval;
interval = atoi(p);
//interval can only be between 0 and 9999
if(interval < 0 || interval > 9999)
{
message(io_data, MSG_INVNUM, interval, "interval", isjson);
return;
}
//set interval
opt_rotate_period = interval;
}
//set pool strategy
pool_strategy = (enum pool_strategy)strategy;
//initiate new strategy
switch_pools(NULL);
message(io_data, MSG_CHSTRAT, 0, (char *)strategies[strategy].s, isjson);
}
static bool pooldetails(char *param, char **url, char **user, char **pass,
char **name, char **desc, char **algo)
char **name, char **desc, char **profile, char **algo)
{
char *ptr, *buf;
@ -2134,23 +1789,28 @@ static bool pooldetails(char *param, char **url, char **user, char **pass, @@ -2134,23 +1789,28 @@ static bool pooldetails(char *param, char **url, char **user, char **pass,
*user = buf;
copyadvanceafter(',', &param, &buf);
if (!*param) // missing pass
if (!(*param)) // missing pass
goto exitsama;
*pass = buf;
copyadvanceafter(',', &param, &buf);
if (!*param) // missing name (allowed)
if (!(*param)) // missing name (allowed)
return true;
*name = buf;
copyadvanceafter(',', &param, &buf);
if (!*param) // missing desc
goto exitsama;
if (!(*param)) // missing desc
return true;
*desc = buf;
copyadvanceafter(',', &param, &buf);
if (!*param) // missing algo
goto exitsama;
if (!(*param)) // missing profile
return true;
*profile = buf;
copyadvanceafter(',', &param, &buf);
if (!(*param)) // missing algo
return true;
*algo = buf;
copyadvanceafter(',', &param, &buf);
@ -2165,7 +1825,7 @@ exitsama: @@ -2165,7 +1825,7 @@ exitsama:
static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{
char *url, *user, *pass;
char *name = NULL, *desc = NULL, *algo = NULL;
char *name = NULL, *desc = NULL, *algo = NULL, *profile = NULL;
struct pool *pool;
char *ptr;
@ -2175,7 +1835,7 @@ static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char * @@ -2175,7 +1835,7 @@ static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *
}
if (!pooldetails(param, &url, &user, &pass,
&name, &desc, &algo)) {
&name, &desc, &profile, &algo)) {
ptr = escape_string(param, isjson);
message(io_data, MSG_INVPDP, 0, ptr, isjson);
if (ptr != param)
@ -2185,13 +1845,14 @@ static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char * @@ -2185,13 +1845,14 @@ static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *
}
/* If API client is old, it might not have provided all fields. */
if (name == NULL) name = strdup("");
if (desc == NULL) desc = strdup("");
if (algo == NULL) algo = strdup("scrypt"); // FIXME?
name = ((name == NULL)?strdup(""):name);
desc = ((desc == NULL)?strdup(""):desc);
profile = ((profile == NULL)?strdup(""):profile);
algo = ((algo == NULL)?strdup(""):algo);
pool = add_pool();
detect_stratum(pool, url);
add_pool_details(pool, true, url, user, pass, name, desc, algo);
add_pool_details(pool, true, url, user, pass, name, desc, profile, algo);
ptr = escape_string(url, isjson);
message(io_data, MSG_ADDPOOL, 0, ptr, isjson);
@ -2729,7 +2390,7 @@ static void devdetails(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m @@ -2729,7 +2390,7 @@ static void devdetails(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
void dosave(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{
char filename[PATH_MAX];
FILE *fcfg;
// FILE *fcfg;
char *ptr;
if (param == NULL || *param == '\0') {
@ -3071,6 +2732,7 @@ struct CMDS { @@ -3071,6 +2732,7 @@ struct CMDS {
{ "gpu", gpudev, false, false },
{ "gpucount", gpucount, false, true },
{ "switchpool", switchpool, true, false },
{ "changestrategy", api_pool_strategy, true, false },
{ "addpool", addpool, true, false },
{ "poolpriority", poolpriority, true, false },
{ "poolquota", poolquota, true, false },

436
api.h

@ -0,0 +1,436 @@ @@ -0,0 +1,436 @@
#ifndef API_H
#define API_H
#include "config.h"
#include "miner.h"
// BUFSIZ varies on Windows and Linux
#define TMPBUFSIZ 8192
// Number of requests to queue - normally would be small
#define QUEUE 100
#ifdef WIN32
struct WSAERRORS {
int id;
char *code;
} WSAErrors[] = {
{ 0, "No error" },
{ WSAEINTR, "Interrupted system call" },
{ WSAEBADF, "Bad file number" },
{ WSAEACCES, "Permission denied" },
{ WSAEFAULT, "Bad address" },
{ WSAEINVAL, "Invalid argument" },
{ WSAEMFILE, "Too many open sockets" },
{ WSAEWOULDBLOCK, "Operation would block" },
{ WSAEINPROGRESS, "Operation now in progress" },
{ WSAEALREADY, "Operation already in progress" },
{ WSAENOTSOCK, "Socket operation on non-socket" },
{ WSAEDESTADDRREQ, "Destination address required" },
{ WSAEMSGSIZE, "Message too long" },
{ WSAEPROTOTYPE, "Protocol wrong type for socket" },
{ WSAENOPROTOOPT, "Bad protocol option" },
{ WSAEPROTONOSUPPORT, "Protocol not supported" },
{ WSAESOCKTNOSUPPORT, "Socket type not supported" },
{ WSAEOPNOTSUPP, "Operation not supported on socket" },
{ WSAEPFNOSUPPORT, "Protocol family not supported" },
{ WSAEAFNOSUPPORT, "Address family not supported" },
{ WSAEADDRINUSE, "Address already in use" },
{ WSAEADDRNOTAVAIL, "Can't assign requested address" },
{ WSAENETDOWN, "Network is down" },
{ WSAENETUNREACH, "Network is unreachable" },
{ WSAENETRESET, "Net connection reset" },
{ WSAECONNABORTED, "Software caused connection abort" },
{ WSAECONNRESET, "Connection reset by peer" },
{ WSAENOBUFS, "No buffer space available" },
{ WSAEISCONN, "Socket is already connected" },
{ WSAENOTCONN, "Socket is not connected" },
{ WSAESHUTDOWN, "Can't send after socket shutdown" },
{ WSAETOOMANYREFS, "Too many references, can't splice" },
{ WSAETIMEDOUT, "Connection timed out" },
{ WSAECONNREFUSED, "Connection refused" },
{ WSAELOOP, "Too many levels of symbolic links" },
{ WSAENAMETOOLONG, "File name too long" },
{ WSAEHOSTDOWN, "Host is down" },
{ WSAEHOSTUNREACH, "No route to host" },
{ WSAENOTEMPTY, "Directory not empty" },
{ WSAEPROCLIM, "Too many processes" },
{ WSAEUSERS, "Too many users" },
{ WSAEDQUOT, "Disc quota exceeded" },
{ WSAESTALE, "Stale NFS file handle" },
{ WSAEREMOTE, "Too many levels of remote in path" },
{ WSASYSNOTREADY, "Network system is unavailable" },
{ WSAVERNOTSUPPORTED, "Winsock version out of range" },
{ WSANOTINITIALISED, "WSAStartup not yet called" },
{ WSAEDISCON, "Graceful shutdown in progress" },
{ WSAHOST_NOT_FOUND, "Host not found" },
{ WSANO_DATA, "No host data of that type was found" },
{ -1, "Unknown error code" }
};
#endif
#define COMSTR ","
#define SEPSTR "|"
#define CMDJOIN '+'
#define JOIN_CMD "CMD="
#define BETWEEN_JOIN SEPSTR
#define _DYNAMIC "D"
#define _DEVS "DEVS"
#define _POOLS "POOLS"
#define _SUMMARY "SUMMARY"
#define _STATUS "STATUS"
#define _VERSION "VERSION"
#define _MINECONFIG "CONFIG"
#define _GPU "GPU"
#define _GPUS "GPUS"
#define _NOTIFY "NOTIFY"
#define _DEVDETAILS "DEVDETAILS"
#define _BYE "BYE"
#define _RESTART "RESTART"
#define _MINESTATS "STATS"
#define _CHECK "CHECK"
#define _MINECOIN "COIN"
#define _DEBUGSET "DEBUG"
#define _SETCONFIG "SETCONFIG"
#define JSON0 "{"
#define JSON1 "\""
#define JSON2 "\":["
#define JSON3 "]"
#define JSON4 ",\"id\":1"
// If anyone cares, id=0 for truncated output
#define JSON4_TRUNCATED ",\"id\":0"
#define JSON5 "}"
#define JSON_START JSON0
#define JSON_DEVS JSON1 _DEVS JSON2
#define JSON_POOLS JSON1 _POOLS JSON2
#define JSON_SUMMARY JSON1 _SUMMARY JSON2
#define JSON_STATUS JSON1 _STATUS JSON2
#define JSON_VERSION JSON1 _VERSION JSON2
#define JSON_MINECONFIG JSON1 _MINECONFIG JSON2
#define JSON_GPU JSON1 _GPU JSON2
#define JSON_GPUS JSON1 _GPUS JSON2
#define JSON_NOTIFY JSON1 _NOTIFY JSON2
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2
#define JSON_CLOSE JSON3
#define JSON_MINESTATS JSON1 _MINESTATS JSON2
#define JSON_CHECK JSON1 _CHECK JSON2
#define JSON_MINECOIN JSON1 _MINECOIN JSON2
#define JSON_DEBUGSET JSON1 _DEBUGSET JSON2
#define JSON_SETCONFIG JSON1 _SETCONFIG JSON2
#define JSON_END JSON4 JSON5
#define JSON_END_TRUNCATED JSON4_TRUNCATED JSON5
#define JSON_BETWEEN_JOIN ","
#define MSG_INVGPU 1
#define MSG_ALRENA 2
#define MSG_ALRDIS 3
#define MSG_GPUMRE 4
#define MSG_GPUREN 5
#define MSG_GPUNON 6
#define MSG_POOL 7
#define MSG_NOPOOL 8
#define MSG_DEVS 9
#define MSG_NODEVS 10
#define MSG_SUMM 11
#define MSG_GPUDIS 12
#define MSG_GPUREI 13
#define MSG_INVCMD 14
#define MSG_MISID 15
#define MSG_GPUDEV 17
#define MSG_NUMGPU 20
#define MSG_VERSION 22
#define MSG_INVJSON 23
#define MSG_MISCMD 24
#define MSG_MISPID 25
#define MSG_INVPID 26
#define MSG_SWITCHP 27
#define MSG_MISVAL 28
#define MSG_NOADL 29
#define MSG_NOGPUADL 30
#define MSG_INVINT 31
#define MSG_GPUINT 32
#define MSG_MINECONFIG 33
#define MSG_GPUMERR 34
#define MSG_GPUMEM 35
#define MSG_GPUEERR 36
#define MSG_GPUENG 37
#define MSG_GPUVERR 38
#define MSG_GPUVDDC 39
#define MSG_GPUFERR 40
#define MSG_GPUFAN 41
#define MSG_MISFN 42
#define MSG_BADFN 43
#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_MISPDP 52
#define MSG_INVPDP 53
#define MSG_TOOMANYP 54
#define MSG_ADDPOOL 55
#define MSG_NOTIFY 60
#define MSG_REMLASTP 66
#define MSG_ACTPOOL 67
#define MSG_REMPOOL 68
#define MSG_DEVDETAILS 69
#define MSG_MINESTATS 70
#define MSG_MISCHK 71
#define MSG_CHECK 72
#define MSG_POOLPRIO 73
#define MSG_DUPPID 74
#define MSG_MISBOOL 75
#define MSG_INVBOOL 76
#define MSG_FOO 77
#define MSG_MINECOIN 78
#define MSG_DEBUGSET 79
#define MSG_SETCONFIG 82
#define MSG_UNKCON 83
#define MSG_INVNUM 84
#define MSG_CONPAR 85
#define MSG_CONVAL 86
#define MSG_NOUSTA 88
#define MSG_ZERMIS 94
#define MSG_ZERINV 95
#define MSG_ZERSUM 96
#define MSG_ZERNOSUM 97
#define MSG_BYE 0x101
#define MSG_INVNEG 121
#define MSG_SETQUOTA 122
#define MSG_LOCKOK 123
#define MSG_LOCKDIS 124
#define MSG_CHSTRAT 125
#define MSG_MISSTRAT 126
#define MSG_INVSTRAT 127
#define MSG_MISSTRATINT 128
enum code_severity {
SEVERITY_ERR,
SEVERITY_WARN,
SEVERITY_INFO,
SEVERITY_SUCC,
SEVERITY_FAIL
};
enum code_parameters {
PARAM_GPU,
PARAM_PID,
PARAM_GPUMAX,
PARAM_PMAX,
PARAM_POOLMAX,
// Single generic case: have the code resolve it - see below
PARAM_DMAX,
PARAM_CMD,
PARAM_POOL,
PARAM_STR,
PARAM_BOTH,
PARAM_BOOL,
PARAM_SET,
PARAM_INT,
PARAM_NONE
};
struct CODES {
const enum code_severity severity;
const int code;
const enum code_parameters params;
const char *description;
} codes[] = {
{ SEVERITY_ERR, MSG_INVGPU, PARAM_GPUMAX, "Invalid GPU id %d - range is 0 - %d" },
{ SEVERITY_INFO, MSG_ALRENA, PARAM_GPU, "GPU %d already enabled" },
{ SEVERITY_INFO, MSG_ALRDIS, PARAM_GPU, "GPU %d already disabled" },
{ SEVERITY_WARN, MSG_GPUMRE, PARAM_GPU, "GPU %d must be restarted first" },
{ SEVERITY_INFO, MSG_GPUREN, PARAM_GPU, "GPU %d sent enable message" },
{ SEVERITY_ERR, MSG_GPUNON, PARAM_NONE, "No GPUs" },
{ SEVERITY_SUCC, MSG_POOL, PARAM_PMAX, "%d Pool(s)" },
{ SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" },
{ SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)" },
{ SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs"
},
{ SEVERITY_SUCC, MSG_SUMM, PARAM_NONE, "Summary" },
{ SEVERITY_INFO, MSG_GPUDIS, PARAM_GPU, "GPU %d set disable flag" },
{ SEVERITY_INFO, MSG_GPUREI, PARAM_GPU, "GPU %d restart attempted" },
{ SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" },
{ SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" },
{ SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" },
{ SEVERITY_SUCC, MSG_NUMGPU, PARAM_NONE, "GPU count" },
{ SEVERITY_SUCC, MSG_VERSION, PARAM_NONE, "SGMiner versions" },
{ SEVERITY_ERR, MSG_INVJSON, PARAM_NONE, "Invalid JSON" },
{ SEVERITY_ERR, MSG_MISCMD, PARAM_CMD, "Missing JSON '%s'" },
{ SEVERITY_ERR, MSG_MISPID, PARAM_NONE, "Missing pool id parameter" },
{ SEVERITY_ERR, MSG_INVPID, PARAM_POOLMAX, "Invalid pool id %d - range is 0 - %d" },
{ SEVERITY_SUCC, MSG_SWITCHP, PARAM_POOL, "Switching to pool %d:'%s'" },
{ SEVERITY_ERR, MSG_MISVAL, PARAM_NONE, "Missing comma after GPU number" },
{ SEVERITY_ERR, MSG_NOADL, PARAM_NONE, "ADL is not available" },
{ SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" },
{ SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " MIN_INTENSITY_STR " - " MAX_INTENSITY_STR },
{ SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" },
{ SEVERITY_SUCC, MSG_MINECONFIG,PARAM_NONE, "sgminer config" },
{ SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" },
{ SEVERITY_ERR, MSG_GPUEERR, PARAM_BOTH, "Setting GPU %d clock to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUENG, PARAM_BOTH, "Setting GPU %d clock to (%s) reported success" },
{ SEVERITY_ERR, MSG_GPUVERR, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUVDDC, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported success" },
{ SEVERITY_ERR, MSG_GPUFERR, PARAM_BOTH, "Setting GPU %d fan to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUFAN, PARAM_BOTH, "Setting GPU %d fan to (%s) reported success" },
{ SEVERITY_ERR, MSG_MISFN, PARAM_NONE, "Missing save filename parameter" },
{ SEVERITY_ERR, MSG_BADFN, PARAM_STR, "Can't open or create save file '%s'" },
{ SEVERITY_SUCC, 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_POOLPRIO,PARAM_NONE, "Changed pool priorities" },
{ SEVERITY_ERR, MSG_DUPPID, PARAM_PID, "Duplicate pool specified %d" },
{ 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_MISPDP, PARAM_NONE, "Missing addpool details" },
{ SEVERITY_ERR, MSG_INVPDP, PARAM_STR, "Invalid addpool details '%s'" },
{ SEVERITY_ERR, MSG_TOOMANYP,PARAM_NONE, "Reached maximum number of pools (%d)" },
{ SEVERITY_SUCC, MSG_ADDPOOL, PARAM_STR, "Added pool '%s'" },
{ SEVERITY_ERR, MSG_REMLASTP,PARAM_POOL, "Cannot remove last pool %d:'%s'" },
{ SEVERITY_ERR, MSG_ACTPOOL, PARAM_POOL, "Cannot remove active pool %d:'%s'" },
{ SEVERITY_SUCC, MSG_REMPOOL, PARAM_BOTH, "Removed pool %d:'%s'" },
{ SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
{ SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" },
{ SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "sgminer stats" },
{ SEVERITY_ERR, MSG_MISCHK, PARAM_NONE, "Missing check cmd" },
{ SEVERITY_SUCC, MSG_CHECK, PARAM_NONE, "Check command" },
{ SEVERITY_ERR, MSG_MISBOOL, PARAM_NONE, "Missing parameter: true/false" },
{ SEVERITY_ERR, MSG_INVBOOL, PARAM_NONE, "Invalid parameter should be true or false" },
{ SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" },
{ SEVERITY_SUCC, MSG_MINECOIN,PARAM_NONE, "sgminer coin" },
{ SEVERITY_SUCC, MSG_DEBUGSET,PARAM_NONE, "Debug settings" },
{ SEVERITY_SUCC, MSG_SETCONFIG,PARAM_SET, "Set config '%s' to %d" },
{ SEVERITY_ERR, MSG_UNKCON, PARAM_STR, "Unknown config '%s'" },
{ SEVERITY_ERR, MSG_INVNUM, PARAM_BOTH, "Invalid number (%d) for '%s' range is 0-9999" },
{ SEVERITY_ERR, MSG_INVNEG, PARAM_BOTH, "Invalid negative number (%d) for '%s'" },
{ SEVERITY_SUCC, MSG_SETQUOTA,PARAM_SET, "Set pool '%s' to quota %d'" },
{ SEVERITY_ERR, MSG_CONPAR, PARAM_NONE, "Missing config parameters 'name,N'" },
{ SEVERITY_ERR, MSG_CONVAL, PARAM_STR, "Missing config value N for '%s,N'" },
{ SEVERITY_INFO, MSG_NOUSTA, PARAM_NONE, "No USB Statistics" },
{ SEVERITY_ERR, MSG_ZERMIS, PARAM_NONE, "Missing zero parameters" },
{ SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" },
{ SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" },
{ SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" },
{ SEVERITY_SUCC, MSG_LOCKOK, PARAM_NONE, "Lock stats created" },
{ SEVERITY_WARN, MSG_LOCKDIS, PARAM_NONE, "Lock stats not enabled" },
{ SEVERITY_SUCC, MSG_CHSTRAT, PARAM_STR, "Multipool strategy changed to '%s'" },
{ SEVERITY_ERR, MSG_MISSTRAT, PARAM_NONE, "Missing multipool strategy" },
{ SEVERITY_ERR, MSG_INVSTRAT, PARAM_NONE, "Invalid multipool strategy %d" },
{ SEVERITY_ERR, MSG_MISSTRATINT, PARAM_NONE, "Missing rotate interval" },
{ SEVERITY_SUCC, MSG_BYE, PARAM_STR, "%s" },
{ SEVERITY_FAIL, 0, (enum code_parameters)0, NULL }
};
struct IP4ACCESS {
in_addr_t ip;
in_addr_t mask;
char group;
};
#define GROUP(g) (toupper(g))
#define PRIVGROUP GROUP('W')
#define NOPRIVGROUP GROUP('R')
#define ISPRIVGROUP(g) (GROUP(g) == PRIVGROUP)
#define GROUPOFFSET(g) (GROUP(g) - GROUP('A'))
#define VALIDGROUP(g) (GROUP(g) >= GROUP('A') && GROUP(g) <= GROUP('Z'))
#define COMMANDS(g) (apigroups[GROUPOFFSET(g)].commands)
#define DEFINEDGROUP(g) (ISPRIVGROUP(g) || COMMANDS(g) != NULL)
struct APIGROUPS {
// This becomes a string like: "|cmd1|cmd2|cmd3|" so it's quick to search
char *commands;
} apigroups['Z' - 'A' + 1]; // only A=0 to Z=25 (R: noprivs, W: allprivs)
struct io_data {
size_t siz;
char *ptr;
char *cur;
bool sock;
bool close;
};
struct io_list {
struct io_data *io_data;
struct io_list *prev;
struct io_list *next;
};
extern void message(struct io_data *io_data, int messageid, int paramid, char *param2, bool isjson);
#define SOCKBUFALLOCSIZ 65536
#define io_new(init) _io_new(init, false)
#define sock_io_new() _io_new(SOCKBUFALLOCSIZ, true)
#if LOCK_TRACKING
#define LOCK_FMT_FFL " - called from %s %s():%d"
#define LOCKMSG(fmt, ...) fprintf(stderr, "APILOCK: " fmt "\n", ##__VA_ARGS__)
#define LOCKMSGMORE(fmt, ...) fprintf(stderr, " " fmt "\n", ##__VA_ARGS__)
#define LOCKMSGFFL(fmt, ...) fprintf(stderr, "APILOCK: " fmt LOCK_FMT_FFL "\n", ##__VA_ARGS__, file, func, linenum)
#define LOCKMSGFLUSH() fflush(stderr)
typedef struct lockstat {
uint64_t lock_id;
const char *file;
const char *func;
int linenum;
struct timeval tv;
} LOCKSTAT;
typedef struct lockline {
struct lockline *prev;
struct lockstat *stat;
struct lockline *next;
} LOCKLINE;
typedef struct lockinfo {
void *lock;
enum cglock_typ typ;
const char *file;
const char *func;
int linenum;
uint64_t gets;
uint64_t gots;
uint64_t tries;
uint64_t dids;
uint64_t didnts; // should be tries - dids
uint64_t unlocks;
LOCKSTAT lastgot;
LOCKLINE *lockgets;
LOCKLINE *locktries;
} LOCKINFO;
typedef struct locklist {
LOCKINFO *info;
struct locklist *next;
} LOCKLIST;
#endif
#endif /* API_H */

2862
config_parser.c

File diff suppressed because it is too large Load Diff

63
config_parser.h

@ -8,34 +8,34 @@ @@ -8,34 +8,34 @@
//helper to check for empty or NULL strings
#ifndef empty_string
#define empty_string(str) ((str && str[0] != '\0')?0:1)
#define empty_string(str) ((str && str[0] != '\0')?0:1)
#endif
//helper function to get a gpu option value
#ifndef gpu_opt
#define gpu_opt(i,optname) gpus[i].optname
#define gpu_opt(i,optname) gpus[i].optname
#endif
//profile structure
struct profile {
int profile_no;
char *name;
int profile_no;
char *name;
algorithm_t algorithm;
const char *devices;
const char *intensity;
const char *xintensity;
const char *rawintensity;
const char *lookup_gap;
const char *gpu_engine;
const char *gpu_memclock;
const char *gpu_threads;
const char *gpu_fan;
const char *gpu_powertune;
const char *gpu_vddc;
const char *shaders;
const char *thread_concurrency;
const char *worksize;
algorithm_t algorithm;
const char *devices;
const char *intensity;
const char *xintensity;
const char *rawintensity;
const char *lookup_gap;
const char *gpu_engine;
const char *gpu_memclock;
const char *gpu_threads;
const char *gpu_fan;
const char *gpu_powertune;
const char *gpu_vddc;
const char *shaders;
const char *thread_concurrency;
const char *worksize;
};
/* globals needed outside */
@ -57,12 +57,12 @@ extern char *set_default_xintensity(const char *arg); @@ -57,12 +57,12 @@ extern char *set_default_xintensity(const char *arg);
extern char *set_default_rawintensity(const char *arg);
extern char *set_default_thread_concurrency(const char *arg);
#ifdef HAVE_ADL
extern char *set_default_gpu_engine(const char *arg);
extern char *set_default_gpu_memclock(const char *arg);
extern char *set_default_gpu_threads(const char *arg);
extern char *set_default_gpu_fan(const char *arg);
extern char *set_default_gpu_powertune(const char *arg);
extern char *set_default_gpu_vddc(const char *arg);
extern char *set_default_gpu_engine(const char *arg);
extern char *set_default_gpu_memclock(const char *arg);
extern char *set_default_gpu_threads(const char *arg);
extern char *set_default_gpu_fan(const char *arg);
extern char *set_default_gpu_powertune(const char *arg);
extern char *set_default_gpu_vddc(const char *arg);
#endif
extern char *set_default_profile(char *arg);
extern char *set_default_shaders(const char *arg);
@ -77,12 +77,12 @@ extern char *set_profile_xintensity(const char *arg); @@ -77,12 +77,12 @@ extern char *set_profile_xintensity(const char *arg);
extern char *set_profile_rawintensity(const char *arg);
extern char *set_profile_thread_concurrency(const char *arg);
#ifdef HAVE_ADL
extern char *set_profile_gpu_engine(const char *arg);
extern char *set_profile_gpu_memclock(const char *arg);
extern char *set_profile_gpu_threads(const char *arg);
extern char *set_profile_gpu_fan(const char *arg);
extern char *set_profile_gpu_powertune(const char *arg);
extern char *set_profile_gpu_vddc(const char *arg);
extern char *set_profile_gpu_engine(const char *arg);
extern char *set_profile_gpu_memclock(const char *arg);
extern char *set_profile_gpu_threads(const char *arg);
extern char *set_profile_gpu_fan(const char *arg);
extern char *set_profile_gpu_powertune(const char *arg);
extern char *set_profile_gpu_vddc(const char *arg);
#endif
extern char *set_profile_nfactor(const char *arg);
extern char *set_profile_shaders(const char *arg);
@ -98,6 +98,7 @@ extern void load_default_config(void); @@ -98,6 +98,7 @@ extern void load_default_config(void);
extern void load_default_profile();
extern void apply_defaults();
extern void apply_pool_profiles();
extern void apply_pool_profile(struct pool *pool);
/* config writer */
extern void write_config(const char *filename);

11
doc/API → doc/API.md

@ -207,13 +207,13 @@ The list of requests - a (*) means it requires privileged access - and replies: @@ -207,13 +207,13 @@ The list of requests - a (*) means it requires privileged access - and replies:
stating the results of enabling pool N
The Msg includes the pool URL
addpool|URL,USR,PASS[,NAME,DESC,ALGO] (*)
addpool|URL,USR,PASS[,NAME,DESC,PROFILE,ALGO] (*)
none There is no reply section just the STATUS section
stating the results of attempting to add pool N
The Msg includes the pool URL
Use '\\' to get a '\' and '\,' to include a comma
inside URL, USR or PASS
Name, description and algorithm are optional
Name, description, profile and algorithm are optional
poolpriority|N,... (*)
none There is no reply section just the STATUS section
@ -235,6 +235,13 @@ The list of requests - a (*) means it requires privileged access - and replies: @@ -235,6 +235,13 @@ The list of requests - a (*) means it requires privileged access - and replies:
The Msg includes the pool URL
N.B. all details for the pool will be lost
changestrategy|STRAT,INT (*)
none There is no reply section just the STATUS section
stating the results of changing multipool strategy
to STRAT. If the strategy requested is "rotate",
the interval INT must be specified as a number
between 0 and 9999 seconds. INT is not required
otherwise.
gpuenable|N (*)
none There is no reply section just the STATUS section
stating the results of the enable request

0
doc/GPU → doc/GPU.md

6
miner.h

@ -253,7 +253,6 @@ enum alive { @@ -253,7 +253,6 @@ enum alive {
LIFE_INIT,
};
enum pool_strategy {
POOL_FAILOVER,
POOL_ROUNDROBIN,
@ -268,6 +267,9 @@ struct strategies { @@ -268,6 +267,9 @@ struct strategies {
const char *s;
};
extern enum pool_strategy pool_strategy;
extern struct strategies strategies[];
struct cgpu_info;
#ifdef HAVE_ADL
@ -1044,7 +1046,7 @@ extern bool detect_stratum(struct pool *pool, char *url); @@ -1044,7 +1046,7 @@ extern bool detect_stratum(struct pool *pool, char *url);
extern void print_summary(void);
extern void adjust_quota_gcd(void);
extern struct pool *add_pool(void);
extern bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *algo);
extern bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *profile, char *algo);
#define MAX_GPUDEVICES 16
#define MAX_DEVICES 4096

57
sgminer.c

@ -71,14 +71,6 @@ char *curly = ":D"; @@ -71,14 +71,6 @@ char *curly = ":D";
#define VERSION GIT_VERSION
#endif
struct strategies strategies[] = {
{ "Failover" },
{ "Round Robin" },
{ "Rotate" },
{ "Load Balance" },
{ "Balance" },
};
static char packagename[256];
bool opt_work_update;
@ -230,6 +222,14 @@ unsigned int total_go, total_ro; @@ -230,6 +222,14 @@ unsigned int total_go, total_ro;
struct pool **pools;
static struct pool *currentpool = NULL;
struct strategies strategies[] = {
{ "Failover" },
{ "Round Robin" },
{ "Rotate" },
{ "Load Balance" },
{ "Balance" },
};
int total_pools, enabled_pools;
enum pool_strategy pool_strategy = POOL_FAILOVER;
int opt_rotate_period;
@ -1390,6 +1390,16 @@ struct opt_table opt_config_table[] = { @@ -1390,6 +1390,16 @@ struct opt_table opt_config_table[] = {
OPT_WITHOUT_ARG("--more-notices",
opt_set_bool, &opt_morenotices,
"Shows work restart and new block notices, hidden by default"),
OPT_WITH_ARG("--intensity|-I",
set_default_intensity, NULL, NULL,
"Intensity of GPU scanning (d or " MIN_INTENSITY_STR
" -> " MAX_INTENSITY_STR
",default: d to maintain desktop interactivity), overridden by --xintensity or --rawintensity."),
OPT_WITH_ARG("--xintensity|-X",
// set_xintensity, NULL, NULL,
set_default_xintensity, NULL, NULL,
"Shader based intensity of GPU scanning (" MIN_XINTENSITY_STR " to "
MAX_XINTENSITY_STR "), overridden --xintensity|-X and --rawintensity."),
OPT_WITH_ARG("--xintensity|-X",
// set_xintensity, NULL, NULL,
set_default_xintensity, NULL, NULL,
@ -1449,7 +1459,7 @@ struct opt_table opt_config_table[] = { @@ -1449,7 +1459,7 @@ struct opt_table opt_config_table[] = {
OPT_WITHOUT_ARG("--no-submit-stale",
opt_set_invbool, &opt_submit_stale,
"Don't submit shares if they are detected as stale"),
OPT_WITHOUT_ARG("--no-extranonce-subscribe",
OPT_WITHOUT_ARG("--no-extranonce|--pool-no-extranonce",
set_no_extranonce_subscribe, NULL,
"Disable 'extranonce' stratum subscribe for pool"),
OPT_WITH_ARG("--pass|--pool-pass|-p",
@ -1628,7 +1638,7 @@ struct opt_table opt_config_table[] = { @@ -1628,7 +1638,7 @@ struct opt_table opt_config_table[] = {
OPT_WITHOUT_ARG("--show-coindiff",
opt_set_bool, &opt_show_coindiff,
"Show coin difficulty rather than hash value of a share"),
OPT_WITH_ARG("--state",
OPT_WITH_ARG("--state|--pool-state",
set_pool_state, NULL, NULL,
"Specify pool state at startup (default: enabled)"),
#ifdef HAVE_SYSLOG_H
@ -1689,7 +1699,7 @@ struct opt_table opt_config_table[] = { @@ -1689,7 +1699,7 @@ struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--worksize|-w",
set_default_worksize, NULL, NULL,
"Override detected optimal worksize - one value or comma separated list"),
OPT_WITH_ARG("--userpass|-O",
OPT_WITH_ARG("--userpass|--pool-userpass|-O",
set_userpass, NULL, NULL,
"Username:Password pair for bitcoin JSON-RPC server"),
OPT_WITHOUT_ARG("--worktime",
@ -7200,7 +7210,7 @@ static void *test_pool_thread(void *arg) @@ -7200,7 +7210,7 @@ static void *test_pool_thread(void *arg)
/* Always returns true that the pool details were added unless we are not
* live, implying this is the only pool being added, so if no pools are
* active it returns false. */
bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *algo)
bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *profile, char *algo)
{
size_t siz;
@ -7211,7 +7221,20 @@ bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char @@ -7211,7 +7221,20 @@ bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char
pool->rpc_pass = pass;
pool->name = name;
pool->description = desc;
set_algorithm(&pool->algorithm, algo);
pool->profile = profile;
//if a profile was supplied, apply pool properties from profile
if(!empty_string(profile))
apply_pool_profile(pool); //remove profile if was invalid
//if profile is empty, assign algorithm or default algorithm
if(empty_string(pool->profile))
{
if(!empty_string(algo))
set_algorithm(&pool->algorithm, algo);
else
set_algorithm(&pool->algorithm, default_profile.algorithm.name);
}
siz = strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2;
pool->rpc_userpass = (char *)malloc(siz);
@ -7236,7 +7259,7 @@ bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char @@ -7236,7 +7259,7 @@ bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char
static bool input_pool(bool live)
{
char *url = NULL, *user = NULL, *pass = NULL;
char *name = NULL, *desc = NULL, *algo = NULL;
char *name = NULL, *desc = NULL, *profile = NULL, *algo = NULL;
struct pool *pool;
bool ret = false;
@ -7254,8 +7277,10 @@ static bool input_pool(bool live) @@ -7254,8 +7277,10 @@ static bool input_pool(bool live)
if (strcmp(name, "-1") == 0) strcpy(name, "");
desc = curses_input("Description (optional)");
if (strcmp(desc, "-1") == 0) strcpy(desc, "");
algo = curses_input("Profile (optional)");
if (strcmp(profile, "-1") == 0) profile[0] = '\0';
algo = curses_input("Algorithm (optional)");
if (strcmp(algo, "-1") == 0) strcpy(algo, opt_algorithm.name);
if (strcmp(algo, "-1") == 0) algo[0] = '\0';
pool = add_pool();
@ -7273,7 +7298,7 @@ static bool input_pool(bool live) @@ -7273,7 +7298,7 @@ static bool input_pool(bool live)
}
ret = add_pool_details(pool, live, url, user, pass,
name, desc, algo);
name, desc, profile, algo);
out:
immedok(logwin, false);

Loading…
Cancel
Save