mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-22 04:24:19 +00:00
Updated the config parser
Updated the config parser to provide better readability and flexibility in config files. The latest features introduced a really messy way to handle config files and this update alleviates this by adding the ability to create profiles and associate them to pools. Todo: Update the config file writer, in-program options and continue to break off the config parsing/command line option code out of sgminer.c to reduce clutter.
This commit is contained in:
parent
14d2b940f9
commit
9faa8fa59f
@ -42,6 +42,7 @@ sgminer_SOURCES += findnonce.c findnonce.h
|
||||
sgminer_SOURCES += adl.c adl.h adl_functions.h
|
||||
sgminer_SOURCES += pool.c pool.h
|
||||
sgminer_SOURCES += algorithm.c algorithm.h
|
||||
sgminer_SOURCES += config_parser.c config_parser.h
|
||||
sgminer_SOURCES += ocl/patch_kernel.c ocl/patch_kernel.h
|
||||
sgminer_SOURCES += ocl/build_kernel.c ocl/build_kernel.h
|
||||
sgminer_SOURCES += ocl/binary_kernel.c ocl/binary_kernel.h
|
||||
|
657
config_parser.c
Normal file
657
config_parser.c
Normal file
@ -0,0 +1,657 @@
|
||||
/*
|
||||
* Copyright 2013-2014 sgminer developers (see AUTHORS.md)
|
||||
* Copyright 2011-2013 Con Kolivas
|
||||
* Copyright 2011-2012 Luke Dashjr
|
||||
* Copyright 2010 Jeff Garzik
|
||||
*
|
||||
* 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. See COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <ccan/opt/opt.h>
|
||||
#include <jansson.h>
|
||||
#include <libgen.h>
|
||||
#include <sha2.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "miner.h"
|
||||
#include "config_parser.h"
|
||||
#include "driver-opencl.h"
|
||||
#include "bench_block.h"
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "pool.h"
|
||||
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
char *cnfbuf = NULL; //config file loaded
|
||||
int fileconf_load; //config file load status
|
||||
const char def_conf[] = "sgminer.conf";
|
||||
char *default_config;
|
||||
bool config_loaded;
|
||||
//static int include_count;
|
||||
|
||||
int json_array_index = -1; //current array index being parsed
|
||||
char *last_json_error = NULL; //last json_error
|
||||
//#define JSON_INCLUDE_CONF "include"
|
||||
#define JSON_LOAD_ERROR "JSON decode of file '%s' failed\n %s"
|
||||
#define JSON_LOAD_ERROR_LEN strlen(JSON_LOAD_ERROR)
|
||||
/*#define JSON_MAX_DEPTH 10
|
||||
#define JSON_MAX_DEPTH_ERR "Too many levels of JSON includes (limit 10) or a loop"*/
|
||||
|
||||
/*******************************************
|
||||
* Profile list functions
|
||||
*******************************************/
|
||||
struct profile default_profile;
|
||||
struct profile **profiles;
|
||||
int total_profiles;
|
||||
|
||||
static struct profile *add_profile()
|
||||
{
|
||||
struct profile *profile;
|
||||
char buf[32];
|
||||
|
||||
if(!(profile = (struct profile *)calloc(sizeof(struct profile), 1)))
|
||||
quit(1, "Failed to calloc profile in add_profile");
|
||||
profile->profile_no = total_profiles;
|
||||
|
||||
//default profile name is the profile index
|
||||
sprintf(buf, "%d", profile->profile_no);
|
||||
profile->name = strdup(buf);
|
||||
|
||||
profiles = (struct profile **)realloc(profiles, sizeof(struct profile *) * (total_profiles + 2));
|
||||
profiles[total_profiles++] = profile;
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
//only used while loading config
|
||||
static struct profile *get_current_profile()
|
||||
{
|
||||
while ((json_array_index + 1) > total_profiles)
|
||||
add_profile();
|
||||
|
||||
if (json_array_index < 0)
|
||||
{
|
||||
if (!total_profiles)
|
||||
add_profile();
|
||||
return profiles[total_profiles - 1];
|
||||
}
|
||||
|
||||
return profiles[json_array_index];
|
||||
}
|
||||
|
||||
//find a profile by name
|
||||
static struct profile *get_profile(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=total_profiles;i--;)
|
||||
{
|
||||
if(!strcasecmp(profiles[i]->name, name))
|
||||
return profiles[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******* Default profile functions used during config parsing *****/
|
||||
char *set_default_intensity(const char *arg)
|
||||
{
|
||||
default_profile.intensity = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_default_xintensity(const char *arg)
|
||||
{
|
||||
default_profile.xintensity = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_default_rawintensity(const char *arg)
|
||||
{
|
||||
default_profile.rawintensity = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_default_thread_concurrency(const char *arg)
|
||||
{
|
||||
default_profile.thread_concurrency = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ADL
|
||||
|
||||
char *set_default_gpu_engine(const char *arg)
|
||||
{
|
||||
default_profile.gpu_engine = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_default_gpu_memclock(const char *arg)
|
||||
{
|
||||
default_profile.gpu_memclock = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_default_gpu_threads(const char *arg)
|
||||
{
|
||||
default_profile.gpu_threads = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_default_gpu_fan(const char *arg)
|
||||
{
|
||||
default_profile.gpu_fan = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *set_default_profile(char *arg)
|
||||
{
|
||||
default_profile.name = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****** Profile functions used in during config parsing ********/
|
||||
char *set_profile_name(char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
|
||||
applog(LOG_DEBUG, "Setting profile %i name to %s", profile->profile_no, arg);
|
||||
opt_set_charp(arg, &profile->name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_algorithm(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
|
||||
//applog(LOG_DEBUG, "Setting profile %s algorithm to %s", profile->name, arg);
|
||||
set_algorithm(&profile->algorithm, arg);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_intensity(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->intensity = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_xintensity(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->xintensity = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_rawintensity(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->rawintensity = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_thread_concurrency(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->thread_concurrency = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ADL
|
||||
|
||||
char *set_profile_gpu_engine(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->gpu_engine = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_gpu_memclock(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->gpu_memclock = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_gpu_threads(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->gpu_threads = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *set_profile_gpu_fan(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
profile->gpu_fan = arg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *set_profile_nfactor(const char *arg)
|
||||
{
|
||||
struct profile *profile = get_current_profile();
|
||||
|
||||
applog(LOG_DEBUG, "Setting profile %s N-factor to %s", profile->name, arg);
|
||||
set_algorithm_nfactor(&profile->algorithm, (const uint8_t) atoi(arg));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* Helper Functions
|
||||
****************************************/
|
||||
//set last json error
|
||||
void set_last_json_error(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
size_t bufsize;
|
||||
|
||||
//build args
|
||||
va_start(args, fmt);
|
||||
//get final string buffer size
|
||||
bufsize = vsnprintf(NULL, 0, JSON_LOAD_ERROR, args);
|
||||
va_end(args);
|
||||
|
||||
//if NULL allocate memory... otherwise reallocate
|
||||
if(!last_json_error)
|
||||
{
|
||||
if(!(last_json_error = (char *)malloc(bufsize+1)))
|
||||
quit(1, "Malloc failure in json error");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!(last_json_error = (char *)realloc(last_json_error, bufsize+1)))
|
||||
quit(1, "Realloc failure in json error");
|
||||
}
|
||||
|
||||
//zero out buffer
|
||||
memset(last_json_error, '\0', bufsize+1);
|
||||
|
||||
//get args again
|
||||
va_start(args, fmt);
|
||||
vsnprintf(last_json_error, bufsize, JSON_LOAD_ERROR, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
//find opt by name in an opt table
|
||||
static struct opt_table *opt_find(struct opt_table *tbl, char *optname)
|
||||
{
|
||||
struct opt_table *opt;
|
||||
char *p, *name;
|
||||
|
||||
for(opt = tbl;opt->type != OPT_END;opt++)
|
||||
{
|
||||
/* We don't handle subtables. */
|
||||
assert(!(opt->type & OPT_SUBTABLE));
|
||||
|
||||
if(!opt->names)
|
||||
continue;
|
||||
|
||||
/* Pull apart the option name(s). */
|
||||
name = strdup(opt->names);
|
||||
for(p = strtok(name, "|");p;p = strtok(NULL, "|"))
|
||||
{
|
||||
/* Ignore short options. */
|
||||
if(p[1] != '-')
|
||||
continue;
|
||||
|
||||
//if this is the opt we're looking for, return it...
|
||||
if(!strcasecmp(optname, p))
|
||||
{
|
||||
free(name);
|
||||
return opt;
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***************************************
|
||||
* Config Parsing Functions
|
||||
****************************************/
|
||||
//Handle parsing JSON objects
|
||||
void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int parent_iteration)
|
||||
{
|
||||
//char *err = NULL;
|
||||
const char *key;
|
||||
json_t *val;
|
||||
|
||||
json_object_foreach(obj, key, val)
|
||||
{
|
||||
//process include
|
||||
if(!strcasecmp(key, "include"))
|
||||
{
|
||||
if(val && json_is_string(val))
|
||||
load_config(json_string_value(val), parentkey, NULL);
|
||||
}
|
||||
else
|
||||
parse_config(val, key, parentkey, fileconf, parent_iteration);
|
||||
/*
|
||||
{
|
||||
if((err = parse_config(val, key, parentkey, fileconf, parent_iteration)))
|
||||
return err;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
//Handle parsing JSON arrays
|
||||
static char *parse_config_array(json_t *obj, char *parentkey, bool fileconf)
|
||||
{
|
||||
char *err = NULL;
|
||||
size_t idx;
|
||||
json_t *val;
|
||||
|
||||
//fix parent key - remove extra "s" to match opt names (e.g. --pool-gpu-memclock not --pools-gpu-memclock)
|
||||
if(!strcasecmp(parentkey, "pools") || !strcasecmp(parentkey, "profiles"))
|
||||
parentkey[(strlen(parentkey) - 1)] = '\0';
|
||||
|
||||
json_array_foreach(obj, idx, val)
|
||||
{
|
||||
//abort on error
|
||||
if((err = parse_config(val, "", parentkey, fileconf, idx)))
|
||||
return err;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Parse JSON values from config file
|
||||
char *parse_config(json_t *val, const char *key, const char *parentkey, bool fileconf, int parent_iteration)
|
||||
{
|
||||
static char err_buf[200];
|
||||
char *err = NULL;
|
||||
struct opt_table *opt;
|
||||
char optname[255];
|
||||
/*const char *key
|
||||
json_t *val;*/
|
||||
|
||||
json_array_index = parent_iteration;
|
||||
|
||||
if (fileconf && !fileconf_load)
|
||||
fileconf_load = 1;
|
||||
|
||||
/*
|
||||
parse the json config items into opts instead of looking for opts in the json config...
|
||||
This adds greater flexibility with config files.
|
||||
*/
|
||||
switch(json_typeof(val))
|
||||
{
|
||||
//json value is an object
|
||||
case JSON_OBJECT:
|
||||
parse_config_object(val, parentkey, false, parent_iteration);
|
||||
break;
|
||||
|
||||
//json value is an array
|
||||
case JSON_ARRAY:
|
||||
err = parse_config_array(val, (char *)key, fileconf);
|
||||
break;
|
||||
|
||||
//other json types process here
|
||||
default:
|
||||
//convert json key to opt name
|
||||
sprintf(optname, "--%s%s%s", ((!empty_string(parentkey))?parentkey:""), ((!empty_string(parentkey))?"-":""), key);
|
||||
|
||||
//look up opt name in config table
|
||||
if((opt = opt_find(opt_config_table, optname)) != NULL)
|
||||
{
|
||||
//strings
|
||||
if ((opt->type & OPT_HASARG) && json_is_string(val))
|
||||
err = opt->cb_arg(json_string_value(val), opt->u.arg);
|
||||
//boolean values
|
||||
else if ((opt->type & OPT_NOARG) && json_is_true(val))
|
||||
err = opt->cb(opt->u.arg);
|
||||
else
|
||||
err = "Invalid value";
|
||||
}
|
||||
else
|
||||
err = "Invalid option";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//error processing JSON...
|
||||
if(err)
|
||||
{
|
||||
/* Allow invalid values to be in configuration
|
||||
* file, just skipping over them provided the
|
||||
* JSON is still valid after that. */
|
||||
if(fileconf)
|
||||
{
|
||||
applog(LOG_WARNING, "Skipping config option %s: %s", optname+2, err);
|
||||
fileconf_load = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(err_buf, sizeof(err_buf), "Error parsing JSON option %s: %s", optname+2, err);
|
||||
return err_buf;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *load_config(const char *arg, const char *parentkey, void __maybe_unused *unused)
|
||||
{
|
||||
json_error_t err;
|
||||
json_t *config;
|
||||
|
||||
//most likely useless but leaving it here for now...
|
||||
if(!cnfbuf)
|
||||
cnfbuf = strdup(arg);
|
||||
|
||||
//no need to restrict the number of includes... if it causes problems, restore it later
|
||||
/*if(++include_count > JSON_MAX_DEPTH)
|
||||
return JSON_MAX_DEPTH_ERR;
|
||||
*/
|
||||
|
||||
#if JANSSON_MAJOR_VERSION > 1
|
||||
config = json_load_file(arg, 0, &err);
|
||||
#else
|
||||
config = json_load_file(arg, &err);
|
||||
#endif
|
||||
|
||||
//if json root is not an object, error out
|
||||
if(!json_is_object(config))
|
||||
{
|
||||
set_last_json_error(JSON_LOAD_ERROR, arg, err.text);
|
||||
return last_json_error;
|
||||
}
|
||||
|
||||
config_loaded = true;
|
||||
|
||||
/* Parse the config now, so we can override it. That can keep pointers
|
||||
* so don't free config object. */
|
||||
return parse_config(config, "", parentkey, true, -1);
|
||||
}
|
||||
|
||||
char *set_default_config(const char *arg)
|
||||
{
|
||||
opt_set_charp(arg, &default_config);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void load_default_config(void)
|
||||
{
|
||||
cnfbuf = (char *)malloc(PATH_MAX);
|
||||
|
||||
default_save_file(cnfbuf);
|
||||
|
||||
if (!access(cnfbuf, R_OK))
|
||||
load_config(cnfbuf, "", NULL);
|
||||
else {
|
||||
free(cnfbuf);
|
||||
cnfbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Startup functions
|
||||
* *****************************************/
|
||||
|
||||
//assign default settings from default profile if set
|
||||
void load_default_profile()
|
||||
{
|
||||
struct profile *profile;
|
||||
|
||||
//if a default profile name is set
|
||||
if(!empty_string(default_profile.name))
|
||||
{
|
||||
//find profile and copy settings
|
||||
if((profile = get_profile(default_profile.name)))
|
||||
{
|
||||
default_profile.algorithm = profile->algorithm;
|
||||
default_profile.intensity = profile->intensity;
|
||||
default_profile.xintensity = profile->xintensity;
|
||||
default_profile.rawintensity = profile->rawintensity;
|
||||
default_profile.thread_concurrency = profile->thread_concurrency;
|
||||
#ifdef HAVE_ADL
|
||||
default_profile.gpu_engine = profile->gpu_engine;
|
||||
default_profile.gpu_memclock = profile->gpu_memclock;
|
||||
default_profile.gpu_threads = profile->gpu_threads;
|
||||
default_profile.gpu_fan = profile->gpu_fan;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//apply default settings
|
||||
void apply_defaults()
|
||||
{
|
||||
set_algorithm(opt_algorithm, default_profile.algorithm.name);
|
||||
|
||||
if(!empty_string(default_profile.intensity))
|
||||
set_intensity(default_profile.intensity);
|
||||
|
||||
if(!empty_string(default_profile.xintensity))
|
||||
set_xintensity(default_profile.xintensity);
|
||||
|
||||
if(!empty_string(default_profile.rawintensity))
|
||||
set_rawintensity(default_profile.rawintensity);
|
||||
|
||||
if(!empty_string(default_profile.thread_concurrency))
|
||||
set_thread_concurrency(default_profile.thread_concurrency);
|
||||
|
||||
#ifdef HAVE_ADL
|
||||
if(!empty_string(default_profile.gpu_engine))
|
||||
set_gpu_engine(default_profile.gpu_engine);
|
||||
|
||||
if(!empty_string(default_profile.gpu_memclock))
|
||||
set_gpu_memclock(default_profile.gpu_memclock);
|
||||
|
||||
if(!empty_string(default_profile.gpu_threads))
|
||||
set_gpu_threads(default_profile.gpu_threads);
|
||||
|
||||
if(!empty_string(default_profile.gpu_fan))
|
||||
set_gpu_fan(default_profile.gpu_fan);
|
||||
#endif
|
||||
}
|
||||
|
||||
//apply profile settings to pools
|
||||
void apply_pool_profiles()
|
||||
{
|
||||
struct profile *profile;
|
||||
int i;
|
||||
|
||||
for(i=total_pools;i--;)
|
||||
{
|
||||
//if the pool has a profile set
|
||||
if(!empty_string(pools[i]->profile))
|
||||
{
|
||||
applog(LOG_DEBUG, "Loading settings from profile \"%s\" for pool %i", pools[i]->profile, pools[i]->pool_no);
|
||||
|
||||
//find profile and apply settings to the pool
|
||||
if((profile = get_profile(pools[i]->profile)))
|
||||
{
|
||||
pools[i]->algorithm = profile->algorithm;
|
||||
applog(LOG_DEBUG, "Pool %i Algorithm set to \"%s\"", pools[i]->pool_no, pools[i]->algorithm.name);
|
||||
|
||||
if(!empty_string(profile->intensity))
|
||||
{
|
||||
pools[i]->intensity = profile->intensity;
|
||||
applog(LOG_DEBUG, "Pool %i Intensity set to \"%s\"", pools[i]->pool_no, pools[i]->intensity);
|
||||
}
|
||||
|
||||
if(!empty_string(profile->xintensity))
|
||||
{
|
||||
pools[i]->xintensity = profile->xintensity;
|
||||
applog(LOG_DEBUG, "Pool %i XIntensity set to \"%s\"", pools[i]->pool_no, pools[i]->xintensity);
|
||||
}
|
||||
|
||||
if(!empty_string(profile->rawintensity))
|
||||
{
|
||||
pools[i]->rawintensity = profile->rawintensity;
|
||||
applog(LOG_DEBUG, "Pool %i Raw Intensity set to \"%s\"", pools[i]->pool_no, pools[i]->rawintensity);
|
||||
}
|
||||
|
||||
if(!empty_string(profile->thread_concurrency))
|
||||
{
|
||||
pools[i]->thread_concurrency = profile->thread_concurrency;
|
||||
applog(LOG_DEBUG, "Pool %i Thread Concurrency set to \"%s\"", pools[i]->pool_no, pools[i]->thread_concurrency);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ADL
|
||||
if(!empty_string(profile->gpu_engine))
|
||||
{
|
||||
pools[i]->gpu_engine = profile->gpu_engine;
|
||||
applog(LOG_DEBUG, "Pool %i GPU Clock set to \"%s\"", pools[i]->pool_no, pools[i]->gpu_engine);
|
||||
}
|
||||
|
||||
if(!empty_string(profile->gpu_memclock))
|
||||
{
|
||||
pools[i]->gpu_memclock = profile->gpu_memclock;
|
||||
applog(LOG_DEBUG, "Pool %i GPU Memory clock set to \"%s\"", pools[i]->pool_no, pools[i]->gpu_memclock);
|
||||
}
|
||||
|
||||
if(!empty_string(profile->gpu_threads))
|
||||
{
|
||||
pools[i]->gpu_threads = profile->gpu_threads;
|
||||
applog(LOG_DEBUG, "Pool %i GPU Threads set to \"%s\"", pools[i]->pool_no, pools[i]->gpu_threads);
|
||||
}
|
||||
|
||||
if(!empty_string(profile->gpu_fan))
|
||||
{
|
||||
pools[i]->gpu_fan = profile->gpu_fan;
|
||||
applog(LOG_DEBUG, "Pool %i GPU Fan set to \"%s\"", pools[i]->pool_no, pools[i]->gpu_fan);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
applog(LOG_DEBUG, "Profile load failed for pool %i: profile %s not found.", pools[i]->pool_no, pools[i]->profile);
|
||||
}
|
||||
}
|
||||
}
|
88
config_parser.h
Normal file
88
config_parser.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef CONFIG_PARSER_H
|
||||
#define CONFIG_PARSER_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "miner.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
|
||||
|
||||
//profile structure
|
||||
struct profile {
|
||||
int profile_no;
|
||||
char *name;
|
||||
|
||||
algorithm_t algorithm;
|
||||
const char *intensity;
|
||||
const char *xintensity;
|
||||
const char *rawintensity;
|
||||
const char *thread_concurrency;
|
||||
const char *gpu_engine;
|
||||
const char *gpu_memclock;
|
||||
const char *gpu_threads;
|
||||
const char *gpu_fan;
|
||||
};
|
||||
|
||||
/* globals needed outside */
|
||||
extern char *cnfbuf;
|
||||
extern int fileconf_load;
|
||||
extern const char def_conf[];
|
||||
extern char *default_config;
|
||||
extern bool config_loaded;
|
||||
|
||||
extern int json_array_index;
|
||||
|
||||
extern struct profile default_profile;
|
||||
|
||||
/* option parser functions */
|
||||
extern char *set_default_intensity(const char *arg);
|
||||
extern char *set_default_xintensity(const char *arg);
|
||||
extern char *set_default_rawintensity(const char *arg);
|
||||
extern char *set_default_thread_concurrency(const char *arg);
|
||||
#ifdef HAVE_ADL
|
||||
extern char *set_default_gpu_engine(const char *arg);
|
||||
extern char *set_default_gpu_memclock(const char *arg);
|
||||
extern char *set_default_gpu_threads(const char *arg);
|
||||
extern char *set_default_gpu_fan(const char *arg);
|
||||
#endif
|
||||
extern char *set_default_profile(char *arg);
|
||||
|
||||
extern char *set_profile_name(char *arg);
|
||||
extern char *set_profile_algorithm(const char *arg);
|
||||
extern char *set_profile_intensity(const char *arg);
|
||||
extern char *set_profile_xintensity(const char *arg);
|
||||
extern char *set_profile_rawintensity(const char *arg);
|
||||
extern char *set_profile_thread_concurrency(const char *arg);
|
||||
#ifdef HAVE_ADL
|
||||
extern char *set_profile_gpu_engine(const char *arg);
|
||||
extern char *set_profile_gpu_memclock(const char *arg);
|
||||
extern char *set_profile_gpu_threads(const char *arg);
|
||||
extern char *set_profile_gpu_fan(const char *arg);
|
||||
#endif
|
||||
extern char *set_profile_nfactor(const char *arg);
|
||||
|
||||
/* helpers */
|
||||
//void set_last_json_error(const char *fmt, ...);
|
||||
//struct opt_table *opt_find(struct opt_table *tbl, char *optname);
|
||||
|
||||
/* config parser functions */
|
||||
//void parse_config_object(json_t *obj, const char *parentkey, bool fileconf, int parent_iteration);
|
||||
//char *parse_config_array(json_t *obj, char *parentkey, bool fileconf);
|
||||
extern char *parse_config(json_t *val, const char *key, const char *parentkey, bool fileconf, int parent_iteration);
|
||||
extern char *load_config(const char *arg, const char *parentkey, void __maybe_unused *unused);
|
||||
extern char *set_default_config(const char *arg);
|
||||
extern void load_default_config(void);
|
||||
|
||||
/*struct profile *add_profile();
|
||||
struct profile *get_current_profile();
|
||||
struct profile *get_profile(char *name);*/
|
||||
|
||||
extern void load_default_profile();
|
||||
extern void apply_defaults();
|
||||
extern void apply_pool_profiles();
|
||||
|
||||
#endif // CONFIG_PARSER_H
|
6
miner.h
6
miner.h
@ -124,6 +124,8 @@ static inline int fsync (int fd)
|
||||
#include "ADL_SDK/adl_sdk.h"
|
||||
#endif
|
||||
|
||||
#include <ccan/opt/opt.h>
|
||||
|
||||
#if (!defined(WIN32) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|
||||
|| (defined(WIN32) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
|
||||
#ifndef bswap_16
|
||||
@ -1081,6 +1083,9 @@ extern double best_diff;
|
||||
extern struct timeval block_timeval;
|
||||
extern char *workpadding;
|
||||
|
||||
//config options table
|
||||
extern struct opt_table opt_config_table[];
|
||||
|
||||
typedef struct _dev_blk_ctx {
|
||||
cl_uint ctx_a; cl_uint ctx_b; cl_uint ctx_c; cl_uint ctx_d;
|
||||
cl_uint ctx_e; cl_uint ctx_f; cl_uint ctx_g; cl_uint ctx_h;
|
||||
@ -1192,6 +1197,7 @@ struct pool {
|
||||
proxytypes_t rpc_proxytype;
|
||||
char *rpc_proxy;
|
||||
|
||||
char *profile;
|
||||
algorithm_t algorithm;
|
||||
const char *intensity;
|
||||
const char *xintensity;
|
||||
|
357
sgminer.c
357
sgminer.c
@ -58,6 +58,7 @@ char *curly = ":D";
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "pool.h"
|
||||
#include "config_parser.h"
|
||||
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
#include <errno.h>
|
||||
@ -233,9 +234,6 @@ enum pool_strategy pool_strategy = POOL_FAILOVER;
|
||||
int opt_rotate_period;
|
||||
static int total_urls;
|
||||
|
||||
/* Used in config parsing, e.g. pool array. */
|
||||
static int json_array_index = -1;
|
||||
|
||||
static
|
||||
#ifndef HAVE_CURSES
|
||||
const
|
||||
@ -280,16 +278,6 @@ static struct stratum_share *stratum_shares = NULL;
|
||||
|
||||
char *opt_socks_proxy = NULL;
|
||||
|
||||
static const char def_conf[] = "sgminer.conf";
|
||||
static char *default_config;
|
||||
static bool config_loaded;
|
||||
static int include_count;
|
||||
#define JSON_INCLUDE_CONF "include"
|
||||
#define JSON_LOAD_ERROR "JSON decode of file '%s' failed\n %s"
|
||||
#define JSON_LOAD_ERROR_LEN strlen(JSON_LOAD_ERROR)
|
||||
#define JSON_MAX_DEPTH 10
|
||||
#define JSON_MAX_DEPTH_ERR "Too many levels of JSON includes (limit 10) or a loop"
|
||||
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
static char *opt_stderr_cmd = NULL;
|
||||
static int forkpid;
|
||||
@ -526,6 +514,7 @@ struct pool *add_pool(void)
|
||||
char buf[32];
|
||||
buf[0] = '\0';
|
||||
pool->name = strdup(buf);
|
||||
pool->profile = strdup(buf); //profile blank by default
|
||||
|
||||
/* Algorithm */
|
||||
pool->algorithm = opt_algorithm;
|
||||
@ -854,6 +843,16 @@ static char *set_pool_name(char *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *set_pool_profile(char *arg)
|
||||
{
|
||||
struct pool *pool = get_current_pool();
|
||||
|
||||
applog(LOG_DEBUG, "Setting pool %i profile to %s", pool->pool_no, arg);
|
||||
opt_set_charp(arg, &pool->profile);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *set_poolname_deprecated(char *arg)
|
||||
{
|
||||
applog(LOG_ERR, "Specifying pool name by --poolname is deprecated. Use --name instead.");
|
||||
@ -1198,7 +1197,7 @@ char *set_difficulty_multiplier(char *arg)
|
||||
}
|
||||
|
||||
/* These options are available from config file or commandline */
|
||||
static struct opt_table opt_config_table[] = {
|
||||
struct opt_table opt_config_table[] = {
|
||||
OPT_WITH_ARG("--algorithm",
|
||||
set_algo, NULL, NULL,
|
||||
"Set mining algorithm and most common defaults, default: scrypt"),
|
||||
@ -1257,6 +1256,9 @@ static struct opt_table opt_config_table[] = {
|
||||
OPT_WITHOUT_ARG("--debug|-D",
|
||||
enable_debug, &opt_debug,
|
||||
"Enable debug output"),
|
||||
OPT_WITH_ARG("--default-profile",
|
||||
set_default_profile, NULL, NULL,
|
||||
"Set Default Profile"),
|
||||
OPT_WITH_ARG("--description",
|
||||
set_pool_description, NULL, NULL,
|
||||
"Pool description"),
|
||||
@ -1291,19 +1293,23 @@ static struct opt_table opt_config_table[] = {
|
||||
"Number of threads per GPU (1 - 10)"),
|
||||
#else
|
||||
OPT_WITH_ARG("--gpu-threads|-g",
|
||||
set_gpu_threads, NULL, NULL,
|
||||
// set_gpu_threads, NULL, NULL,
|
||||
set_default_gpu_threads, NULL, NULL,
|
||||
"Number of threads per GPU - one value or comma separated list (e.g. 1,2,1)"),
|
||||
OPT_WITH_ARG("--gpu-engine",
|
||||
set_gpu_engine, NULL, NULL,
|
||||
// set_gpu_engine, NULL, NULL,
|
||||
set_default_gpu_engine, NULL, NULL,
|
||||
"GPU engine (over)clock range in Mhz - one value, range and/or comma separated list (e.g. 850-900,900,750-850)"),
|
||||
OPT_WITH_ARG("--gpu-fan",
|
||||
set_gpu_fan, NULL, NULL,
|
||||
// set_gpu_fan, NULL, NULL,
|
||||
set_default_gpu_fan, NULL, NULL,
|
||||
"GPU fan percentage range - one value, range and/or comma separated list (e.g. 0-85,85,65)"),
|
||||
OPT_WITH_ARG("--gpu-map",
|
||||
set_gpu_map, NULL, NULL,
|
||||
"Map OpenCL to ADL device order manually, paired CSV (e.g. 1:0,2:1 maps OpenCL 1 to ADL 0, 2 to 1)"),
|
||||
OPT_WITH_ARG("--gpu-memclock",
|
||||
set_gpu_memclock, NULL, NULL,
|
||||
// set_gpu_memclock, NULL, NULL,
|
||||
set_default_gpu_memclock, NULL, NULL,
|
||||
"Set the GPU memory (over)clock in Mhz - one value for all or separate by commas for per card"),
|
||||
OPT_WITH_ARG("--gpu-memdiff",
|
||||
set_gpu_memdiff, NULL, NULL,
|
||||
@ -1317,18 +1323,6 @@ static struct opt_table opt_config_table[] = {
|
||||
OPT_WITH_ARG("--gpu-vddc",
|
||||
set_gpu_vddc, NULL, NULL,
|
||||
"Set the GPU voltage in Volts - one value for all or separate by commas for per card"),
|
||||
OPT_WITH_ARG("--pool-gpu-engine",
|
||||
set_pool_gpu_engine, NULL, NULL,
|
||||
"GPU engine (over)clock range in Mhz - one value, range and/or comma separated list (e.g. 850-900,900,750-850)"),
|
||||
OPT_WITH_ARG("--pool-gpu-memclock",
|
||||
set_pool_gpu_memclock, NULL, NULL,
|
||||
"Set the GPU memory (over)clock in Mhz - one value for all or separate by commas for per card"),
|
||||
OPT_WITH_ARG("--pool-gpu-threads",
|
||||
set_pool_gpu_threads, NULL, NULL,
|
||||
"Number of threads per GPU for pool"),
|
||||
OPT_WITH_ARG("--pool-gpu-fan",
|
||||
set_pool_gpu_fan, NULL, NULL,
|
||||
"GPU fan for pool"),
|
||||
#endif
|
||||
OPT_WITH_ARG("--lookup-gap",
|
||||
set_lookup_gap, NULL, NULL,
|
||||
@ -1344,28 +1338,16 @@ static struct opt_table opt_config_table[] = {
|
||||
OPT_WITHOUT_ARG("--more-notices",
|
||||
opt_set_bool, &opt_morenotices,
|
||||
"Shows work restart and new block notices, hidden by default"),
|
||||
OPT_WITH_ARG("--intensity|-I",
|
||||
set_intensity, NULL, NULL,
|
||||
"Intensity of GPU scanning (d or " MIN_INTENSITY_STR
|
||||
" -> " MAX_INTENSITY_STR
|
||||
",default: d to maintain desktop interactivity), overridden by --xintensity or --rawintensity."),
|
||||
OPT_WITH_ARG("--xintensity|-X",
|
||||
set_xintensity, NULL, NULL,
|
||||
// set_xintensity, NULL, NULL,
|
||||
set_default_xintensity, NULL, NULL,
|
||||
"Shader based intensity of GPU scanning (" MIN_XINTENSITY_STR " to "
|
||||
MAX_XINTENSITY_STR "), overrides --intensity|-I, overridden by --rawintensity."),
|
||||
OPT_WITH_ARG("--rawintensity",
|
||||
set_rawintensity, NULL, NULL,
|
||||
// set_rawintensity, NULL, NULL,
|
||||
set_default_rawintensity, NULL, NULL,
|
||||
"Raw intensity of GPU scanning (" MIN_RAWINTENSITY_STR " to "
|
||||
MAX_RAWINTENSITY_STR "), overrides --intensity|-I and --xintensity|-X."),
|
||||
OPT_WITH_ARG("--pool-intensity",
|
||||
set_pool_intensity, NULL, NULL,
|
||||
"Intensity of GPU scanning (pool-specific)"),
|
||||
OPT_WITH_ARG("--pool-xintensity",
|
||||
set_pool_xintensity, NULL, NULL,
|
||||
"Shader based intensity of GPU scanning (pool-specific)"),
|
||||
OPT_WITH_ARG("--pool-rawintensity",
|
||||
set_pool_rawintensity, NULL, NULL,
|
||||
"Raw intensity of GPU scanning (pool-specific)"),
|
||||
OPT_WITH_ARG("--kernel-path|-K",
|
||||
opt_set_charp, opt_show_charp, &opt_kernel_path,
|
||||
"Specify a path to where kernel files are"),
|
||||
@ -1386,7 +1368,7 @@ static struct opt_table opt_config_table[] = {
|
||||
opt_set_charp, NULL, &opt_stderr_cmd,
|
||||
"Use custom pipe cmd for output messages"),
|
||||
#endif // defined(unix)
|
||||
OPT_WITH_ARG("--name",
|
||||
OPT_WITH_ARG("--name|--pool-name",
|
||||
set_pool_name, NULL, NULL,
|
||||
"Name of pool"),
|
||||
OPT_WITHOUT_ARG("--net-delay",
|
||||
@ -1418,18 +1400,92 @@ static struct opt_table opt_config_table[] = {
|
||||
OPT_WITHOUT_ARG("--no-extranonce-subscribe",
|
||||
set_no_extranonce_subscribe, NULL,
|
||||
"Disable 'extranonce' stratum subscribe for pool"),
|
||||
OPT_WITH_ARG("--pass|-p",
|
||||
OPT_WITH_ARG("--pass|--pool-pass|-p",
|
||||
set_pass, NULL, NULL,
|
||||
"Password for bitcoin JSON-RPC server"),
|
||||
OPT_WITHOUT_ARG("--per-device-stats",
|
||||
opt_set_bool, &want_per_device_stats,
|
||||
"Force verbose mode and output per-device statistics"),
|
||||
|
||||
OPT_WITH_ARG("--poolname", /* TODO: Backward compatibility, to be removed. */
|
||||
set_poolname_deprecated, NULL, NULL,
|
||||
opt_hidden),
|
||||
OPT_WITH_ARG("--priority",
|
||||
OPT_WITH_ARG("--pool-algorithm",
|
||||
set_pool_algorithm, NULL, NULL,
|
||||
"Set algorithm for pool"),
|
||||
#ifdef HAVE_ADL
|
||||
OPT_WITH_ARG("--pool-gpu-engine",
|
||||
set_pool_gpu_engine, NULL, NULL,
|
||||
"Pool GPU engine (over)clock range in Mhz - one value, range and/or comma separated list (e.g. 850-900,900,750-850)"),
|
||||
OPT_WITH_ARG("--pool-gpu-fan",
|
||||
set_pool_gpu_fan, NULL, NULL,
|
||||
"GPU fan for pool"),
|
||||
OPT_WITH_ARG("--pool-gpu-memclock",
|
||||
set_pool_gpu_memclock, NULL, NULL,
|
||||
"Set the Pool GPU memory (over)clock in Mhz - one value for all or separate by commas for per card"),
|
||||
OPT_WITH_ARG("--pool-gpu-threads",
|
||||
set_pool_gpu_threads, NULL, NULL,
|
||||
"Number of threads per GPU for pool"),
|
||||
#endif
|
||||
OPT_WITH_ARG("--pool-intensity",
|
||||
set_pool_intensity, NULL, NULL,
|
||||
"Intensity of GPU scanning (pool-specific)"),
|
||||
OPT_WITH_ARG("--pool-nfactor",
|
||||
set_pool_nfactor, NULL, NULL,
|
||||
"Set N-factor for pool"),
|
||||
OPT_WITH_ARG("--pool-profile",
|
||||
set_pool_profile, NULL, NULL,
|
||||
"Profile to use with the pool"),
|
||||
OPT_WITH_ARG("--pool-rawintensity",
|
||||
set_pool_rawintensity, NULL, NULL,
|
||||
"Raw intensity of GPU scanning (pool-specific)"),
|
||||
OPT_WITH_ARG("--pool-thread-concurrency",
|
||||
set_pool_thread_concurrency, NULL, NULL,
|
||||
"Set thread concurrency for pool"),
|
||||
OPT_WITH_ARG("--pool-xintensity",
|
||||
set_pool_xintensity, NULL, NULL,
|
||||
"Shader based intensity of GPU scanning (pool-specific)"),
|
||||
|
||||
OPT_WITH_ARG("--priority|--pool-priority",
|
||||
set_pool_priority, NULL, NULL,
|
||||
"Pool priority"),
|
||||
|
||||
OPT_WITH_ARG("--profile-algorithm",
|
||||
set_profile_algorithm, NULL, NULL,
|
||||
"Set algorithm for profile"),
|
||||
#ifdef HAVE_ADL
|
||||
OPT_WITH_ARG("--profile-gpu-engine",
|
||||
set_profile_gpu_engine, NULL, NULL,
|
||||
"Profile GPU engine (over)clock range in Mhz - one value, range and/or comma separated list (e.g. 850-900,900,750-850)"),
|
||||
OPT_WITH_ARG("--profile-gpu-fan",
|
||||
set_profile_gpu_fan, NULL, NULL,
|
||||
"GPU fan for profile"),
|
||||
OPT_WITH_ARG("--profile-gpu-memclock",
|
||||
set_profile_gpu_memclock, NULL, NULL,
|
||||
"Set the Profile GPU memory (over)clock in Mhz - one value for all or separate by commas for per card"),
|
||||
OPT_WITH_ARG("--profile-gpu-threads",
|
||||
set_profile_gpu_threads, NULL, NULL,
|
||||
"Number of threads per GPU for profile"),
|
||||
#endif
|
||||
OPT_WITH_ARG("--profile-intensity",
|
||||
set_profile_intensity, NULL, NULL,
|
||||
"Intensity of GPU scanning (profile-specific)"),
|
||||
OPT_WITH_ARG("--profile-name",
|
||||
set_profile_name, NULL, NULL,
|
||||
"Profile Name"),
|
||||
OPT_WITH_ARG("--profile-nfactor",
|
||||
set_profile_nfactor, NULL, NULL,
|
||||
"Set N-factor for profile"),
|
||||
OPT_WITH_ARG("--profile-rawintensity",
|
||||
set_profile_rawintensity, NULL, NULL,
|
||||
"Raw intensity of GPU scanning (profile-specific)"),
|
||||
OPT_WITH_ARG("--profile-thread-concurrency",
|
||||
set_profile_thread_concurrency, NULL, NULL,
|
||||
"Set thread concurrency for profile"),
|
||||
OPT_WITH_ARG("--profile-xintensity",
|
||||
set_profile_xintensity, NULL, NULL,
|
||||
"Shader based intensity of GPU scanning (profile-specific)"),
|
||||
|
||||
OPT_WITHOUT_ARG("--protocol-dump|-P",
|
||||
opt_set_bool, &opt_protocol,
|
||||
"Verbose dump of protocol-level activities"),
|
||||
@ -1439,7 +1495,7 @@ static struct opt_table opt_config_table[] = {
|
||||
OPT_WITHOUT_ARG("--quiet|-q",
|
||||
opt_set_bool, &opt_quiet,
|
||||
"Disable logging output, display status and errors"),
|
||||
OPT_WITH_ARG("--quota|-U",
|
||||
OPT_WITH_ARG("--quota|--pool-quota|-U",
|
||||
set_quota, NULL, NULL,
|
||||
"quota;URL combination for server with load-balance strategy quotas"),
|
||||
OPT_WITHOUT_ARG("--real-quiet",
|
||||
@ -1525,21 +1581,13 @@ static struct opt_table opt_config_table[] = {
|
||||
opt_hidden),
|
||||
#endif
|
||||
OPT_WITH_ARG("--thread-concurrency",
|
||||
set_thread_concurrency, NULL, NULL,
|
||||
// set_thread_concurrency, NULL, NULL,
|
||||
set_default_thread_concurrency, NULL, NULL,
|
||||
"Set GPU thread concurrency for scrypt mining, comma separated"),
|
||||
OPT_WITH_ARG("--url|-o",
|
||||
OPT_WITH_ARG("--url|--pool-url|-o",
|
||||
set_url, NULL, NULL,
|
||||
"URL for bitcoin JSON-RPC server"),
|
||||
OPT_WITH_ARG("--pool-algorithm",
|
||||
set_pool_algorithm, NULL, NULL,
|
||||
"Set algorithm for pool"),
|
||||
OPT_WITH_ARG("--pool-nfactor",
|
||||
set_pool_nfactor, NULL, NULL,
|
||||
"Set N-factor for pool"),
|
||||
OPT_WITH_ARG("--pool-thread-concurrency",
|
||||
set_pool_thread_concurrency, NULL, NULL,
|
||||
"Set thread concurrency for pool"),
|
||||
OPT_WITH_ARG("--user|-u",
|
||||
OPT_WITH_ARG("--user|--pool-user|-u",
|
||||
set_user, NULL, NULL,
|
||||
"Username for bitcoin JSON-RPC server"),
|
||||
OPT_WITH_ARG("--vectors",
|
||||
@ -1561,153 +1609,16 @@ static struct opt_table opt_config_table[] = {
|
||||
"Display extra work time debug information"),
|
||||
OPT_WITH_ARG("--pools",
|
||||
opt_set_bool, NULL, NULL, opt_hidden),
|
||||
OPT_WITH_ARG("--profiles",
|
||||
opt_set_bool, NULL, NULL, opt_hidden),
|
||||
OPT_WITH_ARG("--difficulty-multiplier",
|
||||
set_difficulty_multiplier, NULL, NULL,
|
||||
"Difficulty multiplier for jobs received from stratum pools"),
|
||||
OPT_ENDTABLE
|
||||
};
|
||||
|
||||
static char *load_config(const char *arg, void __maybe_unused *unused);
|
||||
|
||||
static int fileconf_load;
|
||||
|
||||
static char *parse_config(json_t *config, bool fileconf, int parent_iteration)
|
||||
{
|
||||
static char err_buf[200];
|
||||
struct opt_table *opt;
|
||||
json_t *val;
|
||||
|
||||
json_array_index = parent_iteration;
|
||||
|
||||
if (fileconf && !fileconf_load)
|
||||
fileconf_load = 1;
|
||||
|
||||
for (opt = opt_config_table; opt->type != OPT_END; opt++) {
|
||||
char *p, *name;
|
||||
|
||||
/* We don't handle subtables. */
|
||||
assert(!(opt->type & OPT_SUBTABLE));
|
||||
|
||||
if (!opt->names)
|
||||
continue;
|
||||
|
||||
/* Pull apart the option name(s). */
|
||||
name = strdup(opt->names);
|
||||
for (p = strtok(name, "|"); p; p = strtok(NULL, "|")) {
|
||||
char *err = NULL;
|
||||
|
||||
/* Ignore short options. */
|
||||
if (p[1] != '-')
|
||||
continue;
|
||||
|
||||
val = json_object_get(config, p+2);
|
||||
if (!val)
|
||||
continue;
|
||||
|
||||
if ((opt->type & OPT_HASARG) && json_is_string(val)) {
|
||||
err = opt->cb_arg(json_string_value(val),
|
||||
opt->u.arg);
|
||||
} else if ((opt->type & OPT_HASARG) && json_is_array(val)) {
|
||||
size_t n, size = json_array_size(val);
|
||||
|
||||
for (n = 0; n < size && !err; n++) {
|
||||
if (json_is_string(json_array_get(val, n)))
|
||||
err = opt->cb_arg(json_string_value(json_array_get(val, n)), opt->u.arg);
|
||||
else if (json_is_object(json_array_get(val, n)))
|
||||
{
|
||||
err = parse_config(json_array_get(val, n), false, n);
|
||||
}
|
||||
}
|
||||
} else if ((opt->type & OPT_NOARG) && json_is_true(val))
|
||||
err = opt->cb(opt->u.arg);
|
||||
else
|
||||
err = "Invalid value";
|
||||
|
||||
if (err) {
|
||||
/* Allow invalid values to be in configuration
|
||||
* file, just skipping over them provided the
|
||||
* JSON is still valid after that. */
|
||||
if (fileconf) {
|
||||
applog(LOG_WARNING, "Skipping config option %s: %s", p, err);
|
||||
fileconf_load = -1;
|
||||
} else {
|
||||
snprintf(err_buf, sizeof(err_buf), "Error parsing JSON option %s: %s",
|
||||
p, err);
|
||||
return err_buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
|
||||
val = json_object_get(config, JSON_INCLUDE_CONF);
|
||||
if (val && json_is_string(val))
|
||||
return load_config(json_string_value(val), NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *cnfbuf = NULL;
|
||||
|
||||
static char *load_config(const char *arg, void __maybe_unused *unused)
|
||||
{
|
||||
json_error_t err;
|
||||
json_t *config;
|
||||
char *json_error;
|
||||
size_t siz;
|
||||
|
||||
if (!cnfbuf)
|
||||
cnfbuf = strdup(arg);
|
||||
|
||||
if (++include_count > JSON_MAX_DEPTH)
|
||||
return JSON_MAX_DEPTH_ERR;
|
||||
|
||||
#if JANSSON_MAJOR_VERSION > 1
|
||||
config = json_load_file(arg, 0, &err);
|
||||
#else
|
||||
config = json_load_file(arg, &err);
|
||||
#endif
|
||||
if (!json_is_object(config)) {
|
||||
siz = JSON_LOAD_ERROR_LEN + strlen(arg) + strlen(err.text);
|
||||
// TODO: memory leak
|
||||
json_error = (char *)malloc(siz);
|
||||
if (!json_error)
|
||||
quit(1, "Malloc failure in json error");
|
||||
|
||||
snprintf(json_error, siz, JSON_LOAD_ERROR, arg, err.text);
|
||||
return json_error;
|
||||
}
|
||||
|
||||
config_loaded = true;
|
||||
|
||||
/* Parse the config now, so we can override it. That can keep pointers
|
||||
* so don't free config object. */
|
||||
return parse_config(config, true, -1);
|
||||
}
|
||||
|
||||
static char *set_default_config(const char *arg)
|
||||
{
|
||||
opt_set_charp(arg, &default_config);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void default_save_file(char *filename);
|
||||
|
||||
static void load_default_config(void)
|
||||
{
|
||||
cnfbuf = (char *)malloc(PATH_MAX);
|
||||
|
||||
default_save_file(cnfbuf);
|
||||
|
||||
if (!access(cnfbuf, R_OK))
|
||||
load_config(cnfbuf, NULL);
|
||||
else {
|
||||
free(cnfbuf);
|
||||
cnfbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern const char *opt_argv0;
|
||||
|
||||
static char *opt_verusage_and_exit(const char *extra)
|
||||
@ -6195,32 +6106,49 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
||||
// Apply other pool-specific settings
|
||||
// TODO: when config parser is improved, add else statements and set
|
||||
// to default intensity
|
||||
if (work->pool->intensity)
|
||||
if(!empty_string(work->pool->intensity))
|
||||
set_intensity(work->pool->intensity);
|
||||
if (work->pool->xintensity)
|
||||
else if(!empty_string(default_profile.intensity))
|
||||
set_intensity(default_profile.intensity);
|
||||
|
||||
if (!empty_string(work->pool->xintensity))
|
||||
set_xintensity(work->pool->xintensity);
|
||||
if (work->pool->rawintensity)
|
||||
else if(!empty_string(default_profile.xintensity))
|
||||
set_xintensity(default_profile.xintensity);
|
||||
|
||||
if (!empty_string(work->pool->rawintensity))
|
||||
set_rawintensity(work->pool->rawintensity);
|
||||
if (work->pool->thread_concurrency)
|
||||
else if(!empty_string(default_profile.rawintensity))
|
||||
set_rawintensity(default_profile.rawintensity);
|
||||
|
||||
if (!empty_string(work->pool->thread_concurrency))
|
||||
set_thread_concurrency(work->pool->thread_concurrency);
|
||||
#ifdef HAVE_ADL
|
||||
if (work->pool->gpu_engine) {
|
||||
else if(!empty_string(default_profile.thread_concurrency))
|
||||
set_thread_concurrency(default_profile.thread_concurrency);
|
||||
|
||||
#ifdef HAVE_ADL
|
||||
if(!empty_string(work->pool->gpu_engine))
|
||||
{
|
||||
set_gpu_engine(work->pool->gpu_engine);
|
||||
for (i = 0; i < nDevs; i++)
|
||||
set_engineclock(i, gpus[i].min_engine);
|
||||
}
|
||||
if (work->pool->gpu_memclock) {
|
||||
|
||||
if(!empty_string(work->pool->gpu_memclock))
|
||||
{
|
||||
set_gpu_memclock(work->pool->gpu_memclock);
|
||||
for (i = 0; i < nDevs; i++)
|
||||
set_memoryclock(i, gpus[i].gpu_memclock);
|
||||
}
|
||||
if (work->pool->gpu_fan) {
|
||||
|
||||
if(!empty_string(work->pool->gpu_fan))
|
||||
{
|
||||
set_gpu_fan(work->pool->gpu_fan);
|
||||
for (i = 0; i < nDevs; i++)
|
||||
if (gpus[i].min_fan == gpus[i].gpu_fan)
|
||||
set_fanspeed(i, gpus[i].gpu_fan);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
// Change algorithm for each thread (thread_prepare calls initCl)
|
||||
for (i = 0; i < mining_threads; i++) {
|
||||
struct thr_info *thr = mining_thr[i];
|
||||
@ -7952,6 +7880,15 @@ int main(int argc, char *argv[])
|
||||
if (!config_loaded)
|
||||
load_default_config();
|
||||
|
||||
//load default profile if specified in config
|
||||
load_default_profile();
|
||||
|
||||
//apply default settings
|
||||
apply_defaults();
|
||||
|
||||
//apply pool-specific config from profiles
|
||||
apply_pool_profiles();
|
||||
|
||||
if (opt_benchmark) {
|
||||
struct pool *pool;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user