Browse Source

Merge pull request #182 from kanoi/master

api.c 'devdetails' list static details of devices + ZTex ++
nfactor-troky
Con Kolivas 13 years ago
parent
commit
8d8f4ff856
  1. 16
      README
  2. 365
      api.c
  3. 8
      cgminer.c
  4. 114
      miner.php

16
README

@ -55,6 +55,7 @@ CGMiner specific configuration options:
--disable-adl Override detection and disable building with adl --disable-adl Override detection and disable building with adl
--enable-bitforce Compile support for BitForce FPGAs(default disabled) --enable-bitforce Compile support for BitForce FPGAs(default disabled)
--enable-icarus Compile support for Icarus Board(default disabled) --enable-icarus Compile support for Icarus Board(default disabled)
--enable-ztex Compile support for Ztex Board(default disabled)
Basic *nix build instructions: Basic *nix build instructions:
To build with GPU mining support: To build with GPU mining support:
@ -193,7 +194,7 @@ GPU only options:
--worksize|-w <arg> Override detected optimal worksize - one value or comma separated list --worksize|-w <arg> Override detected optimal worksize - one value or comma separated list
FPGA mining boards(BitForce, Icarus) only options: FPGA mining boards(BitForce, Icarus, Ztex) only options:
--scan-serial|-S <arg> Serial port to probe for FPGA mining device --scan-serial|-S <arg> Serial port to probe for FPGA mining device
@ -612,7 +613,7 @@ An example request in both formats to set GPU 0 fan to 80%:
The format of each reply (unless stated otherwise) is a STATUS section The format of each reply (unless stated otherwise) is a STATUS section
followed by an optional detail section followed by an optional detail section
From API verion 1.7 onwards, reply strings in JSON and Text have the From API version 1.7 onwards, reply strings in JSON and Text have the
necessary escaping as required to avoid ambiguity - they didn't before 1.7 necessary escaping as required to avoid ambiguity - they didn't before 1.7
For JSON the 2 characters '"' and '\' are escaped with a '\' before them For JSON the 2 characters '"' and '\' are escaped with a '\' before them
For Text the 4 characters '|' ',' '=' and '\' are escaped the same way For Text the 4 characters '|' ',' '=' and '\' are escaped the same way
@ -647,7 +648,7 @@ The STATUS section is:
This defaults to the cgminer version but is the value of --api-description This defaults to the cgminer version but is the value of --api-description
if it was specified at runtime. if it was specified at runtime.
For API version 1.7: For API version 1.8:
The list of requests - a (*) means it requires privileged access - and replies are: The list of requests - a (*) means it requires privileged access - and replies are:
@ -772,6 +773,8 @@ The list of requests - a (*) means it requires privileged access - and replies a
reply before cgminer quits reply before cgminer quits
notify NOTIFY The last status and history count of each devices problem notify NOTIFY The last status and history count of each devices problem
This lists all devices including those not supported
by the 'devs' command
e.g. NOTIFY=0,Name=GPU,ID=0,Last Well=1332432290,...| e.g. NOTIFY=0,Name=GPU,ID=0,Last Well=1332432290,...|
privileged (*) privileged (*)
@ -791,6 +794,11 @@ The list of requests - a (*) means it requires privileged access - and replies a
stating the results of the disable request stating the results of the disable request
This is only available if PGA mining is enabled This is only available if PGA mining is enabled
devdetails DEVDETAILS Each device with a list of their static details
This lists all devices including those not supported
by the 'devs' command
e.g. DEVDETAILS=0,Name=GPU,ID=0,Driver=opencl,...|
When you enable, disable or restart a GPU or PGA, you will also get Thread messages When you enable, disable or restart a GPU or PGA, you will also get Thread messages
in the cgminer status window in the cgminer status window
@ -1052,7 +1060,7 @@ working in the logs?
A: http://us.php.net/manual/en/sockets.installation.php A: http://us.php.net/manual/en/sockets.installation.php
Q: What is a PGA? Q: What is a PGA?
A: At the moment, cgminer supports 2 FPGA's: Icarus and BitForce. A: At the moment, cgminer supports 3 FPGA's: Icarus, Ztex and BitForce.
They are Field-Programmable Gate Arrays that have been programmed to do Bitcoin They are Field-Programmable Gate Arrays that have been programmed to do Bitcoin
mining. Since the acronym needs to be only 3 characters, the "Field-" part has mining. Since the acronym needs to be only 3 characters, the "Field-" part has
been skipped. been skipped.

365
api.c

