diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ac774d2..16b2eb88 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+# 1.7.0
+- First official Release of XMRigCC-amd #33 #3
+- Full integration of xmrigCC-amd into XMRigCCServer/Dashboard with GPUInfo / remote logging
+- Config property to enable/disable config upload on startup (--cc-upload-config-on-startup) #80
+- Refactoring of remote logging feature: #143
+ - Only deltas will be send to the XMRigCCServer
+ - Fetching miner log on dashboard upon need
+ - Maximum lines of log history kept per miner can be configured on XMRigCCServer
+- Fix correct hugepages status on Dashboard
+- Fix cpu affinity for single thread usage
# 1.6.5
- Hashrate improve -> add autodetection mode for cpu-affinity
- Hashrate improve, more stable hashrates -> refactor memory allocation
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 19ce9852..605bb52f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -211,7 +211,8 @@ endif()
if (WITH_CC_SERVER OR WITH_CC_CLIENT)
set(SOURCES_CC_COMMON
src/cc/ControlCommand.cpp
- src/cc/ClientStatus.cpp)
+ src/cc/ClientStatus.cpp
+ src/cc/GPUInfo.cpp)
else()
add_definitions(/DXMRIG_NO_CC)
endif()
diff --git a/Dockerfile b/Dockerfile
index ca0f4d05..59ceab4f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
FROM ubuntu:latest
RUN apt-get update && \
- apt install software-properties-common git build-essential libbz2-dev cmake libuv1-dev libssl-dev wget gcc g++ -y && \
+ apt install git build-essential libbz2-dev cmake libuv1-dev libssl-dev wget gcc g++ -y && \
apt clean && \
rm -rf /var/lib/apt/lists/*
diff --git a/README.md b/README.md
index cacc5bc9..cd47375a 100644
--- a/README.md
+++ b/README.md
@@ -105,6 +105,7 @@ xmrigCCServer --cc-port=3344 --cc-user=admin --cc-pass=pass --cc-access-token=SE
--cc-key-file=FILE when tls is turned on, use this to point to the right key file (default: server.key)
--cc-client-config-folder=FOLDER Folder contains the client config files
--cc-custom-dashboard=FILE loads a custom dashboard and serve it to '/'
+ --cc-client-log-lines-history=N maximum lines of log history kept per miner (default: 100)
--no-color disable colored output
-S, --syslog use system log for output messages
-B, --background run the miner in the background
@@ -157,7 +158,7 @@ xmrigDaemon -o pool.minemonero.pro:5555 -u YOUR_WALLET -p x -k --cc-url=IP_OF_CC
--cc-worker-id=ID custom worker-id for CC Server
--cc-update-interval-s=N status update interval in seconds (default: 10 min: 1)
--cc-use-remote-logging enable remote logging on CC Server
- --cc-remote-logging-max-rows=N maximum last n-log rows to send CC Server
+ --cc-upload-config-on-startup upload current miner config to CC Server on startup
--no-color disable colored output
-S, --syslog use system log for output messages
-B, --background run the miner in the background
diff --git a/appveyor.yml b/appveyor.yml
index 40ac70f4..80ff01d3 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,5 @@
# version format
-version: 1.6.{build}
+version: 1.7.{build}
# build only tags
skip_non_tags: true
diff --git a/index.html b/index.html
index 2c6d5613..811567d7 100644
--- a/index.html
+++ b/index.html
@@ -411,15 +411,24 @@
var data = table.row( $(this).parents('tr') ).data();
var clientId = data['client_status']['client_id'];
var clientIp = data['client_status']['external_ip'];
- var log = data['client_status']['log'];
- var htmlContent = "
" +
- "Log of: " + clientId + " (" + clientIp + ") "+
- "" +
- "
";
+ $.ajax({
+ type: "GET",
+ url: "/admin/getClientLog?clientId=" + clientId,
+ dataType:"json",
+ success: function(data) {
+ var htmlContent = "" +
+ "Log of: " + clientId + " (" + clientIp + ") "+
+ "" +
+ "
";
- $('#minerLog').find('.modal-body').html(htmlContent);
- $('#minerLog').modal('show');
+ $('#minerLog').find('.modal-body').html(htmlContent);
+ $('#minerLog').modal('show');
+ },
+ error: function (data) {
+ setError('Unable to fetch ' + clientId + ' log. - Please make sure it is enabled on the miner!');
+ }
+ });
});
$('#minerLogRefresh').click(function(event) {
@@ -429,9 +438,17 @@
var row = table.row(index);
var data = row.data();
- if (clientId === data.client_status.client_id) {
- $('#log').val(data.client_status.log);
- }
+ $.ajax({
+ type: "GET",
+ url: "/admin/getClientLog?clientId=" + clientId,
+ dataType:"json",
+ success: function(data) {
+ $('#log').val(data.client_log);
+ },
+ error: function (data) {
+ setError('Unable to fetch ' + clientId + ' log. - Please make sure it is enabled on the miner!');
+ }
+ });
});
});
@@ -573,6 +590,18 @@
tooltip += "Used Threads: " + row.client_status.current_threads;
tooltip += (row.client_status.hash_factor > 1 ? " [" + row.client_status.hash_factor + "x multi hash mode]" :"");
tooltip += '\n';
+
+ if (row.client_status.gpu_info_list) {
+ for (var id in row.client_status.gpu_info_list) {
+ tooltip += "GPU #" + row.client_status.gpu_info_list[id].gpu_info.device_idx + ": ";
+ tooltip += row.client_status.gpu_info_list[id].gpu_info.name + ", "
+ tooltip += "intensity: " + row.client_status.gpu_info_list[id].gpu_info.raw_intensity + " ";
+ tooltip += "("+ row.client_status.gpu_info_list[id].gpu_info.work_size + "/" + row.client_status.gpu_info_list[id].gpu_info.max_work_size + "), ";
+ tooltip += "cu: " + row.client_status.gpu_info_list[id].gpu_info.compute_units;
+ tooltip += '\n';
+ }
+ }
+
tooltip += "Client IP: " + row.client_status.external_ip;
tooltip += '\n';
tooltip += "Version: " + row.client_status.version;
diff --git a/src/App.cpp b/src/App.cpp
index 53c10f21..0b549eda 100644
--- a/src/App.cpp
+++ b/src/App.cpp
@@ -90,7 +90,8 @@ App::App(int argc, char **argv) :
}
if (m_options->ccUseRemoteLogging()) {
- Log::add(new RemoteLog(m_options->ccRemoteLoggingMaxRows()));
+ // 20 lines per second should be enough
+ Log::add(new RemoteLog(static_cast(m_options->ccUpdateInterval() * 20)));
}
# ifdef HAVE_SYSLOG_H
diff --git a/src/Options.cpp b/src/Options.cpp
index 11812ddd..6a69fade 100644
--- a/src/Options.cpp
+++ b/src/Options.cpp
@@ -98,7 +98,7 @@ Options:\n"
--cc-worker-id=ID custom worker-id for CC Server\n\
--cc-update-interval-s=N status update interval in seconds (default: 10 min: 1)\n\
--cc-use-remote-logging enable remote logging on CC Server\n\
- --cc-remote-logging-max-rows=N maximum last n-log rows to send CC Server\n"
+ --cc-upload-config-on-startup upload current miner config to CC Server on startup\n"
# endif
# endif
@@ -111,6 +111,7 @@ Options:\n"
--cc-use-tls enable tls encryption for CC communication\n\
--cc-cert-file=FILE when tls is turned on, use this to point to the right cert file (default: server.pem) \n\
--cc-key-file=FILE when tls is turned on, use this to point to the right key file (default: server.key) \n\
+ --cc-client-log-lines-history=N maximum lines of log history kept per miner (default: 100)\n\
--cc-client-config-folder=FOLDER Folder contains the client config files\n\
--cc-custom-dashboard=FILE loads a custom dashboard and serve it to '/'\n"
# endif
@@ -182,8 +183,9 @@ static struct option const options[] = {
{ "cc-cert-file", 1, nullptr, 4014 },
{ "cc-key-file", 1, nullptr, 4015 },
{ "cc-use-tls", 0, nullptr, 4016 },
- { "cc-use-remote-logging", 0, nullptr, 4017 },
- { "cc-remote-logging-max-rows", 1, nullptr, 4018 },
+ { "cc-use-remote-logging", 0, nullptr, 4017 },
+ { "cc-client-log-lines-history", 1, nullptr, 4018 },
+ { "cc-upload-config-on-startup", 0, nullptr, 4019 },
{ "daemonized", 0, nullptr, 4011 },
{ "doublehash-thread-mask", 1, nullptr, 4013 },
{ "multihash-thread-mask", 1, nullptr, 4013 },
@@ -246,7 +248,7 @@ static struct option const cc_client_options[] = {
{ "update-interval-s", 1, nullptr, 4012 },
{ "use-tls", 0, nullptr, 4016 },
{ "use-remote-logging", 0, nullptr, 4017 },
- { "remote-logging-max-rows",1, nullptr, 4018 },
+ { "upload-config-on-startup", 0, nullptr, 4019 },
{ nullptr, 0, nullptr, 0 }
};
@@ -260,6 +262,7 @@ static struct option const cc_server_options[] = {
{ "cert-file", 1, nullptr, 4014 },
{ "key-file", 1, nullptr, 4015 },
{ "use-tls", 0, nullptr, 4016 },
+ { "client-log-lines-history", 1, nullptr, 4018 },
{ nullptr, 0, nullptr, 0 }
};
@@ -320,7 +323,8 @@ Options::Options(int argc, char **argv) :
m_daemonized(false),
m_ccUseTls(false),
m_ccUseRemoteLogging(true),
- m_configFile(Platform::defaultConfigName()),
+ m_ccUploadConfigOnStartup(true),
+ m_fileName(Platform::defaultConfigName()),
m_apiToken(nullptr),
m_apiWorkerId(nullptr),
m_logFile(nullptr),
@@ -349,12 +353,14 @@ Options::Options(int argc, char **argv) :
m_threads(0),
m_ccUpdateInterval(10),
m_ccPort(0),
- m_ccRemoteLoggingMaxRows(25),
+ m_ccClientLogLinesHistory(100),
m_affinity(-1L),
m_multiHashThreadMask(-1L)
{
m_pools.push_back(new Url());
+ parseConfig(Platform::defaultConfigName());
+
int key;
while (true) {
@@ -374,10 +380,6 @@ Options::Options(int argc, char **argv) :
}
#ifdef XMRIG_CC_SERVER
- if (m_ccPort == 0) {
- parseConfig(Platform::defaultConfigName());
- }
-
if (m_ccPort == 0) {
fprintf(stderr, "No CC Server Port supplied. Exiting.\n");
return;
@@ -390,10 +392,6 @@ Options::Options(int argc, char **argv) :
}
#endif
- if (!m_pools[0]->isValid()) {
- parseConfig(Platform::defaultConfigName());
- }
-
if (!m_pools[0]->isValid() && (!m_ccHost || m_ccPort == 0)) {
fprintf(stderr, "Neither pool nor CCServer URL supplied. Exiting.\n");
return;
@@ -562,7 +560,7 @@ bool Options::parseArg(int key, const char *arg)
case 4006: /* --cc-port */
case 4012: /* --cc-update-interval-c */
return parseArg(key, strtol(arg, nullptr, 10));
- case 4018: /* --cc-remote-logging-max-rows */
+ case 4018: /* --cc-client-log-lines-history */
return parseArg(key, strtol(arg, nullptr, 25));
case 'B': /* --background */
@@ -587,6 +585,9 @@ bool Options::parseArg(int key, const char *arg)
case 4017: /* --cc-use-remote-logging */
return parseBoolean(key, true);
+ case 4019: /* --cc-upload-config-on-startup */
+ return parseBoolean(key, true);
+
case 't': /* --threads */
if (strncmp(arg, "all", 3) == 0) {
m_threads = Cpu::threads();
@@ -762,13 +763,8 @@ bool Options::parseArg(int key, uint64_t arg)
}
break;
- case 4018: /* --cc-remote-logging-max-rows */
- if (arg < 1) {
- m_ccUseRemoteLogging = false;
- }
- else {
- m_ccRemoteLoggingMaxRows = (int) arg;
- }
+ case 4018: /* --cc-client-log-lines-history */
+ m_ccClientLogLinesHistory = (int) arg;
break;
default:
@@ -828,6 +824,10 @@ bool Options::parseBoolean(int key, bool enable)
m_ccUseRemoteLogging = enable;
break;
+ case 4019: /* --cc-upload-config-on-startup */
+ m_ccUploadConfigOnStartup = enable;
+ break;
+
default:
break;
}
@@ -850,7 +850,7 @@ Url *Options::parseUrl(const char *arg) const
void Options::parseConfig(const char *fileName)
{
- m_configFile = fileName;
+ m_fileName = fileName;
rapidjson::Document doc;
if (!getJSON(fileName, doc)) {
diff --git a/src/Options.h b/src/Options.h
index 197092a3..39d26ffd 100644
--- a/src/Options.h
+++ b/src/Options.h
@@ -73,7 +73,8 @@ public:
inline bool daemonized() const { return m_daemonized; }
inline bool ccUseTls() const { return m_ccUseTls; }
inline bool ccUseRemoteLogging() const { return m_ccUseRemoteLogging; }
- inline const char *configFile() const { return m_configFile; }
+ inline bool ccUploadConfigOnStartup() const { return m_ccUploadConfigOnStartup; }
+ inline const char *fileName() const { return m_fileName; }
inline const char *apiToken() const { return m_apiToken; }
inline const char *apiWorkerId() const { return m_apiWorkerId; }
inline const char *logFile() const { return m_logFile; }
@@ -101,7 +102,7 @@ public:
inline size_t threads() const { return m_threads; }
inline int ccUpdateInterval() const { return m_ccUpdateInterval; }
inline int ccPort() const { return m_ccPort; }
- inline size_t ccRemoteLoggingMaxRows() const { return m_ccRemoteLoggingMaxRows; }
+ inline size_t ccClientLogLinesHistory() const { return m_ccClientLogLinesHistory; }
inline int64_t affinity() const { return m_affinity; }
inline int64_t multiHashThreadMask() const { return m_multiHashThreadMask; }
inline void setColors(bool colors) { m_colors = colors; }
@@ -147,7 +148,8 @@ private:
bool m_daemonized;
bool m_ccUseTls;
bool m_ccUseRemoteLogging;
- const char* m_configFile;
+ bool m_ccUploadConfigOnStartup;
+ const char* m_fileName;
char *m_apiToken;
char *m_apiWorkerId;
char *m_logFile;
@@ -176,7 +178,7 @@ private:
size_t m_threads;
int m_ccUpdateInterval;
int m_ccPort;
- size_t m_ccRemoteLoggingMaxRows;
+ size_t m_ccClientLogLinesHistory;
int64_t m_affinity;
int64_t m_multiHashThreadMask;
std::vector m_pools;
diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp
index 596f2731..854ecbf0 100644
--- a/src/cc/CCClient.cpp
+++ b/src/cc/CCClient.cpp
@@ -1,10 +1,4 @@
-/* XMRig
- * Copyright 2010 Jeff Garzik
- * Copyright 2012-2014 pooler
- * Copyright 2014 Lucas Jones
- * Copyright 2014-2016 Wolf9466
- * Copyright 2016 Jay D Dee
- * Copyright 2016-2017 XMRig
+/* XMRigCC
* Copyright 2017- BenDr0id
*
*
@@ -27,19 +21,28 @@
#include
#include <3rdparty/rapidjson/stringbuffer.h>
#include <3rdparty/rapidjson/prettywriter.h>
-#include
-#include
-#include
+
+#include "version.h"
+#include "api/NetworkState.h"
#include "CCClient.h"
#include "App.h"
-#include "Platform.h"
#include "Cpu.h"
-#include "Mem.h"
#include "ControlCommand.h"
-#include "api/NetworkState.h"
+#ifdef TYPE_AMD_GPU
+#include "common/log/Log.h"
+#include "common/log/RemoteLog.h"
+#include "common/Platform.h"
+#include "core/Config.h"
+#else
+#include "Mem.h"
#include "log/Log.h"
+#include "log/RemoteLog.h"
+#include "Platform.h"
+#include "api/NetworkState.h"
+#endif
+
#include "workers/Workers.h"
#include "workers/Hashrate.h"
@@ -55,8 +58,12 @@
CCClient* CCClient::m_self = nullptr;
uv_mutex_t CCClient::m_mutex;
-CCClient::CCClient(Options* options, uv_async_t* async)
- : m_options(options),
+#ifdef TYPE_AMD_GPU
+CCClient::CCClient(xmrig::Config* config, uv_async_t* async)
+#else
+CCClient::CCClient(Options* config, uv_async_t* async)
+#endif
+ : m_config(config),
m_async(async)
{
uv_mutex_init(&m_mutex);
@@ -64,8 +71,8 @@ CCClient::CCClient(Options* options, uv_async_t* async)
m_self = this;
std::string clientId;
- if (m_options->ccWorkerId()) {
- clientId = m_options->ccWorkerId();
+ if (config->ccWorkerId()) {
+ clientId =m_self->m_config->ccWorkerId();
} else {
char hostname[128];
memset(hostname, 0, sizeof(hostname));
@@ -74,27 +81,28 @@ CCClient::CCClient(Options* options, uv_async_t* async)
}
m_clientStatus.setClientId(clientId);
-
- if (m_options->algoName() != nullptr) {
- m_clientStatus.setCurrentAlgoName(m_options->algoName());
- }
-
- m_clientStatus.setHashFactor(Mem::hashFactor());
m_clientStatus.setVersion(Version::string());
m_clientStatus.setCpuBrand(Cpu::brand());
m_clientStatus.setCpuAES(Cpu::hasAES());
- m_clientStatus.setCpuSockets(Cpu::sockets());
- m_clientStatus.setCpuCores(Cpu::cores());
- m_clientStatus.setCpuThreads(Cpu::threads());
+ m_clientStatus.setCpuSockets(static_cast(Cpu::sockets()));
+ m_clientStatus.setCpuCores(static_cast(Cpu::cores()));
+ m_clientStatus.setCpuThreads(static_cast(Cpu::threads()));
m_clientStatus.setCpuX64(Cpu::isX64());
- m_clientStatus.setCpuL2(Cpu::l2());
- m_clientStatus.setCpuL3(Cpu::l3());
- m_clientStatus.setCurrentThreads(m_options->threads());
+ m_clientStatus.setCpuL2(static_cast(Cpu::l2()));
+ m_clientStatus.setCpuL3(static_cast(Cpu::l3()));
+
+#ifdef TYPE_AMD_GPU
+ m_clientStatus.setCurrentThreads(static_cast(config->threads().size()));
+ m_clientStatus.setCurrentAlgoName(config->algorithm().name());
+#else
+ m_clientStatus.setCurrentThreads(static_cast(config->threads()));
+ m_clientStatus.setCurrentAlgoName(config->algoName());
+#endif
m_startTime = std::chrono::system_clock::now();
- if (m_options->ccToken() != nullptr) {
- m_authorization = std::string("Bearer ") + m_self->m_options->ccToken();
+ if (config->ccToken() != nullptr) {
+ m_authorization = std::string("Bearer ") + m_self->m_config->ccToken();
}
uv_thread_create(&m_thread, CCClient::onThreadStarted, this);
@@ -133,16 +141,54 @@ void CCClient::updateNetworkState(const NetworkState& network)
m_self->m_clientStatus.setHashesTotal(network.total);
m_self->m_clientStatus.setAvgTime(network.avgTime());
+#ifdef TYPE_AMD_GPU
+ m_self->m_clientStatus.setHashFactor(0);
+ m_self->m_clientStatus.setHugepagesEnabled(false);
+ m_self->m_clientStatus.setHugepages(false);
+ m_self->m_clientStatus.setTotalPages(0);
+ m_self->m_clientStatus.setTotalHugepages(0);
+ m_self->m_clientStatus.setCurrentPowVariantName(xmrig::Algorithm::getVariantName(network.powVariant));
+#else
+ m_self->m_clientStatus.setHashFactor(Mem::hashFactor());
m_self->m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled());
m_self->m_clientStatus.setHugepages(Mem::isHugepagesAvailable());
m_self->m_clientStatus.setTotalPages(Mem::getTotalPages());
m_self->m_clientStatus.setTotalHugepages(Mem::getTotalHugepages());
m_self->m_clientStatus.setCurrentPowVariantName(getPowVariantName(network.powVariant));
+#endif
uv_mutex_unlock(&m_mutex);
}
}
+#ifdef TYPE_AMD_GPU
+void CCClient::updateGpuInfo(const std::vector& gpuContext)
+{
+ if (m_self) {
+ uv_mutex_lock(&m_mutex);
+
+ m_self->m_clientStatus.clearGPUInfoList();
+
+ for (auto gpu : gpuContext) {
+ GPUInfo gpuInfo;
+ gpuInfo.setName(gpu.name);
+ gpuInfo.setCompMode(gpu.compMode);
+ gpuInfo.setComputeUnits(gpu.computeUnits);
+ gpuInfo.setDeviceIdx(gpu.deviceIdx);
+ gpuInfo.setFreeMem(gpu.freeMem);
+ gpuInfo.setWorkSize(gpu.workSize);
+ gpuInfo.setMaxWorkSize(gpu.maximumWorkSize);
+ gpuInfo.setMemChunk(gpu.memChunk);
+ gpuInfo.setRawIntensity(gpu.rawIntensity);
+
+ m_self->m_clientStatus.addGPUInfo(gpuInfo);
+ }
+
+ uv_mutex_unlock(&m_mutex);
+ }
+}
+#endif
+
void CCClient::publishClientStatusReport()
{
std::string requestUrl = "/client/setClientStatus?clientId=" + m_self->m_clientStatus.getClientId();
@@ -151,10 +197,10 @@ void CCClient::publishClientStatusReport()
auto res = performRequest(requestUrl, requestBuffer, "POST");
if (!res) {
LOG_ERR("[CC-Client] error: unable to performRequest POST -> http://%s:%d%s",
- m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str());
+ m_self->m_config->ccHost(), m_self->m_config->ccPort(), requestUrl.c_str());
} else if (res->status != 200) {
- LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(),
- m_self->m_options->ccPort(), requestUrl.c_str());
+ LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status,m_self->m_config->ccHost(),
+ m_self->m_config->ccPort(), requestUrl.c_str());
} else {
ControlCommand controlCommand;
if (controlCommand.parseFromJsonString(res->body)) {
@@ -194,14 +240,14 @@ void CCClient::updateConfig()
auto res = performRequest(requestUrl, requestBuffer, "GET");
if (!res) {
LOG_ERR("[CC-Client] error: unable to performRequest GET -> http://%s:%d%s",
- m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str());
+ m_self->m_config->ccHost(), m_self->m_config->ccPort(), requestUrl.c_str());
} else if (res->status != 200) {
- LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(),
- m_self->m_options->ccPort(), requestUrl.c_str());
+ LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_config->ccHost(),
+ m_self->m_config->ccPort(), requestUrl.c_str());
} else {
rapidjson::Document document;
if (!document.Parse(res->body.c_str()).HasParseError()) {
- std::ofstream clientConfigFile(m_self->m_options->configFile());
+ std::ofstream clientConfigFile(m_self->m_config->fileName());
if (clientConfigFile) {
rapidjson::StringBuffer buffer(0, 65536);
rapidjson::PrettyWriter writer(buffer);
@@ -213,7 +259,7 @@ void CCClient::updateConfig()
LOG_WARN("[CC-Client] Config updated. -> trigger restart");
} else {
- LOG_ERR("[CC-Client] Not able to store client config to file %s.", m_self->m_options->configFile());
+ LOG_ERR("[CC-Client] Not able to store client config to file %s.", m_self->m_config->fileName());
}
} else {
LOG_ERR("[CC-Client] Not able to store client config. received client config is broken!");
@@ -226,7 +272,7 @@ void CCClient::publishConfig()
std::string requestUrl = "/client/setClientConfig?clientId=" + m_self->m_clientStatus.getClientId();
std::stringstream data;
- std::ifstream clientConfig(m_self->m_options->configFile());
+ std::ifstream clientConfig(m_self->m_config->fileName());
if (clientConfig) {
data << clientConfig.rdbuf();
@@ -246,16 +292,16 @@ void CCClient::publishConfig()
auto res = performRequest(requestUrl, buffer.GetString(), "POST");
if (!res) {
LOG_ERR("[CC-Client] error: unable to performRequest POST -> http://%s:%d%s",
- m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str());
+ m_self->m_config->ccHost(), m_self->m_config->ccPort(), requestUrl.c_str());
} else if (res->status != 200) {
- LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(),
- m_self->m_options->ccPort(), requestUrl.c_str());
+ LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_config->ccHost(),
+ m_self->m_config->ccPort(), requestUrl.c_str());
}
} else {
- LOG_ERR("Not able to send config. Client config %s is broken!", m_self->m_options->configFile());
+ LOG_ERR("Not able to send config. Client config %s is broken!", m_self->m_config->fileName());
}
} else {
- LOG_ERR("Not able to load client config %s. Please make sure it exists!", m_self->m_options->configFile());
+ LOG_ERR("Not able to load client config %s. Please make sure it exists!", m_self->m_config->fileName());
}
}
@@ -266,11 +312,11 @@ std::shared_ptr CCClient::performRequest(const std::string& r
std::shared_ptr cli;
# ifndef XMRIG_NO_TLS
- if (m_self->m_options->ccUseTls()) {
- cli = std::make_shared(m_self->m_options->ccHost(), m_self->m_options->ccPort(), 10);
+ if (m_self->m_config->ccUseTls()) {
+ cli = std::make_shared(m_self->m_config->ccHost(), m_self->m_config->ccPort(), 10);
} else {
# endif
- cli = std::make_shared(m_self->m_options->ccHost(), m_self->m_options->ccPort(), 10);
+ cli = std::make_shared(m_self->m_config->ccHost(), m_self->m_config->ccPort(), 10);
# ifndef XMRIG_NO_TLS
}
# endif
@@ -317,10 +363,12 @@ void CCClient::onThreadStarted(void* handle)
uv_timer_init(&m_self->m_client_loop, &m_self->m_timer);
uv_timer_start(&m_self->m_timer, CCClient::onReport,
- static_cast(m_self->m_options->ccUpdateInterval() * 1000),
- static_cast(m_self->m_options->ccUpdateInterval() * 1000));
+ static_cast(m_self->m_config->ccUpdateInterval() * 1000),
+ static_cast(m_self->m_config->ccUpdateInterval() * 1000));
- m_self->publishConfig();
+ if (m_self->m_config->ccUploadConfigOnStartup()) {
+ m_self->publishConfig();
+ }
uv_run(&m_self->m_client_loop, UV_RUN_DEFAULT);
}
diff --git a/src/cc/CCClient.h b/src/cc/CCClient.h
index 0cf2f457..289bdf2e 100644
--- a/src/cc/CCClient.h
+++ b/src/cc/CCClient.h
@@ -1,10 +1,4 @@
-/* XMRig
- * Copyright 2010 Jeff Garzik
- * Copyright 2012-2014 pooler
- * Copyright 2014 Lucas Jones
- * Copyright 2014-2016 Wolf9466
- * Copyright 2016 Jay D Dee
- * Copyright 2016-2017 XMRig
+/* XMRigCC
* Copyright 2017- BenDr0id
*
*
@@ -31,8 +25,15 @@
#include
#include
#include <3rdparty/cpp-httplib/httplib.h>
-#include "Options.h"
#include "ClientStatus.h"
+#include "version.h"
+
+#ifdef TYPE_AMD_GPU
+#include "amd/GpuContext.h"
+#include "core/Controller.h"
+#else
+#include "Options.h"
+#endif
class Hashrate;
class NetworkState;
@@ -40,7 +41,13 @@ class NetworkState;
class CCClient
{
public:
- CCClient(Options *options, uv_async_t* async);
+#ifdef TYPE_AMD_GPU
+ CCClient(xmrig::Config* m_config, uv_async_t* async);
+ static void updateGpuInfo(const std::vector& network);
+#else
+ CCClient(Options* config, uv_async_t* async);
+#endif
+
~CCClient();
static void updateHashrate(const Hashrate *hashrate);
@@ -60,7 +67,11 @@ private:
static void onThreadStarted(void *handle);
static void onReport(uv_timer_t *handle);
- const Options* m_options;
+#ifdef TYPE_AMD_GPU
+ const xmrig::Config* m_config;
+#else
+ const Options* m_config;
+#endif
static CCClient* m_self;
static uv_mutex_t m_mutex;
diff --git a/src/cc/ClientStatus.cpp b/src/cc/ClientStatus.cpp
index 1a040907..7f84d8cd 100644
--- a/src/cc/ClientStatus.cpp
+++ b/src/cc/ClientStatus.cpp
@@ -1,13 +1,6 @@
-/* XMRig
- * Copyright 2010 Jeff Garzik
- * Copyright 2012-2014 pooler
- * Copyright 2014 Lucas Jones
- * Copyright 2014-2016 Wolf9466
- * Copyright 2016 Jay D Dee
- * Copyright 2016-2017 XMRig
+/* XMRigCC
* Copyright 2017- BenDr0id
*
- *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -27,7 +20,6 @@
#include
#include <3rdparty/rapidjson/stringbuffer.h>
#include <3rdparty/rapidjson/prettywriter.h>
-#include
#include "ClientStatus.h"
@@ -150,6 +142,11 @@ void ClientStatus::setLog(const std::string& log)
m_log = log;
}
+void ClientStatus::clearLog()
+{
+ m_log.clear();
+}
+
bool ClientStatus::hasHugepages() const
{
return m_hasHugepages;
@@ -380,7 +377,7 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
if (document.HasMember("client_status"))
{
- rapidjson::Value::ConstObject clientStatus = document["client_status"].GetObject();
+ const rapidjson::Value& clientStatus = document["client_status"];
if (clientStatus.HasMember("current_status")) {
m_currentStatus = toStatus(clientStatus["current_status"].GetString());
@@ -486,6 +483,18 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
m_cpuL3 = clientStatus["cpu_l3"].GetInt();
}
+ if (clientStatus.HasMember("gpu_info_list") && clientStatus["gpu_info_list"].IsArray()) {
+ m_gpuInfoList.clear();
+
+ auto gpuInfoList = clientStatus["gpu_info_list"].GetArray();
+ for (rapidjson::Value::ConstValueIterator itr = gpuInfoList.Begin(); itr != gpuInfoList.End(); ++itr) {
+ GPUInfo gpuInfo;
+ gpuInfo.parseFromJson((*itr)["gpu_info"]);
+
+ m_gpuInfoList.push_back(gpuInfo);
+ }
+ }
+
if (clientStatus.HasMember("shares_good")) {
m_sharesGood = clientStatus["shares_good"].GetUint64();
}
@@ -510,8 +519,6 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
m_lastStatusUpdate = std::chrono::system_clock::to_time_t(time_point);
result = true;
- } else {
- LOG_ERR("Parse Error, JSON does not contain: control_command");
}
return result;
@@ -551,6 +558,14 @@ rapidjson::Value ClientStatus::toJson(rapidjson::MemoryPoolAllocator(m_lastStatusUpdate), allocator);
-
clientStatus.AddMember("log", rapidjson::StringRef(m_log.c_str()), allocator);
@@ -584,3 +597,13 @@ std::string ClientStatus::toJsonString()
return strdup(buffer.GetString());
}
+
+void ClientStatus::clearGPUInfoList()
+{
+ m_gpuInfoList.clear();
+}
+
+void ClientStatus::addGPUInfo(const GPUInfo gpuInfo)
+{
+ m_gpuInfoList.push_back(gpuInfo);
+}
diff --git a/src/cc/ClientStatus.h b/src/cc/ClientStatus.h
index 66a9b6f2..65eb1ed2 100644
--- a/src/cc/ClientStatus.h
+++ b/src/cc/ClientStatus.h
@@ -1,10 +1,4 @@
-/* XMRig
- * Copyright 2010 Jeff Garzik
- * Copyright 2012-2014 pooler
- * Copyright 2014 Lucas Jones
- * Copyright 2014-2016 Wolf9466
- * Copyright 2016 Jay D Dee
- * Copyright 2016-2017 XMRig
+/* XMRigCC
* Copyright 2017- BenDr0id
*
*
@@ -27,7 +21,9 @@
#include
#include
+#include
#include
+#include "GPUInfo.h"
class ClientStatus
{
@@ -82,7 +78,8 @@ public:
void setVersion(const std::string& version);
std::string getLog() const;
- void setLog(const std::string& version);
+ void setLog(const std::string& log);
+ void clearLog();
bool hasHugepages() const;
void setHugepages(bool hasHugepages);
@@ -135,6 +132,10 @@ public:
int getCpuL3() const;
void setCpuL3(int cpuL3);
+ const std::list getGPUInfoList() const;
+ void addGPUInfo(const GPUInfo gpuInfo);
+ void clearGPUInfoList();
+
uint64_t getSharesGood() const;
void setSharesGood(uint64_t sharesGood);
@@ -156,7 +157,6 @@ public:
rapidjson::Value toJson(rapidjson::MemoryPoolAllocator& allocator);
bool parseFromJson(const rapidjson::Document& document);
-
private:
const char* status_str[3] = {
"RUNNING",
@@ -195,6 +195,8 @@ private:
int m_cpuL2;
int m_cpuL3;
+ std::list m_gpuInfoList;
+
uint64_t m_sharesGood;
uint64_t m_sharesTotal;
uint64_t m_hashesTotal;
diff --git a/src/cc/ControlCommand.cpp b/src/cc/ControlCommand.cpp
index a7cd663e..afdda3dd 100644
--- a/src/cc/ControlCommand.cpp
+++ b/src/cc/ControlCommand.cpp
@@ -1,13 +1,6 @@
-/* XMRig
- * Copyright 2010 Jeff Garzik
- * Copyright 2012-2014 pooler
- * Copyright 2014 Lucas Jones
- * Copyright 2014-2016 Wolf9466
- * Copyright 2016 Jay D Dee
- * Copyright 2016-2017 XMRig
+/* XMRigCC
* Copyright 2017- BenDr0id
*
- *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -22,12 +15,20 @@
* along with this program. If not, see .
*/
+#include
#include <3rdparty/rapidjson/stringbuffer.h>
#include <3rdparty/rapidjson/prettywriter.h>
-#include "log/Log.h"
#include "ControlCommand.h"
+#include "version.h"
+
+#ifdef TYPE_AMD_GPU
+#include "common/log/Log.h"
+#else
+#include "log/Log.h"
+#endif
+
ControlCommand::ControlCommand()
: m_command(Command::START)
{
@@ -57,7 +58,7 @@ bool ControlCommand::parseFromJson(const rapidjson::Document& document)
bool result = false;
if (document.HasMember("control_command")) {
- rapidjson::Value::ConstObject controlCommand = document["control_command"].GetObject();
+ const rapidjson::Value& controlCommand = document["control_command"];
if (controlCommand.HasMember("command")) {
m_command = toCommand(controlCommand["command"].GetString());
result = true;
@@ -81,7 +82,7 @@ rapidjson::Value ControlCommand::toJson(rapidjson::MemoryPoolAllocator
- * Copyright 2012-2014 pooler
- * Copyright 2014 Lucas Jones
- * Copyright 2014-2016 Wolf9466
- * Copyright 2016 Jay D Dee
- * Copyright 2016-2017 XMRig
+/* XMRigCC
* Copyright 2017- BenDr0id
*
- *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -74,7 +67,7 @@ public:
bool parseFromJson(const rapidjson::Document& document);
Command getCommand() const;
- void setCommand(Command command);
+ void setCommand(const Command& command);
bool isOneTimeCommand() const;
diff --git a/src/cc/GPUInfo.cpp b/src/cc/GPUInfo.cpp
new file mode 100644
index 00000000..72ba83f9
--- /dev/null
+++ b/src/cc/GPUInfo.cpp
@@ -0,0 +1,187 @@
+/* XMRigCC
+ * Copyright 2018- BenDr0id
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "GPUInfo.h"
+
+GPUInfo::GPUInfo()
+ : m_deviceIdx(0),
+ m_rawIntensity(0),
+ m_workSize(0),
+ m_maxWorkSize(0),
+ m_freeMem(0),
+ m_memChunk(0),
+ m_compMode(0),
+ m_computeUnits(0)
+{
+
+}
+
+GPUInfo::~GPUInfo()
+{
+
+}
+
+rapidjson::Value GPUInfo::toJson(rapidjson::MemoryPoolAllocator & allocator)
+{
+ rapidjson::Value gpuInfo(rapidjson::kObjectType);
+
+ gpuInfo.AddMember("name", rapidjson::StringRef(m_name.c_str()), allocator);
+ gpuInfo.AddMember("device_idx", m_deviceIdx, allocator);
+ gpuInfo.AddMember("raw_intensity", m_rawIntensity, allocator);
+ gpuInfo.AddMember("work_size", m_workSize, allocator);
+ gpuInfo.AddMember("max_work_size", m_maxWorkSize, allocator);
+ gpuInfo.AddMember("free_mem", m_freeMem, allocator);
+ gpuInfo.AddMember("mem_chunk", m_memChunk, allocator);
+ gpuInfo.AddMember("comp_mode", m_memChunk, allocator);
+ gpuInfo.AddMember("compute_units", m_memChunk, allocator);
+
+ return gpuInfo;
+}
+
+bool GPUInfo::parseFromJson(const rapidjson::Value& gpuInfo)
+{
+ bool result = false;
+
+ if (gpuInfo.HasMember("name")) {
+ m_name = gpuInfo["name"].GetString();
+ result = true;
+ }
+
+ if (gpuInfo.HasMember("device_idx")) {
+ m_deviceIdx = static_cast(gpuInfo["device_idx"].GetInt());
+ }
+
+ if (gpuInfo.HasMember("raw_intensity")) {
+ m_rawIntensity = static_cast(gpuInfo["raw_intensity"].GetInt());
+ }
+
+ if (gpuInfo.HasMember("work_size")) {
+ m_workSize = static_cast(gpuInfo["work_size"].GetInt());
+ }
+
+ if (gpuInfo.HasMember("max_work_size")) {
+ m_maxWorkSize = static_cast(gpuInfo["max_work_size"].GetInt());
+ }
+
+ if (gpuInfo.HasMember("free_mem")) {
+ m_freeMem = static_cast(gpuInfo["free_mem"].GetInt());
+ }
+
+ if (gpuInfo.HasMember("mem_chunk")) {
+ m_memChunk = gpuInfo["mem_chunk"].GetInt();
+ }
+
+ if (gpuInfo.HasMember("comp_mode")) {
+ m_compMode = gpuInfo["comp_mode"].GetInt();
+ }
+
+ if (gpuInfo.HasMember("compute_units")) {
+ m_computeUnits = gpuInfo["compute_units"].GetInt();
+ }
+
+ return result;
+}
+
+size_t GPUInfo::getDeviceIdx() const
+{
+ return m_deviceIdx;
+}
+
+void GPUInfo::setDeviceIdx(size_t deviceIdx)
+{
+ m_deviceIdx = deviceIdx;
+}
+
+size_t GPUInfo::getRawIntensity() const
+{
+ return m_rawIntensity;
+}
+
+void GPUInfo::setRawIntensity(size_t rawIntensity)
+{
+ m_rawIntensity = rawIntensity;
+}
+
+size_t GPUInfo::getWorkSize() const
+{
+ return m_workSize;
+}
+
+void GPUInfo::setWorkSize(size_t workSize)
+{
+ m_workSize = workSize;
+}
+
+size_t GPUInfo::getMaxWorkSize() const
+{
+ return m_maxWorkSize;
+}
+
+void GPUInfo::setMaxWorkSize(size_t maxWorkSize)
+{
+ m_maxWorkSize = maxWorkSize;
+}
+
+size_t GPUInfo::getFreeMem() const
+{
+ return m_freeMem;
+}
+
+void GPUInfo::setFreeMem(size_t freeMem)
+{
+ m_freeMem = freeMem;
+}
+
+int GPUInfo::getMemChunk() const
+{
+ return m_memChunk;
+}
+
+void GPUInfo::setMemChunk(int memChunk)
+{
+ m_memChunk = memChunk;
+}
+
+int GPUInfo::getCompMode() const
+{
+ return m_compMode;
+}
+
+void GPUInfo::setCompMode(int compMode)
+{
+ m_compMode = compMode;
+}
+
+int GPUInfo::getComputeUnits() const
+{
+ return m_computeUnits;
+}
+
+void GPUInfo::setComputeUnits(int computeUnits)
+{
+ m_computeUnits = computeUnits;
+}
+
+std::string GPUInfo::getName() const
+{
+ return m_name;
+}
+
+void GPUInfo::setName(const std::string& name)
+{
+ m_name = name;
+}
diff --git a/src/cc/GPUInfo.h b/src/cc/GPUInfo.h
new file mode 100644
index 00000000..63194895
--- /dev/null
+++ b/src/cc/GPUInfo.h
@@ -0,0 +1,75 @@
+/* XMRigCC
+ * Copyright 2018- BenDr0id
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef XMRIG_GPUINFO_H
+#define XMRIG_GPUINFO_H
+
+#include
+#include <3rdparty/rapidjson/document.h>
+
+class GPUInfo
+{
+public:
+ GPUInfo();
+ ~GPUInfo();
+
+ rapidjson::Value toJson(rapidjson::MemoryPoolAllocator& allocator);
+ bool parseFromJson(const rapidjson::Value& gpuInfo);
+
+ std::string getName() const;
+ void setName(const std::string& name);
+
+ size_t getDeviceIdx() const;
+ void setDeviceIdx(size_t deviceIdx);
+
+ size_t getRawIntensity() const;
+ void setRawIntensity(size_t rawIntensity);
+
+ size_t getWorkSize() const;
+ void setWorkSize(size_t workSize);
+
+ size_t getMaxWorkSize() const;
+ void setMaxWorkSize(size_t maxWorkSize);
+
+ size_t getFreeMem() const;
+ void setFreeMem(size_t freeMem);
+
+ int getMemChunk() const;
+ void setMemChunk(int memChunk);
+
+ int getCompMode() const;
+ void setCompMode(int compMode);
+
+ int getComputeUnits() const;
+ void setComputeUnits(int computeUnits);
+
+private:
+ size_t m_deviceIdx;
+ size_t m_rawIntensity;
+ size_t m_workSize;
+ size_t m_maxWorkSize;
+ size_t m_freeMem;
+
+ int m_memChunk;
+ int m_compMode;
+ int m_computeUnits;
+
+ std::string m_name;
+};
+
+
+#endif //XMRIG_GPUINFO_H
diff --git a/src/cc/README.md b/src/cc/README.md
deleted file mode 100644
index f414dfa6..00000000
--- a/src/cc/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# XMRigCC common repository
-This repository contains all common XMRigCC files.
-
-# Used in this repos
-* [xmrigCC](https://github.com/bendr0id/xmrigCC)
-* [xmrigCC-nvidia](https://github.com/bendr0id/xmrigCC-nvidia)
-
diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp
index 05e1542b..a12d44be 100644
--- a/src/cc/Service.cpp
+++ b/src/cc/Service.cpp
@@ -40,6 +40,8 @@
uv_mutex_t Service::m_mutex;
std::map Service::m_clientCommand;
std::map Service::m_clientStatus;
+std::map> Service::m_clientLog;
+
int Service::m_currentServerTime = 0;
bool Service::start()
@@ -55,6 +57,7 @@ void Service::release()
m_clientCommand.clear();
m_clientStatus.clear();
+ m_clientLog.clear();
uv_mutex_unlock(&m_mutex);
}
@@ -77,6 +80,8 @@ unsigned Service::handleGET(const Options* options, const std::string& url, cons
resultCode = getClientConfig(options, clientId, resp);
} else if (url.rfind("/admin/getClientCommand", 0) == 0) {
resultCode = getClientCommand(clientId, resp);
+ } else if (url.rfind("/admin/getClientLog", 0) == 0) {
+ resultCode = getClientLog(clientId, resp);
}
}
else {
@@ -100,7 +105,7 @@ unsigned Service::handlePOST(const Options* options, const std::string& url, con
url.c_str(), clientIp.c_str(), clientId.c_str(), data.length());
if (url.rfind("/client/setClientStatus", 0) == 0) {
- resultCode = setClientStatus(clientIp, clientId, data, resp);
+ resultCode = setClientStatus(options, clientIp, clientId, data, resp);
} else if (url.rfind("/admin/setClientConfig", 0) == 0 || url.rfind("/client/setClientConfig", 0) == 0) {
resultCode = setClientConfig(options, clientId, data, resp);
} else if (url.rfind("/admin/setClientCommand", 0) == 0) {
@@ -216,7 +221,7 @@ unsigned Service::getClientStatusList(std::string& resp)
return MHD_HTTP_OK;
}
-unsigned Service::setClientStatus(const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp)
+unsigned Service::setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp)
{
int resultCode = MHD_HTTP_BAD_REQUEST;
@@ -228,6 +233,10 @@ unsigned Service::setClientStatus(const std::string& clientIp, const std::string
clientStatus.parseFromJson(document);
clientStatus.setExternalIp(clientIp);
+ setClientLog(options->ccClientLogLinesHistory(), clientId, clientStatus.getLog());
+
+ clientStatus.clearLog();
+
m_clientStatus[clientId] = clientStatus;
resultCode = getClientCommand(clientId, resp);
@@ -266,25 +275,29 @@ unsigned Service::getClientCommand(const std::string& clientId, std::string& res
return MHD_HTTP_OK;
}
-unsigned Service::setClientCommand(const std::string& clientId, const std::string& data, std::string& resp)
+unsigned Service::getClientLog(const std::string& clientId, std::string& resp)
{
- ControlCommand controlCommand;
+ if (m_clientLog.find(clientId) != m_clientLog.end()) {
+ rapidjson::Document respDocument;
+ respDocument.SetObject();
- rapidjson::Document document;
- if (!document.Parse(data.c_str()).HasParseError()) {
- controlCommand.parseFromJson(document);
+ auto& allocator = respDocument.GetAllocator();
- m_clientCommand[clientId] = controlCommand;
+ std::stringstream data;
+ for (auto& m_row : m_clientLog[clientId]) {
+ data << m_row.c_str() << std::endl;
+ }
- return MHD_HTTP_OK;
- } else {
- return MHD_HTTP_BAD_REQUEST;
+ std::string log = data.str();
+ respDocument.AddMember("client_log", rapidjson::StringRef(log.c_str()), allocator);
+
+ rapidjson::StringBuffer buffer(0, 4096);
+ rapidjson::Writer writer(buffer);
+ writer.SetMaxDecimalPlaces(10);
+ respDocument.Accept(writer);
+
+ resp = buffer.GetString();
}
-}
-
-unsigned Service::resetClientStatusList(const std::string& data, std::string& resp)
-{
- m_clientStatus.clear();
return MHD_HTTP_OK;
}
@@ -323,6 +336,49 @@ unsigned Service::getAdminPage(const Options* options, std::string& resp)
return MHD_HTTP_OK;
}
+unsigned Service::setClientCommand(const std::string& clientId, const std::string& data, std::string& resp)
+{
+ ControlCommand controlCommand;
+
+ rapidjson::Document document;
+ if (!document.Parse(data.c_str()).HasParseError()) {
+ controlCommand.parseFromJson(document);
+
+ m_clientCommand[clientId] = controlCommand;
+
+ return MHD_HTTP_OK;
+ } else {
+ return MHD_HTTP_BAD_REQUEST;
+ }
+}
+
+void Service::setClientLog(size_t maxRows, const std::string& clientId, const std::string& log)
+{
+ if (m_clientLog.find(clientId) == m_clientLog.end()) {
+ m_clientLog[clientId] = std::list();
+ }
+
+ auto* clientLog = &m_clientLog[clientId];
+ std::istringstream logStream(log);
+
+ std::string logLine;
+ while (std::getline(logStream, logLine))
+ {
+ if (clientLog->size() == maxRows) {
+ clientLog->pop_front();
+ }
+
+ clientLog->push_back(logLine);
+ }
+}
+
+unsigned Service::resetClientStatusList(const std::string& data, std::string& resp)
+{
+ m_clientStatus.clear();
+
+ return MHD_HTTP_OK;
+}
+
std::string Service::getClientConfigFileName(const Options* options, const std::string& clientId)
{
std::string clientConfigFileName;
diff --git a/src/cc/Service.h b/src/cc/Service.h
index 4993e978..e909debd 100644
--- a/src/cc/Service.h
+++ b/src/cc/Service.h
@@ -48,14 +48,17 @@ public:
private:
static unsigned getClientConfig(const Options* options, const std::string& clientId, std::string& resp);
static unsigned getClientCommand(const std::string& clientId, std::string& resp);
+ static unsigned getClientLog(const std::string& clientId, std::string& resp);
static unsigned getClientStatusList(std::string& resp);
static unsigned getAdminPage(const Options* options, std::string& resp);
- static unsigned setClientStatus(const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
+ static unsigned setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
static unsigned setClientCommand(const std::string& clientId, const std::string& data, std::string& resp);
static unsigned setClientConfig(const Options* options, const std::string &clientId, const std::string &data, std::string &resp);
static unsigned resetClientStatusList(const std::string& data, std::string& resp);
+ static void setClientLog(size_t maxRows, const std::string& clientId, const std::string& log);
+
static std::string getClientConfigFileName(const Options *options, const std::string &clientId);
private:
@@ -63,6 +66,7 @@ private:
static std::map m_clientStatus;
static std::map m_clientCommand;
+ static std::map> m_clientLog;
static uv_mutex_t m_mutex;
diff --git a/src/config.json b/src/config.json
index 2a8aab50..f777770c 100644
--- a/src/config.json
+++ b/src/config.json
@@ -35,6 +35,6 @@
"worker-id": null, // custom worker-id for CC Server (otherwise hostname is used)
"update-interval-s": 10, // status update interval in seconds (default: 10 min: 1)
"use-remote-logging" : true, // enable remote logging on CC Server
- "remote-logging-max-rows" : 20 // maximum last n-log rows to send CC Server
+ "upload-config-on-startup" : true // upload current miner config to CC Server on startup
}
}
diff --git a/src/config_cc.json b/src/config_cc.json
index 2b716a0d..ea4e492a 100644
--- a/src/config_cc.json
+++ b/src/config_cc.json
@@ -12,6 +12,7 @@
"user": "admin", // admin user for access CC Dashboard
"pass": "pass", // admin pass for access CC Dashboard
"client-config-folder" : null, // folder which contains the client-config files (null=current)
+ "client-log-lines-history" : 100, // maximum lines of log history kept per miner
"custom-dashboard" : "index.html" // dashboard html file
}
}
diff --git a/src/default_config.json b/src/default_config.json
index 2a8aab50..d3081d1b 100644
--- a/src/default_config.json
+++ b/src/default_config.json
@@ -5,7 +5,7 @@
"multihash-factor": 0, // number of hash blocks to process at a time (not set or 0 enables automatic selection of optimal number of hash blocks)
"multihash-thread-mask" : null, // for multihash-factors>0 only, limits multihash to given threads (mask), mask "0x3" means run multihash on thread 0 and 1 only (default: all threads)
"pow-variant" : "auto", // specificy the PoW variat to use: -> auto (default), 0 (v0), 1 (v1, aka monerov7, aeonv7), tube (ipbc), alloy, xtl (including autodetect for v5), msr, xhv, rto
- // for further help see: https://github.com/Bendr0id/xmrigCC/wiki/Coin-configurations
+ // for further help see: https://github.com/Bendr0id/xmrigCC/wiki/Coin-configurations
"background": false, // true to run the miner in the background (Windows only, for *nix plase use screen/tmux or systemd service instead)
"colors": true, // false to disable colored output
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
@@ -35,6 +35,6 @@
"worker-id": null, // custom worker-id for CC Server (otherwise hostname is used)
"update-interval-s": 10, // status update interval in seconds (default: 10 min: 1)
"use-remote-logging" : true, // enable remote logging on CC Server
- "remote-logging-max-rows" : 20 // maximum last n-log rows to send CC Server
+ "upload-config-on-startup" : true // upload current miner config to CC Server on startup
}
}
diff --git a/src/log/Log.cpp b/src/log/Log.cpp
index f37d4424..906ddf17 100644
--- a/src/log/Log.cpp
+++ b/src/log/Log.cpp
@@ -35,7 +35,6 @@
Log *Log::m_self = nullptr;
-
Log::Log()
{
uv_mutex_init(&m_mutex);
diff --git a/src/log/RemoteLog.cpp b/src/log/RemoteLog.cpp
index 7a314790..f5552d09 100644
--- a/src/log/RemoteLog.cpp
+++ b/src/log/RemoteLog.cpp
@@ -23,14 +23,18 @@
RemoteLog* RemoteLog::m_self = nullptr;
RemoteLog::RemoteLog(size_t maxRows)
- : maxRows_(maxRows)
+ : m_maxRows(maxRows)
{
+ uv_mutex_init(&m_mutex);
+
m_self = this;
}
RemoteLog::~RemoteLog()
{
m_self = nullptr;
+
+ uv_mutex_destroy(&m_mutex);
}
void RemoteLog::message(int level, const char* fmt, va_list args)
@@ -56,13 +60,17 @@ void RemoteLog::message(int level, const char* fmt, va_list args)
size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size;
buf[size] = '\n';
- if (rows_.size() == maxRows_) {
- rows_.pop_front();
+ uv_mutex_lock(&m_mutex);
+
+ if (m_rows.size() == m_maxRows) {
+ m_rows.pop_front();
}
std::string row = std::regex_replace(std::string(buf, size+1), std::regex("\x1B\\[[0-9;]*[a-zA-Z]"), "");
- rows_.push_back(row);
+ m_rows.push_back(row);
+
+ uv_mutex_unlock(&m_mutex);
delete[](buf);
}
@@ -73,23 +81,21 @@ void RemoteLog::text(const char* fmt, va_list args)
message(0, fmt, args);
}
-void RemoteLog::flushRows()
-{
- if (m_self) {
- m_self->rows_.clear();
- }
-}
-
-
std::string RemoteLog::getRows()
{
std::stringstream data;
+ uv_mutex_lock(&m_self->m_mutex);
+
if (m_self) {
- for (std::list::iterator it = m_self->rows_.begin(); it != m_self->rows_.end(); it++) {
- data << it->c_str();
+ for (auto& m_row : m_self->m_rows) {
+ data << m_row.c_str();
}
}
+ m_self->m_rows.clear();
+
+ uv_mutex_unlock(&m_self->m_mutex);
+
return data.str();
}
diff --git a/src/log/RemoteLog.h b/src/log/RemoteLog.h
index 793e01ba..973cc8f5 100644
--- a/src/log/RemoteLog.h
+++ b/src/log/RemoteLog.h
@@ -21,6 +21,7 @@
#include
#include
+#include
#include "interfaces/ILogBackend.h"
@@ -34,15 +35,15 @@ public:
void message(int level, const char* fmt, va_list args) override;
void text(const char* fmt, va_list args) override;
- static void flushRows();
static std::string getRows();
private:
static RemoteLog* m_self;
- size_t maxRows_;
- std::list rows_;
+ uv_mutex_t m_mutex;
+ size_t m_maxRows;
+ std::list m_rows;
};
#endif /* __REMOTELOG_H__ */
diff --git a/src/version.h b/src/version.h
index 3bc2011d..df1b4407 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,14 +36,14 @@
#define APP_DESC "XMRigCC CPU miner"
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
#endif
-#define APP_VERSION "1.6.5 (based on XMRig)"
+#define APP_VERSION "1.7.0_beta1 (based on XMRig)"
#define APP_DOMAIN ""
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
#define APP_KIND "cpu"
#define APP_VER_MAJOR 1
-#define APP_VER_MINOR 6
-#define APP_VER_BUILD 5
+#define APP_VER_MINOR 7
+#define APP_VER_BUILD 0
#define APP_VER_REV 0
#ifndef NDEBUG