#include "find.h"
#include "util.h"
#include "timestamp.h"
+#include "server_util.h"
disklist_t diskq;
int main(int argc, char **argv);
void usage(void);
+static void estimate(int argc, char **argv);
+static void estimate_one(disk_t *dp);
void force(int argc, char **argv);
void force_one(disk_t *dp);
void unforce(int argc, char **argv);
int bump_thresh(int level);
void export_db(int argc, char **argv);
void import_db(int argc, char **argv);
+void hosts(int argc, char **argv);
+void dles(int argc, char **argv);
void disklist(int argc, char **argv);
void disklist_one(disk_t *dp);
void show_version(int argc, char **argv);
T_("\t\t\t\t\t# Show version info.") },
{ "config", show_config,
T_("\t\t\t\t\t# Show configuration.") },
+ { "estimate", estimate,
+ T_(" [<hostname> [<disks>]* ]*\t# Print server estimate.") },
{ "force", force,
T_(" [<hostname> [<disks>]* ]+\t\t# Force level 0 at next run.") },
{ "unforce", unforce,
T_(" [<hostname> [<disks>]* ]+\t# Clear bump command.") },
{ "disklist", disklist,
T_(" [<hostname> [<disks>]* ]*\t# Debug disklist entries.") },
+ { "hosts", hosts,
+ T_("\t\t\t\t\t# Show all distinct hosts in disklist.") },
+ { "dles", dles,
+ T_("\t\t\t\t\t# Show all dles in disklist, one per line.") },
{ "reuse", reuse,
T_(" <tapelabel> ...\t\t # re-use this tape.") },
{ "no-reuse", noreuse,
int i;
char *conf_diskfile;
char *conf_infofile;
- config_overwrites_t *cfg_ovr = NULL;
+ config_overrides_t *cfg_ovr = NULL;
/*
* Configure program for internationalization:
dbopen(DBG_SUBDIR_SERVER);
- erroutput_type = ERR_INTERACTIVE;
+ add_amanda_log_handler(amanda_log_stderr);
- cfg_ovr = extract_commandline_config_overwrites(&argc, &argv);
+ cfg_ovr = extract_commandline_config_overrides(&argc, &argv);
if(argc < 3) usage();
+ set_config_overrides(cfg_ovr);
+ config_init(CONFIG_INIT_EXPLICIT_NAME, argv[1]);
+
if(strcmp(argv[2],"version") == 0) {
show_version(argc, argv);
goto done;
}
- config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_FATAL, argv[1]);
- apply_config_overwrites(cfg_ovr);
+ conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+ read_diskfile(conf_diskfile, &diskq);
+ amfree(conf_diskfile);
- dbrename(config_name, DBG_SUBDIR_SERVER);
+ if (config_errors(NULL) >= CFGERR_WARNINGS) {
+ config_print_errors();
+ if (config_errors(NULL) >= CFGERR_ERRORS) {
+ g_critical(_("errors processing config file"));
+ }
+ }
- check_running_as(RUNNING_AS_DUMPUSER);
+ dbrename(get_config_name(), DBG_SUBDIR_SERVER);
- conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
- if (read_diskfile(conf_diskfile, &diskq) < 0) {
- error(_("could not load disklist \"%s\""), conf_diskfile);
- /*NOTREACHED*/
- }
- amfree(conf_diskfile);
+ check_running_as(RUNNING_AS_DUMPUSER);
conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
if(read_tapelist(conf_tapelist)) {
{
int i;
- g_fprintf(stderr, _("\nUsage: %s%s <conf> <command> {<args>} [-o configoption]* ...\n"),
- get_pname(), versionsuffix());
+ g_fprintf(stderr, _("\nUsage: %s [-o configoption]* <conf> <command> {<args>} ...\n"),
+ get_pname());
g_fprintf(stderr, _(" Valid <command>s are:\n"));
for (i = 0; i < NCMDS; i++)
g_fprintf(stderr, "\t%s%s\n", cmdtab[i].name, _(cmdtab[i].usage));
/* ----------------------------------------------- */
+static void
+estimate_one(
+ disk_t * dp)
+{
+ char *hostname = dp->host->hostname;
+ char *diskname = dp->name;
+ char *qhost = quote_string(hostname);
+ char *qdisk = quote_string(diskname);
+ info_t info;
+ int stats;
+ gint64 size;
+
+ get_info(hostname, diskname, &info);
+
+ size = internal_server_estimate(dp, &info, 0, &stats);
+ if (stats) {
+ printf("%s %s %d %jd\n", qhost, qdisk, 0, (intmax_t)size);
+ }
+
+ if (info.last_level > 0) {
+ size = internal_server_estimate(dp, &info, info.last_level, &stats);
+ if (stats) {
+ printf("%s %s %d %jd\n", qhost, qdisk, info.last_level,
+ (intmax_t)size);
+ }
+ }
+
+ if (info.last_level > -1) {
+ size = internal_server_estimate(dp, &info, info.last_level+1, &stats);
+ if (stats) {
+ printf("%s %s %d %jd\n", qhost, qdisk, info.last_level+1,
+ (intmax_t)size);
+ }
+ }
+
+ amfree(qhost);
+ amfree(qdisk);
+}
+
+
+static void
+estimate(
+ int argc,
+ char ** argv)
+{
+ disk_t *dp;
+
+ if(argc >= 4)
+ diskloop(argc, argv, "estimate", estimate_one);
+ else
+ for(dp = diskq.head; dp != NULL; dp = dp->next)
+ estimate_one(dp);
+}
+
+
+/* ----------------------------------------------- */
+
+
void
force_one(
disk_t * dp)
char *sort_order = NULL;
find_result_t *output_find;
char *errstr;
+ char **output_find_log;
+ char **name;
if(argc < 3) {
g_fprintf(stderr,
- _("%s: expecting \"find [--sort <hkdlpbf>] [hostname [<disk>]]*\"\n"),
+ _("%s: expecting \"find [--sort <hkdlpbfw>] [hostname [<disk>]]*\"\n"),
get_pname());
usage();
}
case 'P':
case 'b':
case 'B':
+ case 'w':
+ case 'W':
break;
default: valid_sort=0;
}
start_argc=4;
}
errstr = match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
- if (errstr) {
- g_printf("%s", errstr);
- amfree(errstr);
+
+ /* check all log file exists */
+ output_find_log = find_log();
+ for (name = output_find_log; *name != NULL; name++) {
+ amfree(*name);
}
+ amfree(output_find_log);
- output_find = find_dump(&diskq);
+ output_find = find_dump(&diskq); /* Add deleted dump to diskq */
if(argc-(start_argc-1) > 0) {
- free_find_result(&output_find);
+ find_result_t *afind = NULL;
+ find_result_t *afind_next = NULL;
+ find_result_t *new_output_find = NULL;
+ disk_t *dp;
+
+ amfree(errstr);
errstr = match_disklist(&diskq, argc-(start_argc-1),
argv+(start_argc-1));
if (errstr) {
g_printf("%s", errstr);
amfree(errstr);
}
- output_find = find_dump(NULL);
+ for (afind = output_find; afind; afind = afind_next) {
+ afind_next = afind->next;
+ dp = lookup_disk(afind->hostname, afind->diskname);
+ if (dp->todo) {
+ afind->next = new_output_find;
+ new_output_find = afind;
+ } else {
+ amfree(afind);
+ }
+ }
+ output_find = new_output_find;
+ } else if (errstr) {
+ g_printf("%s", errstr);
+ amfree(errstr);
}
sort_find_result(sort_order, &output_find);
}
if (get_info(file.name, file.disk, &info) == -1) {
- g_printf(_("WARNING: No curinfo record for %s:%s\n"), file.name, file.disk);
- return 1; /* not an error */
+ g_printf(_("WARNING: No curinfo record for %s:%s\n"), file.name, file.disk);
+ dumpfile_free_data(&file);
+ return 1; /* not an error */
}
matching_hist_idx = holding_file_find_history(&info, &file);
if (matching_hist_idx == -1) {
g_printf(_("WARNING: No dump matching %s found in curinfo.\n"), filename);
+ dumpfile_free_data(&file);
return 1; /* not an error */
}
matching_hist = info.history[matching_hist_idx];
/* Remove the history element itself before doing the stats */
- for (i = matching_hist_idx; i <= NB_HISTORY; i++) {
+ for (i = matching_hist_idx; i < NB_HISTORY; i++) {
info.history[i] = info.history[i+1];
}
info.history[NB_HISTORY].level = -1;
/* write out the changes */
if (put_info(file.name, file.disk, &info) == -1) {
- g_printf(_("Could not write curinfo record for %s:%s\n"), file.name, file.disk);
- return 0;
+ g_printf(_("Could not write curinfo record for %s:%s\n"), file.name, file.disk);
+ dumpfile_free_data(&file);
+ return 0;
}
+ dumpfile_free_data(&file);
return 1;
}
}
}
amfree(dumpstr);
+ dumpfile_free_data(&file);
}
- g_slist_free_full(file_list);
+ slist_free_full(file_list, g_free);
break;
case HOLDING_DELETE:
error(_("Could not delete '%s'"), (char *)li->data);
}
}
- g_slist_free_full(file_list);
+ slist_free_full(file_list, g_free);
break;
}
}
char hostname[MAX_HOSTNAME_LENGTH+1];
int i;
- g_printf(_("CURINFO Version %s CONF %s\n"), version(), getconf_str(CNF_ORG));
+ g_printf(_("CURINFO Version %s CONF %s\n"), VERSION, getconf_str(CNF_ORG));
curtime = time(0);
if(gethostname(hostname, SIZEOF(hostname)-1) == -1) {
{
info_t info;
int i,l;
+ char *qhost, *qdisk;
if(get_info(dp->host->hostname, dp->name, &info)) {
g_fprintf(stderr, _("Warning: no curinfo record for %s:%s\n"),
dp->host->hostname, dp->name);
return;
}
- g_printf(_("host: %s\ndisk: %s\n"), dp->host->hostname, dp->name);
+ qhost = quote_string(dp->host->hostname);
+ qdisk = quote_string(dp->name);
+ g_printf(_("host: %s\ndisk: %s\n"), qhost, qdisk);
g_printf(_("command: %u\n"), info.command);
g_printf(_("last_level: %d\n"),info.last_level);
g_printf(_("consecutive_runs: %d\n"),info.consecutive_runs);
(intmax_t)info.history[l].date);
}
g_printf("//\n");
+ amfree(qhost);
+ amfree(qdisk);
}
/* ----------------------------------------------- */
skip_whitespace(s, ch);
if(ch == '\0'
|| sscanf(s - 1, "%d.%d.%d", &vers_maj, &vers_min, &vers_patch) != 3) {
- goto bad_header;
+ vers_patch = -1;
+ if (sscanf(s - 1, "%d.%d", &vers_maj, &vers_min) != 2) {
+ goto bad_header;
+ }
}
skip_integer(s, ch); /* skip over major */
}
ch = *s++;
skip_integer(s, ch); /* skip over minor */
- if(ch != '.') {
- goto bad_header;
+ if (vers_patch != -1) {
+ if (ch != '.') {
+ goto bad_header;
+ }
+ ch = *s++;
+ skip_integer(s, ch); /* skip over patch */
+ } else {
+ vers_patch = 0;
}
- ch = *s++;
- skip_integer(s, ch); /* skip over patch */
hdr = "comment";
if(ch == '\0') {
skip_whitespace(s, ch);
if(ch == '\0') goto parse_err;
fp = s-1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- hostname = stralloc(fp);
+ hostname = unquote_string(fp);
s[-1] = (char)ch;
skip_whitespace(s, ch);
skip_whitespace(s, ch);
if(ch == '\0') goto parse_err;
fp = s-1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- diskname = stralloc(fp);
+ diskname = unquote_string(fp);
s[-1] = (char)ch;
amfree(line);
am_host_t *hp;
netif_t *ip;
sle_t *excl;
+ identlist_t pp_scriptlist;
+ estimatelist_t estimates;
+ dumptype_t *dtype = lookup_dumptype(dp->dtype_name);
hp = dp->host;
ip = hp->netif;
- g_printf("line %d:\n", dp->line);
+ g_printf("line %d (%s):\n", dp->line, dp->filename);
g_printf(" host %s:\n", hp->hostname);
g_printf(" interface %s\n",
interface_name(ip->config)[0] ? interface_name(ip->config) : "default");
g_printf(" disk %s:\n", dp->name);
- if(dp->device) g_printf(" device %s\n", dp->device);
+ if (dp->device) g_printf(" device %s\n", dp->device);
g_printf(" program \"%s\"\n", dp->program);
- if(dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
+ if (dp->application)
+ g_printf(" application \"%s\"\n", dp->application);
+ g_printf(" data-path %s\n", data_path_to_string(dp->data_path));
+ if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
g_printf(" exclude file");
for(excl = dp->exclude_file->first; excl != NULL; excl = excl->next) {
g_printf(" \"%s\"", excl->name);
}
g_printf("\n");
}
- if(dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
+ if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
g_printf(" exclude list");
if(dp->exclude_optional) g_printf(" optional");
for(excl = dp->exclude_list->first; excl != NULL; excl = excl->next) {
}
g_printf("\n");
}
- if(dp->include_file != NULL && dp->include_file->nb_element > 0) {
+ if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
g_printf(" include file");
for(excl = dp->include_file->first; excl != NULL; excl = excl->next) {
g_printf(" \"%s\"", excl->name);
}
g_printf("\n");
}
- if(dp->include_list != NULL && dp->include_list->nb_element > 0) {
+ if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
g_printf(" include list");
- if(dp->include_optional) g_printf(" optional");
+ if (dp->include_optional) g_printf(" optional");
for(excl = dp->include_list->first; excl != NULL; excl = excl->next) {
g_printf(" \"%s\"", excl->name);
}
g_printf(" dumpcycle %d\n", dp->dumpcycle);
g_printf(" maxdumps %d\n", dp->maxdumps);
g_printf(" maxpromoteday %d\n", dp->maxpromoteday);
- if(dp->bumppercent > 0) {
+ if (dp->bumppercent > 0) {
g_printf(" bumppercent %d\n", dp->bumppercent);
}
else {
}
g_printf(" ignore %s\n", (dp->ignore? "YES" : "NO"));
g_printf(" estimate ");
- switch(dp->estimate) {
- case ES_CLIENT:
- g_printf("CLIENT\n");
- break;
- case ES_SERVER:
- g_printf("SERVER\n");
- break;
- case ES_CALCSIZE:
- g_printf("CALCSIZE\n");
- break;
+ estimates = dp->estimatelist;
+ while (estimates) {
+ switch((estimate_t)GPOINTER_TO_INT(estimates->data)) {
+ case ES_CLIENT:
+ g_printf("CLIENT");
+ break;
+ case ES_SERVER:
+ g_printf("SERVER");
+ break;
+ case ES_CALCSIZE:
+ g_printf("CALCSIZE");
+ break;
+ case ES_ES:
+ break;
+ }
+ estimates = estimates->next;
+ if (estimates)
+ g_printf(", ");
}
+ g_printf("\n");
g_printf(" compress ");
switch(dp->compress) {
case COMP_BEST:
g_printf("CLIENT BEST\n");
break;
+ case COMP_CUST:
+ g_printf("CLIENT CUSTOM\n");
+ g_printf(" client-custom-compress \"%s\"\n",
+ dp->clntcompprog? dp->clntcompprog : "");
+ break;
case COMP_SERVER_FAST:
g_printf("SERVER FAST\n");
break;
case COMP_SERVER_BEST:
g_printf("SERVER BEST\n");
break;
+ case COMP_SERVER_CUST:
+ g_printf("SERVER CUSTOM\n");
+ g_printf(" server-custom-compress \"%s\"\n",
+ dp->srvcompprog? dp->srvcompprog : "");
+ break;
}
if(dp->compress != COMP_NONE) {
g_printf(" comprate %.2lf %.2lf\n",
break;
case ENCRYPT_CUST:
g_printf("CLIENT\n");
+ g_printf(" client-encrypt \"%s\"\n",
+ dp->clnt_encrypt? dp->clnt_encrypt : "");
+ g_printf(" client-decrypt-option \"%s\"\n",
+ dp->clnt_decrypt_opt? dp->clnt_decrypt_opt : "");
break;
case ENCRYPT_SERV_CUST:
g_printf("SERVER\n");
+ g_printf(" server-encrypt \"%s\"\n",
+ dp->srv_encrypt? dp->srv_encrypt : "");
+ g_printf(" server-decrypt-option \"%s\"\n",
+ dp->srv_decrypt_opt? dp->srv_decrypt_opt : "");
break;
}
- g_printf(" auth %s\n", dp->security_driver);
+ g_printf(" auth \"%s\"\n", dp->auth);
g_printf(" kencrypt %s\n", (dp->kencrypt? "YES" : "NO"));
- g_printf(" amandad_path %s\n", dp->amandad_path);
- g_printf(" client_username %s\n", dp->client_username);
- g_printf(" ssh_keys %s\n", dp->ssh_keys);
+ g_printf(" amandad-path \"%s\"\n", dp->amandad_path);
+ g_printf(" client-username \"%s\"\n", dp->client_username);
+ g_printf(" client-port \"%s\"\n", dp->client_port);
+ g_printf(" ssh-keys \"%s\"\n", dp->ssh_keys);
g_printf(" holdingdisk ");
switch(dp->to_holdingdisk) {
g_printf(" index %s\n", (dp->index? "YES" : "NO"));
g_printf(" starttime %04d\n", (int)dp->starttime);
if(dp->tape_splitsize > (off_t)0) {
- g_printf(" tape_splitsize %lld\n",
+ g_printf(" tape-splitsize %lld\n",
(long long)dp->tape_splitsize);
}
if(dp->split_diskbuffer) {
- g_printf(" split_diskbuffer %s\n", dp->split_diskbuffer);
+ g_printf(" split-diskbuffer %s\n", dp->split_diskbuffer);
}
if(dp->fallback_splitsize > (off_t)0) {
- g_printf(" fallback_splitsize %lldMb\n",
+ g_printf(" fallback-splitsize %lldMb\n",
(long long)(dp->fallback_splitsize / (off_t)1024));
}
g_printf(" skip-incr %s\n", (dp->skip_incr? "YES" : "NO"));
g_printf(" skip-full %s\n", (dp->skip_full? "YES" : "NO"));
+ g_printf(" allow-split %s\n", (dp->allow_split ? "YES" : "NO"));
+ if (dumptype_seen(dtype, DUMPTYPE_RECOVERY_LIMIT)) {
+ char **rl, **r1;
+ rl = val_t_display_strs(dumptype_getconf((dtype),
+ DUMPTYPE_RECOVERY_LIMIT), 1);
+ for(r1 = rl; *r1 != NULL; r1++) {
+ g_printf(" recovery-limit %s\n", *r1);
+ free(*r1);
+ }
+ }
+ if (dumptype_seen(dtype, DUMPTYPE_DUMP_LIMIT)) {
+ char **rl, **r1;
+ rl = val_t_display_strs(dumptype_getconf((dtype),
+ DUMPTYPE_DUMP_LIMIT), 1);
+ for(r1 = rl; *r1 != NULL; r1++) {
+ g_printf(" dump-limit %s\n", *r1);
+ free(*r1);
+ }
+ }
g_printf(" spindle %d\n", dp->spindle);
+ pp_scriptlist = dp->pp_scriptlist;
+ while (pp_scriptlist != NULL) {
+ g_printf(" script \"%s\"\n", (char *)pp_scriptlist->data);
+ pp_scriptlist = pp_scriptlist->next;
+ }
+
+ {
+ char **prop, **p1;;
+
+ prop = val_t_display_strs(dumptype_getconf((dtype), DUMPTYPE_PROPERTY),
+ 0);
+ for(p1 = prop; *p1 != NULL; p1++) {
+ g_printf(" property %s\n", *p1);
+ free(*p1);
+ }
+ amfree(prop);
+ }
g_printf("\n");
}
disklist_one(dp);
}
+/* ----------------------------------------------- */
+
+void
+hosts(
+ int argc G_GNUC_UNUSED,
+ char ** argv G_GNUC_UNUSED)
+{
+ disk_t *dp;
+ gint sentinel = 1;
+ GHashTable *seen = g_hash_table_new(g_str_hash, g_str_equal);
+
+ /* enumerate all hosts, skipping those that have been seen (since
+ * there may be more than one DLE on a host */
+ for(dp = diskq.head; dp != NULL; dp = dp->next) {
+ char *hostname = dp->host->hostname;
+ if (g_hash_table_lookup(seen, hostname))
+ continue;
+ g_printf("%s\n", hostname);
+ g_hash_table_insert(seen, hostname, &sentinel);
+ }
+ g_hash_table_destroy(seen);
+}
+
+/* ----------------------------------------------- */
+
+void
+dles(
+ int argc G_GNUC_UNUSED,
+ char ** argv G_GNUC_UNUSED)
+{
+ disk_t *dp;
+
+ for(dp = diskq.head; dp != NULL; dp = dp->next)
+ g_printf("%s %s\n", dp->host->hostname, dp->name);
+}
+
+/* ----------------------------------------------- */
+
void
show_version(
int argc,