Browse Source

Updated config writer

Config writer now supports profiles and pool specific values. In
addition, the config writer now makes use of the jansson library to
create proper json objects and save them to the config file. This is
much better than trying to write our own json code.

Conflicts (resolved):
	sgminer.c
djm34
Noel Maersk 11 years ago
parent
commit
9fe5272c92
  1. 10
      api.c
  2. 994
      config_parser.c
  3. 19
      config_parser.h
  4. 24
      miner.h
  5. 320
      sgminer.c

10
api.c

@ -31,6 +31,8 @@
#include "util.h" #include "util.h"
#include "pool.h" #include "pool.h"
#include "config_parser.h"
// BUFSIZ varies on Windows and Linux // BUFSIZ varies on Windows and Linux
#define TMPBUFSIZ 8192 #define TMPBUFSIZ 8192
@ -2735,7 +2737,7 @@ void dosave(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, b
param = filename; param = filename;
} }
fcfg = fopen(param, "w"); /*fcfg = fopen(param, "w");
if (!fcfg) { if (!fcfg) {
ptr = escape_string(param, isjson); ptr = escape_string(param, isjson);
message(io_data, MSG_BADFN, 0, ptr, isjson); message(io_data, MSG_BADFN, 0, ptr, isjson);
@ -2743,10 +2745,10 @@ void dosave(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, b
free(ptr); free(ptr);
ptr = NULL; ptr = NULL;
return; return;
} }*/
write_config(fcfg); write_config(param);
fclose(fcfg); //fclose(fcfg);
ptr = escape_string(param, isjson); ptr = escape_string(param, isjson);
message(io_data, MSG_SAVED, 0, ptr, isjson); message(io_data, MSG_SAVED, 0, ptr, isjson);

994
config_parser.c

File diff suppressed because it is too large Load Diff

19
config_parser.h

@ -11,6 +11,11 @@
#define empty_string(str) ((str && str[0] != '\0')?0:1) #define empty_string(str) ((str && str[0] != '\0')?0:1)
#endif #endif
//helper function to get a gpu option value
#define 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;
@ -65,24 +70,18 @@ extern char *set_profile_thread_concurrency(const char *arg);
#endif #endif
extern char *set_profile_nfactor(const char *arg); 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 */ /* 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 *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 *load_config(const char *arg, const char *parentkey, void __maybe_unused *unused);
extern char *set_default_config(const char *arg); extern char *set_default_config(const char *arg);
extern void load_default_config(void); extern void load_default_config(void);
/*struct profile *add_profile(); /* startup functions */
struct profile *get_current_profile();
struct profile *get_profile(char *name);*/
extern void load_default_profile(); extern void load_default_profile();
extern void apply_defaults(); extern void apply_defaults();
extern void apply_pool_profiles(); extern void apply_pool_profiles();
/* config writer */
extern void write_config(const char *filename);
#endif // CONFIG_PARSER_H #endif // CONFIG_PARSER_H

24
miner.h