@ -152,12 +152,13 @@ static SOCKETTYPE sock = INVSOCK;
static const char *UNAVAILABLE = " - API will not be available"; static const char *UNAVAILABLE = " - API will not be available";
//static const char *BLANK = ""; static const char *BLANK = "";
static const char *COMMA = ","; static const char *COMMA = ",";
static const char SEPARATOR = '|'; static const char SEPARATOR = '|';
#define SEPSTR "|"
static const char GPUSEP = ','; static const char GPUSEP = ',';
static const char *APIVERSION = "1.7"; static const char *APIVERSION = "1.8";
static const char *DEAD = "Dead"; static const char *DEAD = "Dead";
static const char *SICK = "Sick"; static const char *SICK = "Sick";
static const char *NOSTART = "NoStart"; static const char *NOSTART = "NoStart";
@ -179,6 +180,9 @@ static const char *DEVICECODE = ""
#ifdef USE_ICARUS #ifdef USE_ICARUS
"ICA " "ICA "
#endif #endif
#ifdef USE_ZTEX
"ZTX "
#endif
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
"CPU " "CPU "
#endif #endif
@ -211,7 +215,7 @@ static const char *OSINFO =
#define _MINECON "CONFIG" #define _MINECON "CONFIG"
#define _GPU "GPU" #define _GPU "GPU"
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
#define _PGA "PGA" #define _PGA "PGA"
#endif #endif
@ -223,6 +227,7 @@ static const char *OSINFO =
#define _PGAS "PGAS" #define _PGAS "PGAS"
#define _CPUS "CPUS" #define _CPUS "CPUS"
#define _NOTIFY "NOTIFY" #define _NOTIFY "NOTIFY"
#define _DEVDETAILS "DEVDETAILS"
#define _BYE "BYE" #define _BYE "BYE"
static const char ISJSON = '{'; static const char ISJSON = '{';
@ -241,7 +246,7 @@ static const char ISJSON = '{';
#define JSON_MINECON JSON1 _MINECON JSON2 #define JSON_MINECON JSON1 _MINECON JSON2
#define JSON_GPU JSON1 _GPU JSON2 #define JSON_GPU JSON1 _GPU JSON2
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
#define JSON_PGA JSON1 _PGA JSON2 #define JSON_PGA JSON1 _PGA JSON2
#endif #endif
@ -253,6 +258,7 @@ static const char ISJSON = '{';
#define JSON_PGAS JSON1 _PGAS JSON2 #define JSON_PGAS JSON1 _PGAS JSON2
#define JSON_CPUS JSON1 _CPUS JSON2 #define JSON_CPUS JSON1 _CPUS JSON2
#define JSON_NOTIFY JSON1 _NOTIFY JSON2 #define JSON_NOTIFY JSON1 _NOTIFY JSON2
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2
#define JSON_BYE JSON1 _BYE JSON1 #define JSON_BYE JSON1 _BYE JSON1
#define JSON_CLOSE JSON3 #define JSON_CLOSE JSON3
#define JSON_END JSON4 #define JSON_END JSON4
@ -320,7 +326,7 @@ static const char *JSON_PARAMETER = "parameter";
#define MSG_TOOMANYP 54 #define MSG_TOOMANYP 54
#define MSG_ADDPOOL 55 #define MSG_ADDPOOL 55
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
#define MSG_PGANON 56 #define MSG_PGANON 56
#define MSG_PGADEV 57 #define MSG_PGADEV 57
#define MSG_INVPGA 58 #define MSG_INVPGA 58
@ -329,7 +335,7 @@ static const char *JSON_PARAMETER = "parameter";
#define MSG_NUMPGA 59 #define MSG_NUMPGA 59
#define MSG_NOTIFY 60 #define MSG_NOTIFY 60
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
#define MSG_PGALRENA 61 #define MSG_PGALRENA 61
#define MSG_PGALRDIS 62 #define MSG_PGALRDIS 62
#define MSG_PGAENA 63 #define MSG_PGAENA 63
@ -340,6 +346,7 @@ static const char *JSON_PARAMETER = "parameter";
#define MSG_REMLASTP 66 #define MSG_REMLASTP 66
#define MSG_ACTPOOL 67 #define MSG_ACTPOOL 67
#define MSG_REMPOOL 68 #define MSG_REMPOOL 68
#define MSG_DEVDETAILS 69
enum code_severity { enum code_severity {
SEVERITY_ERR, SEVERITY_ERR,
@ -385,7 +392,7 @@ struct CODES {
{ SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" }, { SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" },
{ SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)" { SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)"
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
" - %d PGA(s)" " - %d PGA(s)"
#endif #endif
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
@ -394,7 +401,7 @@ struct CODES {
}, },
{ SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs" { SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs"
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
"/PGAs" "/PGAs"
#endif #endif
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
@ -408,7 +415,7 @@ struct CODES {
{ SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" }, { SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" },
{ SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" }, { SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" },
{ SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" }, { SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" },
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
{ SEVERITY_ERR, MSG_PGANON, PARAM_NONE, "No PGAs" }, { SEVERITY_ERR, MSG_PGANON, PARAM_NONE, "No PGAs" },
{ SEVERITY_SUCC, MSG_PGADEV, PARAM_PGA, "PGA%d" }, { SEVERITY_SUCC, MSG_PGADEV, PARAM_PGA, "PGA%d" },
{ SEVERITY_ERR, MSG_INVPGA, PARAM_PGAMAX, "Invalid PGA id %d - range is 0 - %d" }, { SEVERITY_ERR, MSG_INVPGA, PARAM_PGAMAX, "Invalid PGA id %d - range is 0 - %d" },
@ -464,6 +471,7 @@ struct CODES {
{ SEVERITY_ERR, MSG_ACTPOOL, PARAM_POOL, "Cannot remove active 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_REMPOOL, PARAM_BOTH, "Removed pool %d:'%s'" },
{ SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" }, { SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
{ SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" },
{ SEVERITY_FAIL, 0, 0, NULL } { SEVERITY_FAIL, 0, 0, NULL }
}; };
@ -490,6 +498,10 @@ extern struct device_api bitforce_api;
extern struct device_api icarus_api; extern struct device_api icarus_api;
#endif #endif
#ifdef USE_ZTEX
extern struct device_api ztex_api;
#endif
// This is only called when expected to be needed (rarely) // This is only called when expected to be needed (rarely)
// i.e. strings outside of the codes control (input from the user) // i.e. strings outside of the codes control (input from the user)
static char *escape_string(char *str, bool isjson) static char *escape_string(char *str, bool isjson)
@ -552,7 +564,7 @@ static char *escape_string(char *str, bool isjson)
return buf; return buf;
} }
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
static int numpgas() static int numpgas()
{ {
int count = 0; int count = 0;
@ -566,6 +578,10 @@ static int numpgas()
#ifdef USE_ICARUS #ifdef USE_ICARUS
if (devices[i]->api == &icarus_api) if (devices[i]->api == &icarus_api)
count++; count++;
#endif
#ifdef USE_ZTEX
if (devices[i]->api == &ztex_api)
count++;
#endif #endif
} }
return count; return count;
@ -584,6 +600,10 @@ static int pgadevice(int pgaid)
#ifdef USE_ICARUS #ifdef USE_ICARUS
if (devices[i]->api == &icarus_api) if (devices[i]->api == &icarus_api)
count++; count++;
#endif
#ifdef USE_ZTEX
if (devices[i]->api == &ztex_api)
count++;
#endif #endif
if (count == (pgaid + 1)) if (count == (pgaid + 1))
return i; return i;
@ -599,7 +619,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
{ {
char severity; char severity;
char *ptr; char *ptr;
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
int pga; int pga;
#endif #endif
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
@ -625,10 +645,10 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
break; break;
} }
if (isjson) sprintf(msg_buffer, isjson
sprintf(msg_buffer, JSON_START JSON_STATUS "{\"" _STATUS "\":\"%c\",\"When\":%lu,\"Code\":%d,\"Msg\":\"", severity, (unsigned long)when, messageid); ? JSON_START JSON_STATUS "{\"" _STATUS "\":\"%c\",\"When\":%lu,\"Code\":%d,\"Msg\":\""
else : _STATUS "=%c,When=%lu,Code=%d,Msg=",
sprintf(msg_buffer, _STATUS "=%c,When=%lu,Code=%d,Msg=", severity, (unsigned long)when, messageid); severity, (unsigned long)when, messageid);
ptr = msg_buffer + strlen(msg_buffer); ptr = msg_buffer + strlen(msg_buffer);
@ -644,7 +664,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
case PARAM_GPUMAX: case PARAM_GPUMAX:
sprintf(ptr, codes[i].description, paramid, nDevs - 1); sprintf(ptr, codes[i].description, paramid, nDevs - 1);
break; break;
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
case PARAM_PGAMAX: case PARAM_PGAMAX:
pga = numpgas(); pga = numpgas();
sprintf(ptr, codes[i].description, paramid, pga - 1); sprintf(ptr, codes[i].description, paramid, pga - 1);
@ -666,7 +686,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
sprintf(ptr, codes[i].description, paramid, total_pools - 1); sprintf(ptr, codes[i].description, paramid, total_pools - 1);
break; break;
case PARAM_DMAX: case PARAM_DMAX:
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
pga = numpgas(); pga = numpgas();
#endif #endif
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
@ -677,7 +697,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
#endif #endif
sprintf(ptr, codes[i].description, nDevs sprintf(ptr, codes[i].description, nDevs
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
, pga , pga
#endif #endif
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
@ -701,35 +721,30 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
ptr = msg_buffer + strlen(msg_buffer); ptr = msg_buffer + strlen(msg_buffer);
if (isjson) sprintf(ptr, isjson
sprintf(ptr, "\",\"Description\":\"%s\"}" JSON_CLOSE, opt_api_description); ? "\",\"Description\":\"%s\"}" JSON_CLOSE
else : ",Description=%s" SEPSTR,
sprintf(ptr, ",Description=%s%c", opt_api_description, SEPARATOR); opt_api_description);
return msg_buffer; return msg_buffer;
} }
} }
if (isjson) sprintf(msg_buffer, isjson
sprintf(msg_buffer, JSON_START JSON_STATUS "{\"" _STATUS "\":\"F\",\"When\":%lu,\"Code\":-1,\"Msg\":\"%d\",\"Description\":\"%s\"}" JSON_CLOSE, ? JSON_START JSON_STATUS "{\"" _STATUS "\":\"F\",\"When\":%lu,\"Code\":-1,\"Msg\":\"%d\",\"Description\":\"%s\"}" JSON_CLOSE
(unsigned long)when, messageid, opt_api_description); : _STATUS "=F,When=%lu,Code=-1,Msg=%d,Description=%s" SEPSTR,
else (unsigned long)when, messageid, opt_api_description);
sprintf(msg_buffer, _STATUS "=F,When=%lu,Code=-1,Msg=%d,Description=%s%c",
(unsigned long)when, messageid, opt_api_description, SEPARATOR);
return msg_buffer; return msg_buffer;
} }
static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
{ {
if (isjson) sprintf(io_buffer, isjson
sprintf(io_buffer, "%s," JSON_VERSION "{\"CGMiner\":\"%s\",\"API\":\"%s\"}" JSON_CLOSE, ? "%s," JSON_VERSION "{\"CGMiner\":\"%s\",\"API\":\"%s\"}" JSON_CLOSE
message(MSG_VERSION, 0, NULL, isjson), : "%s" _VERSION ",CGMiner=%s,API=%s" SEPSTR,
VERSION, APIVERSION); message(MSG_VERSION, 0, NULL, isjson),
else VERSION, APIVERSION);
sprintf(io_buffer, "%s" _VERSION ",CGMiner=%s,API=%s%c",
message(MSG_VERSION, 0, NULL, isjson),
VERSION, APIVERSION, SEPARATOR);
} }
static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
@ -752,7 +767,7 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
const char *adl = NO; const char *adl = NO;
#endif #endif
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
pgacount = numpgas(); pgacount = numpgas();
#endif #endif
@ -762,10 +777,12 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
strcpy(io_buffer, message(MSG_MINECON, 0, NULL, isjson)); strcpy(io_buffer, message(MSG_MINECON, 0, NULL, isjson));
if (isjson) sprintf(buf, isjson
sprintf(buf, "," JSON_MINECON "{\"GPU Count\":%d,\"PGA Count\":%d,\"CPU Count\":%d,\"Pool Count\":%d,\"ADL\":\"%s\",\"ADL in use\":\"%s\",\"Strategy\":\"%s\",\"Log Interval\":%d,\"Device Code\":\"%s\",\"OS\":\"%s\"}" JSON_CLOSE, nDevs, pgacount, cpucount, total_pools, adl, adlinuse, strategies[pool_strategy].s, opt_log_interval, DEVICECODE, OSINFO); ? "," JSON_MINECON "{\"GPU Count\":%d,\"PGA Count\":%d,\"CPU Count\":%d,\"Pool Count\":%d,\"ADL\":\"%s\",\"ADL in use\":\"%s\",\"Strategy\":\"%s\",\"Log Interval\":%d,\"Device Code\":\"%s\",\"OS\":\"%s\"}" JSON_CLOSE
else : _MINECON ",GPU Count=%d,PGA Count=%d,CPU Count=%d,Pool Count=%d,ADL=%s,ADL in use=%s,Strategy=%s,Log Interval=%d,Device Code=%s,OS=%s" SEPSTR,
sprintf(buf, _MINECON ",GPU Count=%d,PGA Count=%d,CPU Count=%d,Pool Count=%d,ADL=%s,ADL in use=%s,Strategy=%s,Log Interval=%d,Device Code=%s,OS=%s%c", nDevs, pgacount, cpucount, total_pools, adl, adlinuse, strategies[pool_strategy].s, opt_log_interval, DEVICECODE, OSINFO, SEPARATOR);
nDevs, pgacount, cpucount, total_pools, adl, adlinuse,
strategies[pool_strategy].s, opt_log_interval, DEVICECODE, OSINFO);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
@ -808,28 +825,21 @@ static void gpustatus(int gpu, bool isjson)
else else
sprintf(intensity, "%d", cgpu->intensity); sprintf(intensity, "%d", cgpu->intensity);
if (isjson) sprintf(buf, isjson
sprintf(buf, "{\"GPU\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"Fan Speed\":%d,\"Fan Percent\":%d,\"GPU Clock\":%d,\"Memory Clock\":%d,\"GPU Voltage\":%.3f,\"GPU Activity\":%d,\"Powertune\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Intensity\":\"%s\",\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}", ? "{\"GPU\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"Fan Speed\":%d,\"Fan Percent\":%d,\"GPU Clock\":%d,\"Memory Clock\":%d,\"GPU Voltage\":%.3f,\"GPU Activity\":%d,\"Powertune\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Intensity\":\"%s\",\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}"
gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt, : "GPU=%d,Enabled=%s,Status=%s,Temperature=%.2f,Fan Speed=%d,Fan Percent=%d,GPU Clock=%d,Memory Clock=%d,GPU Voltage=%.3f,GPU Activity=%d,Powertune=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Intensity=%s,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f" SEPSTR,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->utility, intensity, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, cgpu->utility, intensity,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
else (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes);
sprintf(buf, "GPU=%d,Enabled=%s,Status=%s,Temperature=%.2f,Fan Speed=%d,Fan Percent=%d,GPU Clock=%d,Memory Clock=%d,GPU Voltage=%.3f,GPU Activity=%d,Powertune=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Intensity=%s,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c",
gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->utility, intensity,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
} }
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
static void pgastatus(int pga, bool isjson) static void pgastatus(int pga, bool isjson)
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -843,6 +853,12 @@ static void pgastatus(int pga, bool isjson)
return; return;
struct cgpu_info *cgpu = devices[dev]; struct cgpu_info *cgpu = devices[dev];
double frequency = 0;
#ifdef USE_ZTEX
if (cgpu->api == &ztex_api && cgpu->device_ztex)
frequency = cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1);
#endif
cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
@ -860,22 +876,15 @@ static void pgastatus(int pga, bool isjson)
else else
status = (char *)ALIVE; status = (char *)ALIVE;
if (isjson) sprintf(buf, isjson
sprintf(buf, "{\"PGA\":%d,\"Name\":\"%s\",\"ID\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}", ? "{\"PGA\":%d,\"Name\":\"%s\",\"ID\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f,\"Frequency\":%.2f}"
pga, cgpu->api->name, cgpu->device_id, : "PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f,Frequency=%.2f" SEPSTR,
enabled, status, cgpu->temp, pga, cgpu->api->name, cgpu->device_id,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, enabled, status, cgpu->temp,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility, cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
else (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, frequency);
sprintf(buf, "PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c",
pga, cgpu->api->name, cgpu->device_id,
enabled, status, cgpu->temp,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
@ -892,22 +901,15 @@ static void cpustatus(int cpu, bool isjson)
cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
if (isjson) sprintf(buf, isjson
sprintf(buf, "{\"CPU\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}", ? "{\"CPU\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}"
cpu, cgpu->total_mhashes / total_secs, : "CPU=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f" SEPSTR,
opt_log_interval, cgpu->rolling, cpu, cgpu->total_mhashes / total_secs,
cgpu->accepted, cgpu->rejected, opt_log_interval, cgpu->rolling,
cgpu->utility, cgpu->accepted, cgpu->rejected,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, cgpu->utility,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
else (unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes);
sprintf(buf, "CPU=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c",
cpu, cgpu->total_mhashes / total_secs,
opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected,
cgpu->utility,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
@ -917,9 +919,14 @@ static void cpustatus(int cpu, bool isjson)
static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson) static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
{ {
int devcount = 0; int devcount = 0;
int numpga = 0;
int i; int i;
if (nDevs == 0 && opt_n_threads == 0) { #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
numpga = numpgas();
#endif
if (nDevs == 0 && opt_n_threads == 0 && numpga == 0) {
strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson)); strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson));
return; return;
} }
@ -940,9 +947,7 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b
devcount++; devcount++;
} }
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
int numpga = numpgas();
if (numpga > 0) if (numpga > 0)
for (i = 0; i < numpga; i++) { for (i = 0; i < numpga; i++) {
if (isjson && devcount > 0) if (isjson && devcount > 0)
@ -1003,7 +1008,7 @@ static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
strcat(io_buffer, JSON_CLOSE); strcat(io_buffer, JSON_CLOSE);
} }
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson) static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
{ {
int numpga = numpgas(); int numpga = numpgas();
@ -1207,27 +1212,18 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
rpc_url = escape_string(pool->rpc_url, isjson); rpc_url = escape_string(pool->rpc_url, isjson);
rpc_user = escape_string(pool->rpc_user, isjson); rpc_user = escape_string(pool->rpc_user, isjson);
if (isjson) sprintf(buf, isjson
sprintf(buf, "%s{\"POOL\":%d,\"URL\":\"%s\",\"Status\":\"%s\",\"Priority\":%d,\"Long Poll\":\"%s\",\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Remote Failures\":%d,\"User\":\"%s\"}", ? "%s{\"POOL\":%d,\"URL\":\"%s\",\"Status\":\"%s\",\"Priority\":%d,\"Long Poll\":\"%s\",\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Remote Failures\":%d,\"User\":\"%s\"}"
(i > 0) ? COMMA : "", : "%sPOOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d,User=%s" SEPSTR,
i, rpc_url, status, pool->prio, lp, (isjson && (i > 0)) ? COMMA : BLANK,
pool->getwork_requested, i, rpc_url, status, pool->prio, lp,
pool->accepted, pool->rejected, pool->getwork_requested,
pool->discarded_work, pool->accepted, pool->rejected,
pool->stale_shares, pool->discarded_work,
pool->getfail_occasions, pool->stale_shares,
pool->remotefail_occasions, pool->getfail_occasions,
rpc_user); pool->remotefail_occasions,
else rpc_user);
sprintf(buf, "POOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d,User=%s%c",
i, rpc_url, status, pool->prio, lp,
pool->getwork_requested,
pool->accepted, pool->rejected,
pool->discarded_work,
pool->stale_shares,
pool->getfail_occasions,
pool->remotefail_occasions,
rpc_user, SEPARATOR);
strcat(io_buffer, buf); strcat(io_buffer, buf);
@ -1258,35 +1254,23 @@ static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo
mhs = total_mhashes_done / total_secs; mhs = total_mhashes_done / total_secs;
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
if (isjson) sprintf(io_buffer, isjson
sprintf(io_buffer, "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"Algorithm\":\"%s\",\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE, ? "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"Algorithm\":\"%s\",\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE
message(MSG_SUMM, 0, NULL, isjson), : "%s" _SUMMARY ",Elapsed=%.0f,Algorithm=%s,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f" SEPSTR,
total_secs, algo, mhs, found_blocks, message(MSG_SUMM, 0, NULL, isjson),
total_getworks, total_accepted, total_rejected, total_secs, algo, mhs, found_blocks,
hw_errors, utility, total_discarded, total_stale, total_getworks, total_accepted, total_rejected,
total_go, local_work, total_ro, new_blocks, total_mhashes_done); hw_errors, utility, total_discarded, total_stale,
else total_go, local_work, total_ro, new_blocks, total_mhashes_done);
sprintf(io_buffer, "%s" _SUMMARY ",Elapsed=%.0f,Algorithm=%s,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f%c",
message(MSG_SUMM, 0, NULL, isjson),
total_secs, algo, mhs, found_blocks,
total_getworks, total_accepted, total_rejected,
hw_errors, utility, total_discarded, total_stale,
total_go, local_work, total_ro, new_blocks, total_mhashes_done, SEPARATOR);
#else #else
if (isjson) sprintf(io_buffer, isjson
sprintf(io_buffer, "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE, ? "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE
message(MSG_SUMM, 0, NULL, isjson), : "%s" _SUMMARY ",Elapsed=%.0f,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f" SEPSTR,
total_secs, mhs, found_blocks, message(MSG_SUMM, 0, NULL, isjson),
total_getworks, total_accepted, total_rejected, total_secs, mhs, found_blocks,
hw_errors, utility, total_discarded, total_stale, total_getworks, total_accepted, total_rejected,
total_go, local_work, total_ro, new_blocks, total_mhashes_done); hw_errors, utility, total_discarded, total_stale,
else total_go, local_work, total_ro, new_blocks, total_mhashes_done);
sprintf(io_buffer, "%s" _SUMMARY ",Elapsed=%.0f,MHS av=%.2f,Found Blocks=%d,Getworks=%d,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Discarded=%d,Stale=%d,Get Failures=%d,Local Work=%u,Remote Failures=%u,Network Blocks=%u,Total MH=%.4f%c",
message(MSG_SUMM, 0, NULL, isjson),
total_secs, mhs, found_blocks,
total_getworks, total_accepted, total_rejected,
hw_errors, utility, total_discarded, total_stale,
total_go, local_work, total_ro, new_blocks, total_mhashes_done, SEPARATOR);
#endif #endif
} }
@ -1397,10 +1381,10 @@ static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
strcpy(io_buffer, message(MSG_NUMGPU, 0, NULL, isjson)); strcpy(io_buffer, message(MSG_NUMGPU, 0, NULL, isjson));
if (isjson) sprintf(buf, isjson
sprintf(buf, "," JSON_GPUS "{\"Count\":%d}" JSON_CLOSE, nDevs); ? "," JSON_GPUS "{\"Count\":%d}" JSON_CLOSE
else : _GPUS ",Count=%d" SEPSTR,
sprintf(buf, _GPUS ",Count=%d%c", nDevs, SEPARATOR); nDevs);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
@ -1410,16 +1394,16 @@ static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
char buf[BUFSIZ]; char buf[BUFSIZ];
int count = 0; int count = 0;
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
count = numpgas(); count = numpgas();
#endif #endif
strcpy(io_buffer, message(MSG_NUMPGA, 0, NULL, isjson)); strcpy(io_buffer, message(MSG_NUMPGA, 0, NULL, isjson));
if (isjson) sprintf(buf, isjson
sprintf(buf, "," JSON_PGAS "{\"Count\":%d}" JSON_CLOSE, count); ? "," JSON_PGAS "{\"Count\":%d}" JSON_CLOSE
else : _PGAS ",Count=%d" SEPSTR,
sprintf(buf, _PGAS ",Count=%d%c", count, SEPARATOR); count);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
@ -1435,10 +1419,10 @@ static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
strcpy(io_buffer, message(MSG_NUMCPU, 0, NULL, isjson)); strcpy(io_buffer, message(MSG_NUMCPU, 0, NULL, isjson));
if (isjson) sprintf(buf, isjson
sprintf(buf, "," JSON_CPUS "{\"Count\":%d}" JSON_CLOSE, count); ? "," JSON_CPUS "{\"Count\":%d}" JSON_CLOSE
else : _CPUS ",Count=%d" SEPSTR,
sprintf(buf, _CPUS ",Count=%d%c", count, SEPARATOR); count);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
@ -1890,22 +1874,16 @@ void notifystatus(int device, struct cgpu_info *cgpu, bool isjson)
// ALL counters (and only counters) must start the name with a '*' // ALL counters (and only counters) must start the name with a '*'
// Simplifies future external support for adding new counters // Simplifies future external support for adding new counters
if (isjson) sprintf(buf, isjson
sprintf(buf, "%s{\"NOTIFY\":%d,\"Name\":\"%s\",\"ID\":%d,\"Last Well\":%lu,\"Last Not Well\":%lu,\"Reason Not Well\":\"%s\",\"*Thread Fail Init\":%d,\"*Thread Zero Hash\":%d,\"*Thread Fail Queue\":%d,\"*Dev Sick Idle 60s\":%d,\"*Dev Dead Idle 600s\":%d,\"*Dev Nostart\":%d,\"*Dev Over Heat\":%d,\"*Dev Thermal Cutoff\":%d}" JSON_CLOSE, ? "%s{\"NOTIFY\":%d,\"Name\":\"%s\",\"ID\":%d,\"Last Well\":%lu,\"Last Not Well\":%lu,\"Reason Not Well\":\"%s\",\"*Thread Fail Init\":%d,\"*Thread Zero Hash\":%d,\"*Thread Fail Queue\":%d,\"*Dev Sick Idle 60s\":%d,\"*Dev Dead Idle 600s\":%d,\"*Dev Nostart\":%d,\"*Dev Over Heat\":%d,\"*Dev Thermal Cutoff\":%d}" JSON_CLOSE
device > 0 ? "," : "", device, cgpu->api->name, cgpu->device_id, : "%sNOTIFY=%d,Name=%s,ID=%d,Last Well=%lu,Last Not Well=%lu,Reason Not Well=%s,*Thread Fail Init=%d,*Thread Zero Hash=%d,*Thread Fail Queue=%d,*Dev Sick Idle 60s=%d,*Dev Dead Idle 600s=%d,*Dev Nostart=%d,*Dev Over Heat=%d,*Dev Thermal Cutoff=%d" SEPSTR,
cgpu->device_last_well, cgpu->device_last_not_well, reason, (isjson && (device > 0)) ? COMMA : BLANK,
cgpu->thread_fail_init_count, cgpu->thread_zero_hash_count, device, cgpu->api->name, cgpu->device_id,
cgpu->thread_fail_queue_count, cgpu->dev_sick_idle_60_count, cgpu->device_last_well, cgpu->device_last_not_well, reason,
cgpu->dev_dead_idle_600_count, cgpu->dev_nostart_count, cgpu->thread_fail_init_count, cgpu->thread_zero_hash_count,
cgpu->dev_over_heat_count, cgpu->dev_thermal_cutoff_count); cgpu->thread_fail_queue_count, cgpu->dev_sick_idle_60_count,
else cgpu->dev_dead_idle_600_count, cgpu->dev_nostart_count,
sprintf(buf, "NOTIFY=%d,Name=%s,ID=%d,Last Well=%lu,Last Not Well=%lu,Reason Not Well=%s,*Thread Fail Init=%d,*Thread Zero Hash=%d,*Thread Fail Queue=%d,*Dev Sick Idle 60s=%d,*Dev Dead Idle 600s=%d,*Dev Nostart=%d,*Dev Over Heat=%d,*Dev Thermal Cutoff=%d%c", cgpu->dev_over_heat_count, cgpu->dev_thermal_cutoff_count);
device, cgpu->api->name, cgpu->device_id,
cgpu->device_last_well, cgpu->device_last_not_well, reason,
cgpu->thread_fail_init_count, cgpu->thread_zero_hash_count,
cgpu->thread_fail_queue_count, cgpu->dev_sick_idle_60_count,
cgpu->dev_dead_idle_600_count, cgpu->dev_nostart_count,
cgpu->dev_over_heat_count, cgpu->dev_thermal_cutoff_count, SEPARATOR);
strcat(io_buffer, buf); strcat(io_buffer, buf);
} }
@ -1933,6 +1911,42 @@ static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool
strcat(io_buffer, JSON_CLOSE); strcat(io_buffer, JSON_CLOSE);
} }
static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
{
char buf[BUFSIZ];
struct cgpu_info *cgpu;
int i;
if (total_devices == 0) {
strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson));
return;
}
strcpy(io_buffer, message(MSG_DEVDETAILS, 0, NULL, isjson));
if (isjson) {
strcat(io_buffer, COMMA);
strcat(io_buffer, JSON_DEVDETAILS);
}
for (i = 0; i < total_devices; i++) {
cgpu = devices[i];
sprintf(buf, isjson
? "%s{\"DEVDETAILS\":%d,\"Name\":\"%s\",\"ID\":%d,\"Driver\":\"%s\",\"Kernel\":\"%s\",\"Model\":\"%s\",\"Device Path\":\"%s\"}"
: "%sDEVDETAILS=%d,Name=%s,ID=%d,Driver=%s,Kernel=%s,Model=%s,Device Path=%s" SEPSTR,
(isjson && (i > 0)) ? COMMA : BLANK,
i, cgpu->api->name, cgpu->device_id,
cgpu->api->dname, cgpu->kname ? : BLANK,
cgpu->name ? : BLANK, cgpu->device_path ? : BLANK);
strcat(io_buffer, buf);
}
if (isjson)
strcat(io_buffer, JSON_CLOSE);
}
void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson) void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
{ {
FILE *fcfg; FILE *fcfg;
@ -1977,7 +1991,7 @@ struct CMDS {
{ "gpudisable", gpudisable, true }, { "gpudisable", gpudisable, true },
{ "gpurestart", gpurestart, true }, { "gpurestart", gpurestart, true },
{ "gpu", gpudev, false }, { "gpu", gpudev, false },
#if defined(USE_BITFORCE) || defined(USE_ICARUS) #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX)
{ "pga", pgadev, false }, { "pga", pgadev, false },
{ "pgaenable", pgaenable, true }, { "pgaenable", pgaenable, true },
{ "pgadisable", pgadisable, true }, { "pgadisable", pgadisable, true },
@ -2002,6 +2016,7 @@ struct CMDS {
{ "quit", doquit, true }, { "quit", doquit, true },
{ "privileged", privileged, true }, { "privileged", privileged, true },
{ "notify", notify, false }, { "notify", notify, false },
{ "devdetails", devdetails, false },
{ NULL, NULL, false } { NULL, NULL, false }
}; };
@ -2015,7 +2030,7 @@ static void send_result(SOCKETTYPE c, bool isjson)
len = strlen(io_buffer); len = strlen(io_buffer);
applog(LOG_DEBUG, "API: send reply: (%d) '%.10s%s'", len+1, io_buffer, len > 10 ? "..." : ""); applog(LOG_DEBUG, "API: send reply: (%d) '%.10s%s'", len+1, io_buffer, len > 10 ? "..." : BLANK);
// ignore failure - it's closed immediately anyway // ignore failure - it's closed immediately anyway
n = send(c, io_buffer, len+1, 0); n = send(c, io_buffer, len+1, 0);

8
cgminer.c

@ -324,10 +324,10 @@ static void applog_and_exit(const char *fmt, ...)
} }
static pthread_mutex_t sharelog_lock; static pthread_mutex_t sharelog_lock;
FILE *sharelog_file = NULL; static FILE *sharelog_file = NULL;
static void static void sharelog(const char*disposition, const struct work*work)
sharelog(const char*disposition, const struct work*work) { {
if (!sharelog_file) if (!sharelog_file)
return; return;
@ -361,7 +361,7 @@ sharelog(const char*disposition, const struct work*work) {
free(target); free(target);
free(hash); free(hash);
free(data); free(data);
if (rv >= sizeof(s)) if (rv >= (int)(sizeof(s)))
s[sizeof(s) - 1] = '\0'; s[sizeof(s) - 1] = '\0';
else else
if (rv < 0) { if (rv < 0) {

114
miner.php

@ -1,7 +1,7 @@
<?php <?php
session_start(); session_start();
# #
global $miner, $port, $readonly, $notify, $rigs; global $miner, $port, $readonly, $notify, $rigs, $socktimeoutsec;
# #
# Don't touch these 2 - see $rigs below # Don't touch these 2 - see $rigs below
$miner = null; $miner = null;
@ -25,14 +25,30 @@ $notify = true;
# e.g. $rigs = array('127.0.0.1:4028','myrig.com:4028'); # e.g. $rigs = array('127.0.0.1:4028','myrig.com:4028');
$rigs = array('127.0.0.1:4028'); $rigs = array('127.0.0.1:4028');
# #
# This should be OK for most cases
# However, the longer it is the longer you have to wait while php
# hangs if the target cgminer isn't runnning or listening
# Feel free to increase it if your network is very slow
# Also, on some windows PHP, apparently the $usec is ignored
$socktimeoutsec = 10;
#
$here = $_SERVER['PHP_SELF']; $here = $_SERVER['PHP_SELF'];
# #
global $tablebegin, $tableend, $warnfont, $warnoff; global $tablebegin, $tableend, $warnfont, $warnoff, $dfmt;
#
$tablebegin = '<tr><td><table border=1 cellpadding=5 cellspacing=0>'; $tablebegin = '<tr><td><table border=1 cellpadding=5 cellspacing=0>';
$tableend = '</table></td></tr>'; $tableend = '</table></td></tr>';
$warnfont = '<font color=red><b>'; $warnfont = '<font color=red><b>';
$warnoff = '</b></font>'; $warnoff = '</b></font>';
$dfmt = 'H:i:s j-M-Y \U\T\CP';
#
# Ensure it is only ever shown once
global $showndate;
$showndate = false;
#
# For summary page to stop retrying failed rigs
global $rigerror;
$rigerror = array();
# #
function htmlhead($checkapi) function htmlhead($checkapi)
{ {
@ -80,7 +96,7 @@ $error = null;
# #
function getsock($addr, $port) function getsock($addr, $port)
{ {
global $error; global $error, $socktimeoutsec;
$socket = null; $socket = null;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
@ -92,6 +108,11 @@ function getsock($addr, $port)
return null; return null;
} }
// Ignore if this fails since the socket connect may work anyway
// and nothing is gained by aborting if the option cannot be set
// since we don't know in advance if it can connect
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => $socktimeoutsec, 'usec' => 0));
$res = socket_connect($socket, $addr, $port); $res = socket_connect($socket, $addr, $port);
if ($res === false) if ($res === false)
{ {
@ -203,6 +224,8 @@ function getparam($name, $both = false)
# #
function fmt($section, $name, $value) function fmt($section, $name, $value)
{ {
global $dfmt;
$errorclass = ' class=err'; $errorclass = ' class=err';
$warnclass = ' class=warn'; $warnclass = ' class=warn';
$b = '&nbsp;'; $b = '&nbsp;';
@ -325,6 +348,9 @@ function fmt($section, $name, $value)
if ($value != 'Y') if ($value != 'Y')
$class = $warnclass; $class = $warnclass;
break; break;
case 'STATUS.When':
$ret = date($dfmt, $value);
break;
} }
if ($section == 'NOTIFY' && substr($name, 0, 1) == '*' && $value != '0') if ($section == 'NOTIFY' && substr($name, 0, 1) == '*' && $value != '0')
@ -346,7 +372,7 @@ function showhead($cmd, $item, $values)
foreach ($values as $name => $value) foreach ($values as $name => $value)
{ {
if ($name == '0') if ($name == '0' or $name == '')
$name = '&nbsp;'; $name = '&nbsp;';
echo "<td valign=bottom class=h>$name</td>"; echo "<td valign=bottom class=h>$name</td>";
} }
@ -360,18 +386,22 @@ function showhead($cmd, $item, $values)
# #
function details($cmd, $list, $rig) function details($cmd, $list, $rig)
{ {
global $tablebegin, $tableend; global $tablebegin, $tableend, $dfmt;
global $poolcmd, $readonly; global $poolcmd, $readonly;
global $showndate;
$dfmt = 'H:i:s j-M-Y \U\T\CP';
$stas = array('S' => 'Success', 'W' => 'Warning', 'I' => 'Informational', 'E' => 'Error', 'F' => 'Fatal'); $stas = array('S' => 'Success', 'W' => 'Warning', 'I' => 'Informational', 'E' => 'Error', 'F' => 'Fatal');
echo $tablebegin; echo $tablebegin;
echo '<tr><td class=sta>Date: '.date($dfmt).'</td></tr>'; if ($showndate === false)
{
echo '<tr><td class=sta>Date: '.date($dfmt).'</td></tr>';
echo $tableend.$tablebegin; echo $tableend.$tablebegin;
$showndate = true;
}
if (isset($list['STATUS'])) if (isset($list['STATUS']))
{ {
@ -550,18 +580,23 @@ function process($cmds, $rig)
} }
# #
# $head is a hack but this is just a demo anyway :) # $head is a hack but this is just a demo anyway :)
function doforeach($cmd, $des, $sum, $head) function doforeach($cmd, $des, $sum, $head, $datetime)
{ {
global $miner, $port; global $miner, $port;
global $error, $readonly, $notify, $rigs; global $error, $readonly, $notify, $rigs;
global $tablebegin, $tableend, $warnfont, $warnoff; global $tablebegin, $tableend, $warnfont, $warnoff, $dfmt;
global $rigerror;
$header = $head; $header = $head;
$anss = array(); $anss = array();
$count = 0; $count = 0;
$preverr = count($rigerror);
foreach ($rigs as $rig) foreach ($rigs as $rig)
{ {
if (isset($rigerror[$rig]))
continue;
$parts = explode(':', $rig, 2); $parts = explode(':', $rig, 2);
if (count($parts) == 2) if (count($parts) == 2)
{ {
@ -574,6 +609,7 @@ function doforeach($cmd, $des, $sum, $head)
{ {
echo "<tr><td colspan=100>Error on rig $count getting $des: "; echo "<tr><td colspan=100>Error on rig $count getting $des: ";
echo $warnfont.$error.$warnoff.'</td></tr>'; echo $warnfont.$error.$warnoff.'</td></tr>';
$rigerror[$rig] = $error;
$error = null; $error = null;
} }
else else
@ -584,10 +620,56 @@ function doforeach($cmd, $des, $sum, $head)
if (count($anss) == 0) if (count($anss) == 0)
{ {
echo "<tr><td>Failed to access any rigs successfully</td></tr>"; echo '<tr><td>Failed to access any rigs successfully';
if ($preverr > 0)
echo ' (or rigs had previous errors)';
echo '</td></tr>';
return; return;
} }
if ($datetime)
{
echo '<tr><td class=sta>Date: '.date($dfmt).'</td></tr>';
echo $tableend.$tablebegin;
$dthead = array('' => 1, 'STATUS' => 1, 'Description' => 1, 'When' => 1);
showhead('', null, $dthead);
foreach ($anss as $rig => $ans)
{
echo '<tr>';
foreach ($ans as $item => $row)
{
if ($item != 'STATUS')
continue;
foreach ($dthead as $name => $x)
{
if ($name == '')
echo "<td align=right><input type=button value='Rig $rig' onclick='pr(\"?rig=$rig\",null)'></td>";
else
{
if (isset($row[$name]))
list($showvalue, $class) = fmt('STATUS', $name, $row[$name]);
else
{
$class = '';
$showvalue = '&nbsp;';
}
echo "<td$class align=right>$showvalue</td>";
}
}
}
echo '</tr>';
}
echo $tableend;
echo '<tr><td><br><br></td></tr>';
echo $tablebegin;
}
$total = array(); $total = array();
foreach ($anss as $rig => $ans) foreach ($anss as $rig => $ans)
@ -795,15 +877,15 @@ function display()
echo $tablebegin; echo $tablebegin;
$sum = array('MHS av', 'Getworks', 'Found Blocks', 'Accepted', 'Rejected', 'Discarded', 'Stale', 'Utility', 'Local Work', 'Total MH'); $sum = array('MHS av', 'Getworks', 'Found Blocks', 'Accepted', 'Rejected', 'Discarded', 'Stale', 'Utility', 'Local Work', 'Total MH');
doforeach('summary', 'summary information', $sum, array()); doforeach('summary', 'summary information', $sum, array(), true);
echo $tableend; echo $tableend;
echo '<tr><td><br><br></td></tr>'; echo '<tr><td><br><br></td></tr>';
echo $tablebegin; echo $tablebegin;
doforeach('devs', 'device list', $sum, array(''=>'','ID'=>'','Name'=>'')); doforeach('devs', 'device list', $sum, array(''=>'','ID'=>'','Name'=>''), false);
echo $tableend; echo $tableend;
echo '<tr><td><br><br></td></tr>'; echo '<tr><td><br><br></td></tr>';
echo $tablebegin; echo $tablebegin;
doforeach('pools', 'pool list', $sum, array(''=>'')); doforeach('pools', 'pool list', $sum, array(''=>''), false);
echo $tableend; echo $tableend;
} }
# #

Loading…
Cancel
Save