Browse Source

Config writer fix

Reworked how the config writer works to properly save the config file.
Sometimes settings would get lost in profiles.

Also changed algorithm switch to only perform a soft reset and lowered
the verbosity of the algorithm switcher.
djm34
ystarnaud 11 years ago
parent
commit
f8fcbbcd0a
  1. 2
      api.c
  2. 692
      config_parser.c
  3. 19
      config_parser.h
  4. 22
      miner.h
  5. 12
      sgminer.c

2
api.c

@ -1370,10 +1370,12 @@ static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __
root = api_add_const(root, "ADL", (char *)adl, false); root = api_add_const(root, "ADL", (char *)adl, false);
root = api_add_string(root, "ADL in use", adlinuse, false); root = api_add_string(root, "ADL in use", adlinuse, false);
root = api_add_const(root, "Strategy", strategies[pool_strategy].s, false); root = api_add_const(root, "Strategy", strategies[pool_strategy].s, false);
root = api_add_int(root, "Rotate Period", &opt_rotate_period, false);
root = api_add_int(root, "Log Interval", &opt_log_interval, false); root = api_add_int(root, "Log Interval", &opt_log_interval, false);
root = api_add_const(root, "Device Code", DEVICECODE, false); root = api_add_const(root, "Device Code", DEVICECODE, false);
root = api_add_const(root, "OS", OSINFO, false); root = api_add_const(root, "OS", OSINFO, false);
root = api_add_bool(root, "Failover-Only", &opt_fail_only, false); root = api_add_bool(root, "Failover-Only", &opt_fail_only, false);
root = api_add_int(root, "Failover Switch Delay", &opt_fail_switch_delay, false);
root = api_add_int(root, "ScanTime", &opt_scantime, false); root = api_add_int(root, "ScanTime", &opt_scantime, false);
root = api_add_int(root, "Queue", &opt_queue, false); root = api_add_int(root, "Queue", &opt_queue, false);
root = api_add_int(root, "Expiry", &opt_expiry, false); root = api_add_int(root, "Expiry", &opt_expiry, false);

692
config_parser.c