@ -934,7 +934,21 @@ extern bool opt_protocol;
extern bool have_longpoll; extern bool have_longpoll;
extern char *opt_kernel_path; extern char *opt_kernel_path;
extern char *opt_socks_proxy; extern char *opt_socks_proxy;
#if defined(unix) || defined(__APPLE__)
extern char *opt_stderr_cmd;
#endif // defined(unix)
struct schedtime {
bool enable;
struct tm tm;
};
extern struct schedtime schedstart;
extern struct schedtime schedstop;
extern char *sgminer_path; extern char *sgminer_path;
extern int opt_shares;
extern bool opt_fail_only; extern bool opt_fail_only;
extern bool opt_autofan; extern bool opt_autofan;
extern bool opt_autoengine; extern bool opt_autoengine;
@ -1058,6 +1072,9 @@ extern struct cgpu_info gpus[MAX_GPUDEVICES];
extern double total_secs; extern double total_secs;
extern int mining_threads; extern int mining_threads;
extern int total_devices; extern int total_devices;
extern bool devices_enabled[MAX_DEVICES];
extern int opt_devs_enabled;
extern bool opt_removedisabled;
extern struct cgpu_info **devices; extern struct cgpu_info **devices;
extern int total_pools; extern int total_pools;
extern struct pool **pools; extern struct pool **pools;
@ -1380,7 +1397,7 @@ extern void kill_work(void);
extern void switch_pools(struct pool *selected); extern void switch_pools(struct pool *selected);
extern void discard_work(struct work *work); extern void discard_work(struct work *work);
extern void remove_pool(struct pool *pool); extern void remove_pool(struct pool *pool);
extern void write_config(FILE *fcfg); //extern void write_config(FILE *fcfg);
extern void zero_bestshare(void); extern void zero_bestshare(void);
extern void zero_stats(void); extern void zero_stats(void);
extern void default_save_file(char *filename); extern void default_save_file(char *filename);
@ -1404,6 +1421,11 @@ extern struct work *copy_work_noffset(struct work *base_work, int noffset);
#define copy_work(work_in) copy_work_noffset(work_in, 0) #define copy_work(work_in) copy_work_noffset(work_in, 0)
extern struct cgpu_info *get_devices(int id); extern struct cgpu_info *get_devices(int id);
extern char *set_int_0_to_9999(const char *arg, int *i);
extern char *set_int_1_to_65535(const char *arg, int *i);
extern char *set_int_0_to_10(const char *arg, int *i);
extern char *set_int_1_to_10(const char *arg, int *i);
enum api_data_type { enum api_data_type {
API_ESCAPE, API_ESCAPE,
API_STRING, API_STRING,

320
sgminer.c

@ -113,10 +113,10 @@ int opt_hamsi_expand_big = 4;
bool opt_restart = true; bool opt_restart = true;
struct list_head scan_devices; struct list_head scan_devices;
static bool devices_enabled[MAX_DEVICES]; bool devices_enabled[MAX_DEVICES];
static int opt_devs_enabled; int opt_devs_enabled;
static bool opt_display_devs; static bool opt_display_devs;
static bool opt_removedisabled; bool opt_removedisabled;
int total_devices; int total_devices;
static int most_devices; static int most_devices;
struct cgpu_info **devices; struct cgpu_info **devices;
@ -129,7 +129,7 @@ bool use_curses;
#endif #endif
static bool opt_submit_stale = true; static bool opt_submit_stale = true;
static int opt_shares; int opt_shares;
bool opt_fail_only; bool opt_fail_only;
int opt_fail_switch_delay = 60; int opt_fail_switch_delay = 60;
static bool opt_fix_protocol; static bool opt_fix_protocol;
@ -279,7 +279,7 @@ static struct stratum_share *stratum_shares = NULL;
char *opt_socks_proxy = NULL; char *opt_socks_proxy = NULL;
#if defined(unix) || defined(__APPLE__) #if defined(unix) || defined(__APPLE__)
static char *opt_stderr_cmd = NULL; char *opt_stderr_cmd = NULL;
static int forkpid; static int forkpid;
#endif // defined(unix) #endif // defined(unix)
@ -292,11 +292,6 @@ struct thread_q *getq;
static int total_work; static int total_work;
struct work *staged_work = NULL; struct work *staged_work = NULL;
struct schedtime {
bool enable;
struct tm tm;
};
struct schedtime schedstart; struct schedtime schedstart;
struct schedtime schedstop; struct schedtime schedstop;
bool sched_paused; bool sched_paused;
@ -608,22 +603,22 @@ char *set_int_range(const char *arg, int *i, int min, int max)
return NULL; return NULL;
} }
static char *set_int_0_to_9999(const char *arg, int *i) char *set_int_0_to_9999(const char *arg, int *i)
{ {
return set_int_range(arg, i, 0, 9999); return set_int_range(arg, i, 0, 9999);
} }
static char *set_int_1_to_65535(const char *arg, int *i) char *set_int_1_to_65535(const char *arg, int *i)
{ {
return set_int_range(arg, i, 1, 65535); return set_int_range(arg, i, 1, 65535);
} }
static char *set_int_0_to_10(const char *arg, int *i) char *set_int_0_to_10(const char *arg, int *i)
{ {
return set_int_range(arg, i, 0, 10); return set_int_range(arg, i, 0, 10);
} }
static char *set_int_1_to_10(const char *arg, int *i) char *set_int_1_to_10(const char *arg, int *i)
{ {
return set_int_range(arg, i, 1, 10); return set_int_range(arg, i, 1, 10);
} }
@ -4243,285 +4238,6 @@ static void display_pool_summary(struct pool *pool)
} }
#endif #endif
/* add a mutex if this needs to be thread safe in the future */
static struct JE {
char *buf;
struct JE *next;
} *jedata = NULL;
static void json_escape_free()
{
struct JE *jeptr = jedata;
struct JE *jenext;
jedata = NULL;
while (jeptr) {
jenext = jeptr->next;
free(jeptr->buf);
free(jeptr);
jeptr = jenext;
}
}
static char *json_escape(char *str)
{
struct JE *jeptr;
char *buf, *ptr;
/* 2x is the max, may as well just allocate that */
ptr = buf = (char *)malloc(strlen(str) * 2 + 1);
jeptr = (struct JE *)malloc(sizeof(*jeptr));
jeptr->buf = buf;
jeptr->next = jedata;
jedata = jeptr;
while (*str) {
if (*str == '\\' || *str == '"')
*(ptr++) = '\\';
*(ptr++) = *(str++);
}
*ptr = '\0';
return buf;
}
void write_config(FILE *fcfg)
{
int i;
/* Write pool values */
fputs("{\n\"pools\" : [", fcfg);
for(i = 0; i < total_pools; i++) {
struct pool *pool = pools[i];
fprintf(fcfg, "%s", i > 0 ? "," : "");
if (pool->quota != 1) {
fprintf(fcfg, "\n\t{\n\t\t\"quota\" : \"%s%s%s%d;%s\"",
pool->rpc_proxy ? json_escape((char *)proxytype(pool->rpc_proxytype)) : "",
pool->rpc_proxy ? json_escape(pool->rpc_proxy) : "",
pool->rpc_proxy ? "|" : "",
pool->quota,
json_escape(pool->rpc_url));
} else {
fprintf(fcfg, "\n\t{\n\t\t\"url\" : \"%s%s%s%s\"",
pool->rpc_proxy ? json_escape((char *)proxytype(pool->rpc_proxytype)) : "",
pool->rpc_proxy ? json_escape(pool->rpc_proxy) : "",
pool->rpc_proxy ? "|" : "",
json_escape(pool->rpc_url));
}
if (!pool->extranonce_subscribe)
fprintf(fcfg, ",\n\t\t\"no-extranonce-subscribe\" : true");
fprintf(fcfg, ",\n\t\t\"user\" : \"%s\"", json_escape(pool->rpc_user));
fprintf(fcfg, ",\n\t\t\"pass\" : \"%s\"", json_escape(pool->rpc_pass));
/* Using get_pool_name() here is unsafe if opt_incognito is true. */
if (strcmp(pool->name, "") != 0) {
fprintf(fcfg, ",\n\t\t\"name\" : \"%s\"", json_escape(pool->name));
}
if (strcmp(pool->description, "") != 0) {
fprintf(fcfg, ",\n\t\t\"description\" : \"%s\"", json_escape(pool->description));
}
if (!cmp_algorithm(&pool->algorithm, &opt_algorithm)) {
fprintf(fcfg, ",\n\t\t\"algorithm\" : \"%s\"", json_escape(pool->algorithm.name));
}
if (pool->prio != i) {
fprintf(fcfg, ",\n\t\t\"priority\" : \"%d\"", pool->prio);
}
fprintf(fcfg, "\n\t}");
}
fputs("\n]\n", fcfg);
/* Write only if there are usable GPUs */
if (nDevs) {
fputs(",\n\"intensity\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
if (gpus[i].dynamic)
fprintf(fcfg, "%sd", i > 0 ? "," : "");
else
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].intensity);
fputs("\",\n\"xintensity\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].xintensity);
fputs("\",\n\"rawintensity\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].rawintensity);
/* All current kernels only support vector=1 */
/* fputs("\",\n\"vectors\" : \"", fcfg); */
/* for(i = 0; i < nDevs; i++) */
/* fprintf(fcfg, "%s%d", i > 0 ? "," : "", */
/* gpus[i].vwidth); */
fputs("\",\n\"worksize\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "",
(int)gpus[i].work_size);
fputs("\",\n\"algorithm\" : \"", fcfg);
for(i = 0; i < nDevs; i++) {
fprintf(fcfg, "%s", i > 0 ? "," : "");
fprintf(fcfg, "%s", gpus[i].algorithm.name);
}
fputs("\",\n\"lookup-gap\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "",
(int)gpus[i].opt_lg);
fputs("\",\n\"thread-concurrency\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "",
(int)gpus[i].opt_tc);
fputs("\",\n\"shaders\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "",
(int)gpus[i].shaders);
fputs("\",\n\"gpu-threads\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "",
(int)gpus[i].threads);
#ifdef HAVE_ADL
fputs("\",\n\"gpu-engine\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "", gpus[i].min_engine, gpus[i].gpu_engine);
fputs("\",\n\"gpu-fan\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "", gpus[i].min_fan, gpus[i].gpu_fan);
fputs("\",\n\"gpu-memclock\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_memclock);
fputs("\",\n\"gpu-memdiff\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_memdiff);
fputs("\",\n\"gpu-powertune\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_powertune);
fputs("\",\n\"gpu-vddc\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%1.3f", i > 0 ? "," : "", gpus[i].gpu_vddc);
fputs("\",\n\"temp-cutoff\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].cutofftemp);
fputs("\",\n\"temp-overheat\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].adl.overtemp);
fputs("\",\n\"temp-target\" : \"", fcfg);
for(i = 0; i < nDevs; i++)
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].adl.targettemp);
#endif
fputs("\"", fcfg);
}
#ifdef HAVE_ADL
if (opt_reorder)
fprintf(fcfg, ",\n\"gpu-reorder\" : true");
#endif
/* Simple bool and int options */
struct opt_table *opt;
for (opt = opt_config_table; opt->type != OPT_END; opt++) {
char *p, *name = strdup(opt->names);
for (p = strtok(name, "|"); p; p = strtok(NULL, "|")) {
if (p[1] != '-')
continue;
if (opt->type & OPT_NOARG &&
((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)))
fprintf(fcfg, ",\n\"%s\" : true", p+2);
if (opt->type & OPT_HASARG &&
((void *)opt->cb_arg == (void *)set_int_0_to_9999 ||
(void *)opt->cb_arg == (void *)set_int_1_to_65535 ||
(void *)opt->cb_arg == (void *)set_int_0_to_10 ||
(void *)opt->cb_arg == (void *)set_int_1_to_10) && opt->desc != opt_hidden)
fprintf(fcfg, ",\n\"%s\" : \"%d\"", p+2, *(int *)opt->u.arg);
}
}
/* Special case options */
fprintf(fcfg, ",\n\"shares\" : \"%d\"", opt_shares);
if (pool_strategy == POOL_BALANCE)
fputs(",\n\"balance\" : true", fcfg);
if (pool_strategy == POOL_LOADBALANCE)
fputs(",\n\"load-balance\" : true", fcfg);
if (pool_strategy == POOL_ROUNDROBIN)
fputs(",\n\"round-robin\" : true", fcfg);
if (pool_strategy == POOL_ROTATE)
fprintf(fcfg, ",\n\"rotate\" : \"%d\"", opt_rotate_period);
#if defined(unix) || defined(__APPLE__)
if (opt_stderr_cmd && *opt_stderr_cmd)
fprintf(fcfg, ",\n\"monitor\" : \"%s\"", json_escape(opt_stderr_cmd));
#endif // defined(unix)
if (opt_kernel_path && *opt_kernel_path) {
char *kpath = strdup(opt_kernel_path);
if (kpath[strlen(kpath)-1] == '/')
kpath[strlen(kpath)-1] = 0;
fprintf(fcfg, ",\n\"kernel-path\" : \"%s\"", json_escape(kpath));
}
if (schedstart.enable)
fprintf(fcfg, ",\n\"sched-time\" : \"%d:%d\"", schedstart.tm.tm_hour, schedstart.tm.tm_min);
if (schedstop.enable)
fprintf(fcfg, ",\n\"stop-time\" : \"%d:%d\"", schedstop.tm.tm_hour, schedstop.tm.tm_min);
if (opt_socks_proxy && *opt_socks_proxy)
fprintf(fcfg, ",\n\"socks-proxy\" : \"%s\"", json_escape(opt_socks_proxy));
if (opt_devs_enabled) {
fprintf(fcfg, ",\n\"device\" : \"");
bool extra_devs = false;
for (i = 0; i < MAX_DEVICES; i++) {
if (devices_enabled[i]) {
int startd = i;
if (extra_devs)
fprintf(fcfg, ",");
while (i < MAX_DEVICES && devices_enabled[i + 1])
++i;
fprintf(fcfg, "%d", startd);
if (i > startd)
fprintf(fcfg, "-%d", i);
}
}
fprintf(fcfg, "\"");
}
if (opt_removedisabled)
fprintf(fcfg, ",\n\"remove-disabled\" : true");
if (strcmp(opt_algorithm.name, "scrypt") != 0)
fprintf(fcfg, ",\n\"algorithm\" : \"%s\"", json_escape(opt_algorithm.name));
if (opt_api_allow)
fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", json_escape(opt_api_allow));
if (strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0)
fprintf(fcfg, ",\n\"api-mcast-addr\" : \"%s\"", json_escape(opt_api_mcast_addr));
if (strcmp(opt_api_mcast_code, API_MCAST_CODE) != 0)
fprintf(fcfg, ",\n\"api-mcast-code\" : \"%s\"", json_escape(opt_api_mcast_code));
if (*opt_api_mcast_des)
fprintf(fcfg, ",\n\"api-mcast-des\" : \"%s\"", json_escape(opt_api_mcast_des));
if (strcmp(opt_api_description, PACKAGE_STRING) != 0)
fprintf(fcfg, ",\n\"api-description\" : \"%s\"", json_escape(opt_api_description));
if (opt_api_groups)
fprintf(fcfg, ",\n\"api-groups\" : \"%s\"", json_escape(opt_api_groups));
fputs("\n}\n", fcfg);
json_escape_free();
}
void zero_bestshare(void) void zero_bestshare(void)
{ {
int i; int i;
@ -4975,13 +4691,13 @@ retry:
} }
else else
free(str); free(str);
fcfg = fopen(filename, "w"); /*fcfg = fopen(filename, "w");
if (!fcfg) { if (!fcfg) {
wlogprint("Cannot open or create file\n"); wlogprint("Cannot open or create file\n");
goto retry; goto retry;
} }*/
write_config(fcfg); write_config(filename);
fclose(fcfg); //fclose(fcfg);
goto retry; goto retry;
} else if (!strncasecmp(&input, "r", 1)) { } else if (!strncasecmp(&input, "r", 1)) {
@ -7889,6 +7605,16 @@ int main(int argc, char *argv[])
//apply pool-specific config from profiles //apply pool-specific config from profiles
apply_pool_profiles(); apply_pool_profiles();
/*FILE *fcfg = fopen("testconf_test.conf", "w");
if (!fcfg) {
wlogprint("Cannot open or create file\n");
quit(1,"");
}*/
write_config("./testconf_test.conf");
//fclose(fcfg);
quit(1,"file saved.");
if (opt_benchmark) { if (opt_benchmark) {
struct pool *pool; struct pool *pool;

Loading…
Cancel
Save