X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famadmin.c;h=bd26906c1553ac5e6ce6131dae8d209206967b9b;hb=refs%2Ftags%2Fupstream%2F3.3.1;hp=9acacbc87238be1ea4347959a36025cb4b687be4;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/server-src/amadmin.c b/server-src/amadmin.c index 9acacbc..bd26906 100644 --- a/server-src/amadmin.c +++ b/server-src/amadmin.c @@ -41,11 +41,14 @@ #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); @@ -75,6 +78,8 @@ static int next_level0(disk_t *dp, info_t *info); 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); @@ -93,6 +98,8 @@ static const struct { T_("\t\t\t\t\t# Show version info.") }, { "config", show_config, T_("\t\t\t\t\t# Show configuration.") }, + { "estimate", estimate, + T_(" [ []* ]*\t# Print server estimate.") }, { "force", force, T_(" [ []* ]+\t\t# Force level 0 at next run.") }, { "unforce", unforce, @@ -105,6 +112,10 @@ static const struct { T_(" [ []* ]+\t# Clear bump command.") }, { "disklist", disklist, T_(" [ []* ]*\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_(" ...\t\t # re-use this tape.") }, { "no-reuse", noreuse, @@ -140,7 +151,7 @@ main( int i; char *conf_diskfile; char *conf_infofile; - config_overwrites_t *cfg_ovr = NULL; + config_overrides_t *cfg_ovr = NULL; /* * Configure program for internationalization: @@ -161,30 +172,34 @@ main( 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)) { @@ -231,8 +246,8 @@ usage(void) { int i; - g_fprintf(stderr, _("\nUsage: %s%s {} [-o configoption]* ...\n"), - get_pname(), versionsuffix()); + g_fprintf(stderr, _("\nUsage: %s [-o configoption]* {} ...\n"), + get_pname()); g_fprintf(stderr, _(" Valid s are:\n")); for (i = 0; i < NCMDS; i++) g_fprintf(stderr, "\t%s%s\n", cmdtab[i].name, _(cmdtab[i].usage)); @@ -329,6 +344,64 @@ diskloop( /* ----------------------------------------------- */ +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) @@ -1033,10 +1106,12 @@ find( 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 ] [hostname []]*\"\n"), + _("%s: expecting \"find [--sort ] [hostname []]*\"\n"), get_pname()); usage(); } @@ -1062,6 +1137,8 @@ find( case 'P': case 'b': case 'B': + case 'w': + case 'W': break; default: valid_sort=0; } @@ -1077,21 +1154,42 @@ find( 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); @@ -1228,14 +1326,16 @@ remove_holding_file_from_catalog( } 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 */ } @@ -1243,7 +1343,7 @@ remove_holding_file_from_catalog( 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; @@ -1317,10 +1417,12 @@ remove_holding_file_from_catalog( /* 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; } @@ -1402,8 +1504,9 @@ holding( } } amfree(dumpstr); + dumpfile_free_data(&file); } - g_slist_free_full(file_list); + slist_free_full(file_list, g_free); break; case HOLDING_DELETE: @@ -1421,7 +1524,7 @@ holding( error(_("Could not delete '%s'"), (char *)li->data); } } - g_slist_free_full(file_list); + slist_free_full(file_list, g_free); break; } } @@ -1503,7 +1606,7 @@ export_db( 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) { @@ -1533,13 +1636,16 @@ export_one( { 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); @@ -1571,6 +1677,8 @@ export_one( (intmax_t)info.history[l].date); } g_printf("//\n"); + amfree(qhost); + amfree(qdisk); } /* ----------------------------------------------- */ @@ -1615,7 +1723,10 @@ import_db( 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 */ @@ -1624,11 +1735,15 @@ import_db( } 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') { @@ -1717,9 +1832,9 @@ import_one(void) 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); @@ -1734,9 +1849,9 @@ import_one(void) 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); @@ -1978,27 +2093,33 @@ disklist_one( 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) { @@ -2006,16 +2127,16 @@ disklist_one( } 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); } @@ -2025,7 +2146,7 @@ disklist_one( 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 { @@ -2058,17 +2179,26 @@ disklist_one( } 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) { @@ -2081,12 +2211,22 @@ disklist_one( 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", @@ -2100,17 +2240,26 @@ disklist_one( 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) { @@ -2129,19 +2278,55 @@ disklist_one( 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"); } @@ -2160,6 +2345,44 @@ disklist( 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,