@ -732,6 +732,10 @@ char *load_config(const char *arg, const char *parentkey, void __maybe_unused *u
return JSON_MAX_DEPTH_ERR; return JSON_MAX_DEPTH_ERR;
*/ */
//check if the file exists
if(access(arg, F_OK) == -1)
quit(1, "%s: file not found.", arg);
#if JANSSON_MAJOR_VERSION > 1 #if JANSSON_MAJOR_VERSION > 1
config = json_load_file(arg, 0, &err); config = json_load_file(arg, 0, &err);
#else #else
@ -901,10 +905,8 @@ void apply_pool_profiles()
int i; int i;
for (i=total_pools; i--;) for (i=total_pools; i--;)
{
apply_pool_profile(pools[i]); apply_pool_profile(pools[i]);
} }
}
void apply_pool_profile(struct pool *pool) void apply_pool_profile(struct pool *pool)
{ {
@ -1073,26 +1075,69 @@ void apply_pool_profile(struct pool *pool)
applog(LOG_DEBUG, "Pool %i Worksize set to \"%s\"", pool->pool_no, pool->worksize); applog(LOG_DEBUG, "Pool %i Worksize set to \"%s\"", pool->pool_no, pool->worksize);
} }
//helper function to add json values to pool object /***************************************
static bool build_pool_json_add(json_t *object, const char *key, const char *val, const char *str_compare, int id) * Config Writer Functions
{ ****************************************/
if(!empty_string(val))
{ /*******************************
if(safe_cmp(str_compare, val)) * Helper macros
{ *******************************/
if(json_object_set(object, key, json_string(val)) == -1) #define JSON_POOL_ERR "json_object_set() failed on pool(%d):%s"
{ #define JSON_PROFILE_ERR "json_object_set() failed on profile(%d):%s"
set_last_json_error("json_object_set() failed on pool(%d):%s", id, key); #define JSON_ROOT_ERR "Error: config_parser::write_config():\n json_object_set() failed on %s"
return false;
#ifndef json_pool_add
#define json_pool_add(obj, key, val, id) \
if(json_object_set(obj, key, val) == -1) { \
set_last_json_error(JSON_POOL_ERR, id, key); \
return NULL; \
} }
#endif
#ifndef json_profile_add
#define json_profile_add(obj, key, val, parentkey, id) \
if(json_object_set(obj, key, val) == -1) { \
if(!empty_string(parentkey)) { \
set_last_json_error(JSON_PROFILE_ERR, id, key); \
return NULL; \
} else { \
applog(LOG_ERR, JSON_ROOT_ERR, key); \
return NULL; \
} \
} }
#endif
#ifndef json_add
#define json_add(obj, key, val) \
if(json_object_set(obj, key, val) == -1) { \
applog(LOG_ERR, JSON_ROOT_ERR, key); \
return; \
} }
#endif
// helper function to add json values to pool object
static json_t *build_pool_json_add(json_t *object, const char *key, const char *val, const char *str_compare, const char *default_compare, int id)
{
// if pool value is empty, abort
if (empty_string(val))
return object;
// check to see if its the same value as profile, abort if it is
if(safe_cmp(str_compare, val) == 0)
return object;
// check to see if it's the same value as default profile, abort if it is
if(safe_cmp(default_compare, val) == 0)
return object;
return true; // not same value, add value to JSON
json_pool_add(object, key, json_string(val), id);
return object;
} }
//builds the "pools" json array for config file //builds the "pools" json array for config file
json_t *build_pool_json() static json_t *build_pool_json()
{ {
json_t *pool_array, *obj; json_t *pool_array, *obj;
struct pool *pool; struct pool *pool;
@ -1120,82 +1165,42 @@ json_t *build_pool_json()
// pool name // pool name
if(!empty_string(pool->name)) if(!empty_string(pool->name))
{ json_pool_add(obj, "name", json_string(pool->name), pool->pool_no);
if(json_object_set(obj, "name", json_string(pool->name)) == -1)
{
set_last_json_error("json_object_set() failed on pool(%d):name", pool->pool_no);
return NULL;
}
}
// add quota/url // add quota/url
if(pool->quota != 1) if(pool->quota != 1)
{ {
if(json_object_set(obj, "quota", json_sprintf("%s%s%s%d;%s", json_pool_add(obj, "quota", json_sprintf("%s%s%s%d;%s",
((pool->rpc_proxy)?(char *)proxytype(pool->rpc_proxytype):""), ((pool->rpc_proxy)?(char *)proxytype(pool->rpc_proxytype):""),
((pool->rpc_proxy)?pool->rpc_proxy:""), ((pool->rpc_proxy)?pool->rpc_proxy:""),
((pool->rpc_proxy)?"|":""), ((pool->rpc_proxy)?"|":""),
pool->quota, pool->quota,
pool->rpc_url)) == -1) pool->rpc_url), pool->pool_no);
{
set_last_json_error("json_object_set() failed on pool(%d):quota", pool->pool_no);
return NULL;
}
} }
else else
{ {
if(json_object_set(obj, "url", json_sprintf("%s%s%s%s", json_pool_add(obj, "url", json_sprintf("%s%s%s%s",
((pool->rpc_proxy)?(char *)proxytype(pool->rpc_proxytype):""), ((pool->rpc_proxy)?(char *)proxytype(pool->rpc_proxytype):""),
((pool->rpc_proxy)?pool->rpc_proxy:""), ((pool->rpc_proxy)?pool->rpc_proxy:""),
((pool->rpc_proxy)?"|":""), ((pool->rpc_proxy)?"|":""),
pool->rpc_url)) == -1) pool->rpc_url), pool->pool_no);
{
set_last_json_error("json_object_set() failed on pool(%d):url", pool->pool_no);
return NULL;
}
} }
// user // user
if(json_object_set(obj, "user", json_string(pool->rpc_user)) == -1) json_pool_add(obj, "user", json_string(pool->rpc_user), pool->pool_no);
{
set_last_json_error("json_object_set() failed on pool(%d):user", pool->pool_no);
return NULL;
}
// pass // pass
if(json_object_set(obj, "pass", json_string(pool->rpc_pass)) == -1) json_pool_add(obj, "pass", json_string(pool->rpc_pass), pool->pool_no);
{
set_last_json_error("json_object_set() failed on pool(%d):pass", pool->pool_no);
return NULL;
}
if (!pool->extranonce_subscribe) if (!pool->extranonce_subscribe)
{ json_pool_add(obj, "no-extranonce", json_true(), pool->pool_no);
if(json_object_set(obj, "no-extranonce", json_true()) == -1)
{
set_last_json_error("json_object_set() failed on pool(%d):no-extranonce", pool->pool_no);
return NULL;
}
}
if (!empty_string(pool->description)) if (!empty_string(pool->description))
{ json_pool_add(obj, "no-description", json_string(pool->description), pool->pool_no);
if(json_object_set(obj, "description", json_string(pool->description)) == -1)
{
set_last_json_error("json_object_set() failed on pool(%d):description", pool->pool_no);
return NULL;
}
}
// if priority isnt the same as array index, specify it // if priority isnt the same as array index, specify it
if (pool->prio != i) if (pool->prio != i)
{ json_pool_add(obj, "priority", json_sprintf("%d", pool->prio), pool->pool_no);
if(json_object_set(obj, "priority", json_sprintf("%d", pool->prio)) == -1)
{
set_last_json_error("json_object_set() failed on pool(%d):description", pool->pool_no);
return NULL;
}
}
// if a profile was specified, add it then compare pool/profile settings to see what we write // if a profile was specified, add it then compare pool/profile settings to see what we write
if (!empty_string(pool->profile)) if (!empty_string(pool->profile))
@ -1203,11 +1208,7 @@ json_t *build_pool_json()
if ((profile = get_profile(pool->profile))) if ((profile = get_profile(pool->profile)))
{ {
// save profile name // save profile name
if(json_object_set(obj, "profile", json_string(pool->profile)) == -1) json_pool_add(obj, "profile", json_string(pool->profile), pool->pool_no);
{
set_last_json_error("json_object_set() failed on pool(%d):profile", pool->pool_no);
return NULL;
}
} }
// profile not found use default profile // profile not found use default profile
else else
@ -1221,71 +1222,70 @@ json_t *build_pool_json()
if (!cmp_algorithm(&pool->algorithm, &profile->algorithm)) if (!cmp_algorithm(&pool->algorithm, &profile->algorithm))
{ {
// save algorithm name // save algorithm name
if(json_object_set(obj, "algorithm", json_string(pool->algorithm.name)) == -1) json_pool_add(obj, "algorithm", json_string(pool->algorithm.name), pool->pool_no);
{
set_last_json_error("json_object_set() failed on pool(%d):algorithm", pool->pool_no);
return NULL;
}
//TODO: add other options like nfactor etc... // save nfactor also
if (pool->algorithm.type == ALGO_NSCRYPT)
json_pool_add(obj, "nfactor", json_sprintf("%d", profile->algorithm.nfactor), pool->pool_no);
} }
// if pool and profile value doesn't match below, add it // if pool and profile value doesn't match below, add it
// devices // devices
if(!build_pool_json_add(obj, "device", pool->devices, profile->devices, pool->pool_no)) if (!build_pool_json_add(obj, "device", pool->devices, profile->devices, default_profile.devices, pool->pool_no))
return NULL; return NULL;
// lookup-gap // lookup-gap
if(!build_pool_json_add(obj, "lookup-gap", pool->lookup_gap, profile->lookup_gap, pool->pool_no)) if (!build_pool_json_add(obj, "lookup-gap", pool->lookup_gap, profile->lookup_gap, default_profile.lookup_gap, pool->pool_no))
return NULL; return NULL;
//intensity // rawintensity
if(!build_pool_json_add(obj, "intensity", pool->intensity, profile->intensity, pool->pool_no)) if (!empty_string(pool->rawintensity))
if (!build_pool_json_add(obj, "rawintensity", pool->rawintensity, profile->rawintensity, default_profile.rawintensity, pool->pool_no))
return NULL; return NULL;
// xintensity // xintensity
if(!build_pool_json_add(obj, "xintensity", pool->xintensity, profile->xintensity, pool->pool_no)) else if (!empty_string(pool->xintensity))
if (!build_pool_json_add(obj, "xintensity", pool->xintensity, profile->xintensity, default_profile.xintensity, pool->pool_no))
return NULL; return NULL;
// intensity
//rawintensity else
if(!build_pool_json_add(obj, "rawintensity", pool->rawintensity, profile->rawintensity, pool->pool_no)) if (!build_pool_json_add(obj, "intensity", pool->intensity, profile->intensity, default_profile.intensity, pool->pool_no))
return NULL; return NULL;
// shaders // shaders
if(!build_pool_json_add(obj, "shaders", pool->shaders, profile->shaders, pool->pool_no)) if (!build_pool_json_add(obj, "shaders", pool->shaders, profile->shaders, default_profile.shaders, pool->pool_no))
return NULL; return NULL;
// thread_concurrency // thread_concurrency
if(!build_pool_json_add(obj, "thread-concurrency", pool->thread_concurrency, profile->thread_concurrency, pool->pool_no)) if (!build_pool_json_add(obj, "thread-concurrency", pool->thread_concurrency, profile->thread_concurrency, default_profile.thread_concurrency, pool->pool_no))
return NULL; return NULL;
// worksize // worksize
if(!build_pool_json_add(obj, "worksize", pool->worksize, profile->worksize, pool->pool_no)) if (!build_pool_json_add(obj, "worksize", pool->worksize, profile->worksize, default_profile.worksize, pool->pool_no))
return NULL; return NULL;
#ifdef HAVE_ADL #ifdef HAVE_ADL
// gpu_engine // gpu_engine
if(!build_pool_json_add(obj, "gpu-engine", pool->gpu_engine, profile->gpu_engine, pool->pool_no)) if (!build_pool_json_add(obj, "gpu-engine", pool->gpu_engine, profile->gpu_engine, default_profile.gpu_engine, pool->pool_no))
return NULL; return NULL;
// gpu_memclock // gpu_memclock
if(!build_pool_json_add(obj, "gpu-memclock", pool->gpu_memclock, profile->gpu_memclock, pool->pool_no)) if (!build_pool_json_add(obj, "gpu-memclock", pool->gpu_memclock, profile->gpu_memclock, default_profile.gpu_memclock, pool->pool_no))
return NULL; return NULL;
// gpu_threads // gpu_threads
if(!build_pool_json_add(obj, "gpu-threads", pool->gpu_threads, profile->gpu_threads, pool->pool_no)) if (!build_pool_json_add(obj, "gpu-threads", pool->gpu_threads, profile->gpu_threads, default_profile.gpu_threads, pool->pool_no))
return NULL; return NULL;
// gpu_fan // gpu_fan
if(!build_pool_json_add(obj, "gpu-fan", pool->gpu_fan, profile->gpu_fan, pool->pool_no)) if (!build_pool_json_add(obj, "gpu-fan", pool->gpu_fan, profile->gpu_fan, default_profile.gpu_fan, pool->pool_no))
return NULL; return NULL;
// gpu-powertune // gpu-powertune
if(!build_pool_json_add(obj, "gpu-powertune", pool->gpu_powertune, profile->gpu_powertune, pool->pool_no)) if (!build_pool_json_add(obj, "gpu-powertune", pool->gpu_powertune, profile->gpu_powertune, default_profile.gpu_powertune, pool->pool_no))
return NULL; return NULL;
// gpu-vddc // gpu-vddc
if(!build_pool_json_add(obj, "gpu-vddc", pool->gpu_vddc, profile->gpu_vddc, pool->pool_no)) if (!build_pool_json_add(obj, "gpu-vddc", pool->gpu_vddc, profile->gpu_vddc, default_profile.gpu_vddc, pool->pool_no))
return NULL; return NULL;
#endif #endif
@ -1300,142 +1300,144 @@ json_t *build_pool_json()
return pool_array; return pool_array;
} }
//helper function to add json values to profile object //helper function to add json values to profile object
static bool build_profile_json_add(json_t *object, const char *key, const char *val, const char *str_compare, bool isdefault, int id) static json_t *build_profile_json_add(json_t *object, const char *key, const char *val, const char *str_compare, const bool isdefault, const char *parentkey, int id)
{
if(!empty_string(val))
{ {
//always add if default profile is this profile //if default profile, make sure we sync profile and default_profile values...
if(safe_cmp(str_compare, val) || isdefault) if(isdefault)
{ val = str_compare;
if(json_object_set(object, key, json_string(val)) == -1)
{
set_last_json_error("json_object_set() failed on profile(%d):%s", id, key);
return false;
}
}
}
return true;
}
//builds the "profiles" json array for config file // no value, return...
json_t *build_profile_json() if(empty_string(val))
{ return object;
json_t *profile_array, *obj;
struct profile *profile;
bool isdefault;
int i;
//create the "pools" array //if the value is the same as default profile and, the current profile is not default profile, return...
if(!(profile_array = json_array())) if((safe_cmp(str_compare, val) == 0) && isdefault == false)
{ return object;
set_last_json_error("json_array() failed on profiles");
return NULL;
}
//process pool entries json_profile_add(object, key, json_string(val), parentkey, id);
for(i=0;i<total_profiles;i++)
{
profile = profiles[i];
isdefault = false;
if(!empty_string(default_profile.name)) return object;
{
if(!strcmp(profile->name, default_profile.name))
isdefault = true;
}
//create a new object
if(!(obj = json_object()))
{
set_last_json_error("json_object() failed on profile %d", profile->profile_no);
return NULL;
} }
//profile name // helper function to write all the profile settings
if(!empty_string(profile->name)) static json_t *build_profile_settings_json(json_t *object, struct profile *profile, const bool isdefault, const char *parentkey)
{
if(json_object_set(obj, "name", json_string(profile->name)) == -1)
{ {
set_last_json_error("json_object_set() failed on profile(%d):name", profile->profile_no); // if algorithm is different than default profile or profile is default profile, add it
return NULL; if (!cmp_algorithm(&default_profile.algorithm, &profile->algorithm) || isdefault)
}
}
//if algorithm is different than profile, add it - if default profile is the current profile, always add
if(!cmp_algorithm(&default_profile.algorithm, &profile->algorithm) || !strcasecmp(default_profile.name, profile->name))
{ {
// save algorithm name // save algorithm name
if(json_object_set(obj, "algorithm", json_string(profile->algorithm.name)) == -1) json_profile_add(object, "algorithm", json_string(profile->algorithm.name), parentkey, profile->profile_no);
{
set_last_json_error("json_object_set() failed on profile(%d):algorithm", profile->profile_no);
return NULL;
}
//TODO: add other options like nfactor etc... // save nfactor also
if (profile->algorithm.type == ALGO_NSCRYPT)
json_profile_add(object, "nfactor", json_sprintf("%u", profile->algorithm.nfactor), parentkey, profile->profile_no);
} }
//if pool and profile value doesn't match below, add it
// devices // devices
if(!build_profile_json_add(obj, "device", profile->devices, default_profile.devices, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "device", profile->devices, default_profile.devices, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// lookup-gap // lookup-gap
if(!build_profile_json_add(obj, "lookup-gap", profile->lookup_gap, default_profile.lookup_gap, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "lookup-gap", profile->lookup_gap, default_profile.lookup_gap, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
//intensity // rawintensity
if(!build_profile_json_add(obj, "intensity", profile->intensity, default_profile.intensity, isdefault, profile->profile_no)) if (!empty_string(profile->rawintensity))
if(!build_profile_json_add(object, "rawintensity", profile->rawintensity, default_profile.rawintensity, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// xintensity // xintensity
if(!build_profile_json_add(obj, "xintensity", profile->xintensity, default_profile.xintensity, isdefault, profile->profile_no)) else if (!empty_string(profile->xintensity))
if(!build_profile_json_add(object, "xintensity", profile->xintensity, default_profile.xintensity, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// intensity
//rawintensity else if (!empty_string(profile->intensity))
if(!build_profile_json_add(obj, "rawintensity", profile->rawintensity, default_profile.rawintensity, isdefault, profile->profile_no)) if(!build_profile_json_add(object, "intensity", profile->intensity, default_profile.intensity, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
//shaders //shaders
if(!build_profile_json_add(obj, "shaders", profile->shaders, default_profile.shaders, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "shaders", profile->shaders, default_profile.shaders, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// thread_concurrency // thread_concurrency
if(!build_profile_json_add(obj, "thread-concurrency", profile->thread_concurrency, default_profile.thread_concurrency, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "thread-concurrency", profile->thread_concurrency, default_profile.thread_concurrency, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// worksize // worksize
if(!build_profile_json_add(obj, "worksize", profile->worksize, default_profile.worksize, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "worksize", profile->worksize, default_profile.worksize, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
#ifdef HAVE_ADL #ifdef HAVE_ADL
// gpu_engine // gpu_engine
if(!build_profile_json_add(obj, "gpu-engine", profile->gpu_engine, default_profile.gpu_engine, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "gpu-engine", profile->gpu_engine, default_profile.gpu_engine, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// gpu_memclock // gpu_memclock
if(!build_profile_json_add(obj, "gpu-memclock", profile->gpu_memclock, default_profile.gpu_memclock, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "gpu-memclock", profile->gpu_memclock, default_profile.gpu_memclock, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// gpu_threads // gpu_threads
if(!build_profile_json_add(obj, "gpu-threads", profile->gpu_threads, default_profile.gpu_threads, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "gpu-threads", profile->gpu_threads, default_profile.gpu_threads, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// gpu_fan // gpu_fan
if(!build_profile_json_add(obj, "gpu-fan", profile->gpu_fan, default_profile.gpu_fan, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "gpu-fan", profile->gpu_fan, default_profile.gpu_fan, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// gpu-powertune // gpu-powertune
if(!build_profile_json_add(obj, "gpu-powertune", profile->gpu_powertune, default_profile.gpu_powertune, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "gpu-powertune", profile->gpu_powertune, default_profile.gpu_powertune, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
// gpu-vddc // gpu-vddc
if(!build_profile_json_add(obj, "gpu-vddc", profile->gpu_vddc, default_profile.gpu_vddc, isdefault, profile->profile_no)) if (!build_profile_json_add(object, "gpu-vddc", profile->gpu_vddc, default_profile.gpu_vddc, isdefault, parentkey, profile->profile_no))
return NULL; return NULL;
#endif #endif
return object;
}
// builds the "profiles" json array for config file
json_t *build_profile_json()
{
json_t *profile_array, *obj;
struct profile *profile;
bool isdefault;
int i;
// create the "profiles" array
if (!(profile_array = json_array()))
{
set_last_json_error("json_array() failed on profiles");
return NULL;
}
//process pool entries
for (i=0;i<total_profiles;i++)
{
profile = profiles[i];
isdefault = false;
if (!empty_string(default_profile.name))
{
if (!strcasecmp(profile->name, default_profile.name))
isdefault = true;
}
// create a new object
if(!(obj = json_object()))
{
set_last_json_error("json_object() failed on profile %d", profile->profile_no);
return NULL;
}
// profile name
if (!empty_string(profile->name))
json_profile_add(obj, "name", json_string(profile->name), "profile", profile->profile_no);
// save profile settings
if(!build_profile_settings_json(obj, profile, isdefault, "profile"))
return NULL;
// all done, add pool to array... // all done, add pool to array...
if(json_array_append_new(profile_array, obj) == -1) if(json_array_append_new(profile_array, obj) == -1)
{ {
@ -1454,6 +1456,7 @@ void write_config(const char *filename)
char *p, *optname; char *p, *optname;
int i; int i;
// json root
if (!(config = json_object())) if (!(config = json_object()))
{ {
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object() failed on root."); applog(LOG_ERR, "Error: config_parser::write_config():\n json_object() failed on root.");
@ -1492,205 +1495,33 @@ void write_config(const char *filename)
switch (pool_strategy) switch (pool_strategy)
{ {
case POOL_BALANCE: case POOL_BALANCE:
if(json_object_set(config, "balance", json_true()) == -1) json_add(config, "balance", json_true());
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on balance");
return;
}
break; break;
case POOL_LOADBALANCE: case POOL_LOADBALANCE:
if(json_object_set(config, "load-balance", json_true()) == -1) json_add(config, "load-balance", json_true());
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on load-balance");
return;
}
break; break;
case POOL_ROUNDROBIN: case POOL_ROUNDROBIN:
if(json_object_set(config, "round-robin", json_true()) == -1) json_add(config, "round-robin", json_true());
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on round-robin");
return;
}
break; break;
case POOL_ROTATE: case POOL_ROTATE:
if(json_object_set(config, "rotate", json_sprintf("%d", opt_rotate_period)) == -1) json_add(config, "rotate", json_sprintf("%d", opt_rotate_period));
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on rotate");
return;
}
break; break;
//default failover only //default failover only
default: default:
if(json_object_set(config, "failover-only", json_true()) == -1) json_add(config, "failover-only", json_true());
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on failover-only");
return;
}
break; break;
} }
//if using a specific profile as default, set it //if using a specific profile as default, set it
if (!empty_string(default_profile.name)) if (!empty_string(default_profile.name))
{ {
if(json_object_set(config, "default-profile", json_string(default_profile.name)) == -1) json_add(config, "default-profile", json_string(default_profile.name));
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on default_profile");
return;
}
} }
//otherwise save default profile values //otherwise save default profile values
else else
{ // save default profile settings
//save algorithm name if(!build_profile_settings_json(config, &default_profile, true, ""))
if(json_object_set(config, "algorithm", json_string(default_profile.algorithm.name)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on algorithm");
return; return;
}
//TODO: add other options like nfactor etc...
//devices
if(!empty_string(default_profile.devices))
{
if(json_object_set(config, "devices", json_string(default_profile.devices)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on devices");
return;
}
}
//lookup-gap
if(!empty_string(default_profile.lookup_gap))
{
if(json_object_set(config, "lookup-gap", json_string(default_profile.lookup_gap)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on lookup-gap");
return;
}
}
//intensity
if(!empty_string(default_profile.intensity))
{
if(json_object_set(config, "intensity", json_string(default_profile.intensity)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on intensity");
return;
}
}
//xintensity
if(!empty_string(default_profile.xintensity))
{
if(json_object_set(config, "xintensity", json_string(default_profile.xintensity)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on xintensity");
return;
}
}
//rawintensity
if(!empty_string(default_profile.rawintensity))
{
if(json_object_set(config, "rawintensity", json_string(default_profile.rawintensity)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on rawintensity");
return;
}
}
//shaders
if(!empty_string(default_profile.shaders))
{
if(json_object_set(config, "shaders", json_string(default_profile.shaders)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on shaders");
return;
}
}
//thread_concurrency
if(!empty_string(default_profile.thread_concurrency))
{
if(json_object_set(config, "thread-concurrency", json_string(default_profile.thread_concurrency)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on thread_concurrency");
return;
}
}
//worksize
if(!empty_string(default_profile.worksize))
{
if(json_object_set(config, "worksize", json_string(default_profile.worksize)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on worksize");
return;
}
}
#ifdef HAVE_ADL
//gpu_engine
if(!empty_string(default_profile.gpu_engine))
{
if(json_object_set(config, "gpu-engine", json_string(default_profile.gpu_engine)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-engine");
return;
}
}
//gpu_memclock
if(!empty_string(default_profile.gpu_memclock))
{
if(json_object_set(config, "gpu-memclock", json_string(default_profile.gpu_memclock)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-memclock");
return;
}
}
//gpu_threads
if(!empty_string(default_profile.gpu_threads))
{
if(json_object_set(config, "gpu-threads", json_string(default_profile.gpu_threads)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-threads");
return;
}
}
//gpu_fan
if(!empty_string(default_profile.gpu_fan))
{
if(json_object_set(config, "gpu-fan", json_string(default_profile.gpu_fan)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-fan");
return;
}
}
//gpu-powertune
if(!empty_string(default_profile.gpu_powertune))
{
if(json_object_set(config, "gpu-powertune", json_string(default_profile.gpu_powertune)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-powertune");
return;
}
}
//gpu-vddc
if(!empty_string(default_profile.gpu_vddc))
{
if(json_object_set(config, "gpu-vddc", json_string(default_profile.gpu_vddc)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-vddc");
return;
}
}
#endif
}
//devices //devices
/*if(opt_devs_enabled) /*if(opt_devs_enabled)
@ -1725,90 +1556,50 @@ void write_config(const char *filename)
//remove-disabled //remove-disabled
if(opt_removedisabled) if(opt_removedisabled)
{ json_add(config, "remove-disabled", json_true());
if(json_object_set(config, "remove-disabled", json_true()) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on remove-disabled");
return;
}
}
//write gpu settings that aren't part of profiles -- only write if gpus are available //write gpu settings that aren't part of profiles -- only write if gpus are available
if(nDevs) if(nDevs)
{ {
#ifdef HAVE_ADL #ifdef HAVE_ADL
//temp-cutoff //temp-cutoff
for(i = 0;i < nDevs; i++) for(i = 0;i < nDevs; i++)
obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), gpus[i].cutofftemp); obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), gpus[i].cutofftemp);
if(json_object_set(config, "temp-cutoff", obj) == -1) json_add(config, "temp-cutoff", obj);
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on temp-cutoff");
return;
}
//temp-overheat //temp-overheat
for(i = 0;i < nDevs; i++) for(i = 0;i < nDevs; i++)
obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), gpus[i].adl.overtemp); obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), gpus[i].adl.overtemp);
if(json_object_set(config, "temp-overheat", obj) == -1) json_add(config, "temp-overheat", obj);
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on temp-overheat");
return;
}
//temp-target //temp-target
for(i = 0;i < nDevs; i++) for(i = 0;i < nDevs; i++)
obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), gpus[i].adl.targettemp); obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), gpus[i].adl.targettemp);
if(json_object_set(config, "temp-target", obj) == -1) json_add(config, "temp-target", obj);
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on temp-target");
return;
}
//reorder gpus //reorder gpus
if(opt_reorder) if(opt_reorder)
{ json_add(config, "gpu-reorder", json_true());
if(json_object_set(config, "gpu-reorder", json_true()) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-reorder");
return;
}
}
//gpu-memdiff //gpu-memdiff - FIXME: should be moved to pool/profile options
for(i = 0;i < nDevs; i++) for(i = 0;i < nDevs; i++)
obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), (int)gpus[i].gpu_memdiff); obj = json_sprintf("%s%s%d", ((i > 0)?json_string_value(obj):""), ((i > 0)?",":""), (int)gpus[i].gpu_memdiff);
if(json_object_set(config, "gpu-memdiff", obj) == -1) json_add(config, "gpu-memdiff", obj);
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on gpu-memdiff");
return;
}
#endif #endif
} }
//add other misc options //add other misc options
//shares //shares
if(json_object_set(config, "shares", json_sprintf("%d", opt_shares)) == -1) json_add(config, "shares", json_sprintf("%d", opt_shares));
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on shares");
return;
}
#if defined(unix) || defined(__APPLE__) #if defined(unix) || defined(__APPLE__)
//monitor //monitor
if(opt_stderr_cmd && *opt_stderr_cmd) if(opt_stderr_cmd && *opt_stderr_cmd)
{ json_add(config, "monitor", json_string(opt_stderr_cmd));
if(json_object_set(config, "monitor", json_string(opt_stderr_cmd)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on monitor");
return;
}
}
#endif // defined(unix) #endif // defined(unix)
//kernel path //kernel path
@ -1819,104 +1610,45 @@ void write_config(const char *filename)
if(kpath[strlen(kpath)-1] == '/') if(kpath[strlen(kpath)-1] == '/')
kpath[strlen(kpath)-1] = 0; kpath[strlen(kpath)-1] = 0;
if(json_object_set(config, "kernel-path", json_string(kpath)) == -1) json_add(config, "kernel-path", json_string(kpath));
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on kernel-path");
return;
}
} }
//sched-time //sched-time
if(schedstart.enable) if(schedstart.enable)
{ json_add(config, "sched-time", json_sprintf("%d:%d", schedstart.tm.tm_hour, schedstart.tm.tm_min));
if(json_object_set(config, "sched-time", json_sprintf("%d:%d", schedstart.tm.tm_hour, schedstart.tm.tm_min)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on sched-time");
return;
}
}
//stop-time //stop-time
if(schedstop.enable) if(schedstop.enable)
{ json_add(config, "stop-time", json_sprintf("%d:%d", schedstop.tm.tm_hour, schedstop.tm.tm_min));
if(json_object_set(config, "stop-time", json_sprintf("%d:%d", schedstop.tm.tm_hour, schedstop.tm.tm_min)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on stop-time");
return;
}
}
//socks-proxy //socks-proxy
if(opt_socks_proxy && *opt_socks_proxy) if(opt_socks_proxy && *opt_socks_proxy)
{ json_add(config, "socks-proxy", json_string(opt_socks_proxy));
if(json_object_set(config, "socks-proxy", json_string(opt_socks_proxy)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on socks-proxy");
return;
}
}
//api stuff //api stuff
//api-allow //api-allow
if(opt_api_allow) if(opt_api_allow)
{ json_add(config, "api-allow", json_string(opt_api_allow));
if(json_object_set(config, "api-allow", json_string(opt_api_allow)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on api-allow");
return;
}
}
//api-mcast-addr //api-mcast-addr
if(strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0) if(strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0)
{ json_add(config, "api-mcast-addr", json_string(opt_api_mcast_addr));
if(json_object_set(config, "api-mcast-addr", json_string(opt_api_mcast_addr)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on api-mcast-addr");
return;
}
}
//api-mcast-code //api-mcast-code
if(strcmp(opt_api_mcast_code, API_MCAST_CODE) != 0) if(strcmp(opt_api_mcast_code, API_MCAST_CODE) != 0)
{ json_add(config, "api-mcast-code", json_string(opt_api_mcast_code));
if(json_object_set(config, "api-mcast-code", json_string(opt_api_mcast_code)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on api-mcast-code");
return;
}
}
//api-mcast-des //api-mcast-des
if(*opt_api_mcast_des) if(*opt_api_mcast_des)
{ json_add(config, "api-mcast-des", json_string(opt_api_mcast_des));
if(json_object_set(config, "api-mcast-des", json_string(opt_api_mcast_des)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on api-mcast-des");
return;
}
}
//api-description //api-description
if(strcmp(opt_api_description, PACKAGE_STRING) != 0) if(strcmp(opt_api_description, PACKAGE_STRING) != 0)
{ json_add(config, "api-description", json_string(opt_api_description));
if(json_object_set(config, "api-description", json_string(opt_api_description)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on api-description");
return;
}
}
//api-groups //api-groups
if(opt_api_groups) if(opt_api_groups)
{ json_add(config, "api-groups", json_string(opt_api_groups));
if(json_object_set(config, "api-groups", json_string(opt_api_groups)) == -1)
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on api-groups");
return;
}
}
//add other misc bool/int options //add other misc bool/int options
for(opt = opt_config_table; opt->type != OPT_END; opt++) for(opt = opt_config_table; opt->type != OPT_END; opt++)
@ -1938,11 +1670,7 @@ void write_config(const char *filename)
((void *)opt->cb == (void *)opt_set_bool || (void *)opt->cb == (void *)opt_set_invbool) && ((void *)opt->cb == (void *)opt_set_bool || (void *)opt->cb == (void *)opt_set_invbool) &&
(*(bool *)opt->u.arg == ((void *)opt->cb == (void *)opt_set_bool))) (*(bool *)opt->u.arg == ((void *)opt->cb == (void *)opt_set_bool)))
{ {
if(json_object_set(config, p+2, json_true()) == -1) json_add(config, p+2, json_true());
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on %s.", p+2);
return;
}
break; //exit for loop... so we don't enter a duplicate value if an option has multiple names break; //exit for loop... so we don't enter a duplicate value if an option has multiple names
} }
//numeric types //numeric types
@ -1952,11 +1680,7 @@ void write_config(const char *filename)
(void *)opt->cb_arg == (void *)set_int_0_to_10 || (void *)opt->cb_arg == (void *)set_int_0_to_10 ||
(void *)opt->cb_arg == (void *)set_int_1_to_10) && opt->desc != opt_hidden) (void *)opt->cb_arg == (void *)set_int_1_to_10) && opt->desc != opt_hidden)
{ {
if(json_object_set(config, p+2, json_sprintf("%d", *(int *)opt->u.arg)) == -1) json_add(config, p+2, json_sprintf("%d", *(int *)opt->u.arg));
{
applog(LOG_ERR, "Error: config_parser::write_config():\n json_object_set() failed on %s.", p+2);
return;
}
break; //exit for loop... so we don't enter a duplicate value if an option has multiple names break; //exit for loop... so we don't enter a duplicate value if an option has multiple names
} }
} }

19
config_parser.h

@ -7,25 +7,6 @@
#include "api.h" #include "api.h"
#include "algorithm.h" #include "algorithm.h"
//helper to check for empty or NULL strings
#ifndef empty_string
#define empty_string(str) ((str && str[0] != '\0')?0:1)
#endif
#ifndef safe_cmp
#define safe_cmp(val1, val2) (((val1 && strcasecmp(val1, val2) != 0) || empty_string(val1))?1:0)
#endif
#ifndef pool_cmp
#define pool_cmp(val1, val2) (((val1 && val2 && strcasecmp(val1, val2) == 0) || empty_string(val1))?1:0)
#endif
#ifndef isnull
#define isnull(str, default_str) ((str == NULL)?default_str:str)
#endif
//helper function to get a gpu option value
#ifndef gpu_opt
#define gpu_opt(i,optname) gpus[i].optname
#endif
//profile structure //profile structure
struct profile { struct profile {
int profile_no; int profile_no;

22
miner.h

@ -245,6 +245,27 @@ enum drv_driver {
DRIVER_PARSE_COMMANDS(DRIVER_PROTOTYPE) DRIVER_PARSE_COMMANDS(DRIVER_PROTOTYPE)
#endif #endif
// helper to check for empty or NULL strings
#ifndef empty_string
#define empty_string(str) ((str && str[0] != '\0')?0:1)
#endif
// helper to safely compare strings: 0 = equal, 1 = not equal
#ifndef safe_cmp
#define safe_cmp(val1, val2) ((!empty_string(val1) && !empty_string(val2))?((strcasecmp(val1, val2) == 0)?0:1):((empty_string(val1) && empty_string(val2))?0:1))
#endif
// helper to pick pool settings or default profile settings
#ifndef pool_cmp
#define pool_cmp(val1, val2) (((val1 && val2 && strcasecmp(val1, val2) == 0) || empty_string(val1))?1:0)
#endif
// helper safely output a string
#ifndef isnull
#define isnull(str, default_str) ((str == NULL)?default_str:str)
#endif
// helper to get boolean value out of string
#ifndef strtobool
#define strtobool(str) ((str && (!strcasecmp(str, "true") || !strcasecmp(str, "yes") || !strcasecmp(str, "1")))?true:false)
#endif
enum alive { enum alive {
LIFE_WELL, LIFE_WELL,
LIFE_SICK, LIFE_SICK,
@ -1003,6 +1024,7 @@ extern struct schedtime schedstop;
extern char *sgminer_path; extern char *sgminer_path;
extern int opt_shares; extern int opt_shares;
extern bool opt_fail_only; extern bool opt_fail_only;
extern int opt_fail_switch_delay;
extern bool opt_autofan; extern bool opt_autofan;
extern bool opt_autoengine; extern bool opt_autoengine;
extern bool use_curses; extern bool use_curses;

12
sgminer.c

@ -6084,10 +6084,6 @@ static unsigned long compare_pool_settings(struct pool *pool1, struct pool *pool
if(!pool1 || !pool2) if(!pool1 || !pool2)
return 0; return 0;
//compare algorithm
if(!cmp_algorithm(&pool1->algorithm, &pool2->algorithm))
options |= (SWITCHER_APPLY_ALGO | SWITCHER_HARD_RESET);
//compare pool devices //compare pool devices
opt1 = get_pool_setting(pool1->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all")); opt1 = get_pool_setting(pool1->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all"));
opt2 = get_pool_setting(pool2->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all")); opt2 = get_pool_setting(pool2->devices, ((!empty_string(default_profile.devices))?default_profile.devices:"all"));
@ -6104,6 +6100,10 @@ static unsigned long compare_pool_settings(struct pool *pool1, struct pool *pool
if(strcasecmp(opt1, opt2) != 0) if(strcasecmp(opt1, opt2) != 0)
options |= (SWITCHER_APPLY_GT | SWITCHER_HARD_RESET); options |= (SWITCHER_APPLY_GT | SWITCHER_HARD_RESET);
//compare algorithm
if(!cmp_algorithm(&pool1->algorithm, &pool2->algorithm))
options |= (SWITCHER_APPLY_ALGO | ((!opt_isset(options, SWITCHER_HARD_RESET))?SWITCHER_SOFT_RESET:0));
//lookup gap //lookup gap
opt1 = get_pool_setting(pool1->lookup_gap, default_profile.lookup_gap); opt1 = get_pool_setting(pool1->lookup_gap, default_profile.lookup_gap);
opt2 = get_pool_setting(pool2->lookup_gap, default_profile.lookup_gap); opt2 = get_pool_setting(pool2->lookup_gap, default_profile.lookup_gap);
@ -6258,7 +6258,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{ {
if((pool_switch_options = compare_pool_settings(pools[mythr->pool_no], work->pool)) == 0) if((pool_switch_options = compare_pool_settings(pools[mythr->pool_no], work->pool)) == 0)
{ {
applog(LOG_NOTICE, "No settings change from pool %s...", isnull(get_pool_name(work->pool), "")); applog(LOG_DEBUG, "No settings change from pool %s...", isnull(get_pool_name(work->pool), ""));
rd_lock(&mining_thr_lock); rd_lock(&mining_thr_lock);
@ -6305,7 +6305,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{ {
const char *opt; const char *opt;
applog(LOG_NOTICE, "Applying pool settings for %s...", isnull(get_pool_name(work->pool), "")); applog(LOG_DEBUG, "Applying pool settings for %s...", isnull(get_pool_name(work->pool), ""));
rd_lock(&mining_thr_lock); rd_lock(&mining_thr_lock);
// Shutdown all threads first (necessary) // Shutdown all threads first (necessary)

Loading…
Cancel
Save