/amanda/tags/amanda261p2/client-src/sendsize.c
C | 2487 lines | 2101 code | 239 blank | 147 comment | 522 complexity | a5d35b12252a8a89ca7fb58d8a2707a8 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1998 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. U.M. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors: the Amanda Development Team. Its members are listed in a
- * file named AUTHORS, in the root directory of this distribution.
- */
- /*
- * $Id: sendsize.c 10421 2008-03-06 18:48:30Z martineau $
- *
- * send estimated backup sizes using dump
- */
- #include "amanda.h"
- #include "pipespawn.h"
- #include "amfeatures.h"
- #include "amandates.h"
- #include "clock.h"
- #include "util.h"
- #include "getfsent.h"
- #include "version.h"
- #include "client_util.h"
- #include "conffile.h"
- #include "amandad.h"
- #ifdef SAMBA_CLIENT
- #include "findpass.h"
- #endif
- #define sendsize_debug(i, ...) do { \
- if ((i) <= debug_sebdsize) { \
- dbprintf(__VA_ARGS__); \
- } \
- } while (0)
- #ifdef HAVE_SETPGID
- # define SETPGRP setpgid(getpid(), getpid())
- # define SETPGRP_FAILED() do { \
- dbprintf(_("setpgid(%ld,%ld) failed: %s\n"), \
- (long)getpid(), (long)getpid(), strerror(errno)); \
- } while(0)
- #else /* () line 0 */
- #if defined(SETPGRP_VOID)
- # define SETPGRP setpgrp()
- # define SETPGRP_FAILED() do { \
- dbprintf(_("setpgrp() failed: %s\n"), strerror(errno)); \
- } while(0)
- #else
- # define SETPGRP setpgrp(0, getpid())
- # define SETPGRP_FAILED() do { \
- dbprintf(_("setpgrp(0,%ld) failed: %s\n"), \
- (long)getpid(), strerror(errno)); \
- } while(0)
- #endif
- #endif
- typedef struct level_estimates_s {
- time_t dumpsince;
- int estsize;
- int needestimate;
- } level_estimate_t;
- typedef struct disk_estimates_s {
- struct disk_estimates_s *next;
- char *qamname;
- char *qamdevice;
- char *dirname;
- char *qdirname;
- pid_t child;
- int done;
- dle_t *dle;
- level_estimate_t est[DUMP_LEVELS];
- } disk_estimates_t;
- disk_estimates_t *est_list;
- static am_feature_t *our_features = NULL;
- static char *our_feature_string = NULL;
- static g_option_t *g_options = NULL;
- static gboolean amandates_started = FALSE;
- /* local functions */
- int main(int argc, char **argv);
- void dle_add_diskest(dle_t *dle);
- void calc_estimates(disk_estimates_t *est);
- void free_estimates(disk_estimates_t *est);
- void dump_calc_estimates(disk_estimates_t *);
- void star_calc_estimates(disk_estimates_t *);
- void smbtar_calc_estimates(disk_estimates_t *);
- void gnutar_calc_estimates(disk_estimates_t *);
- void application_api_calc_estimate(disk_estimates_t *);
- void generic_calc_estimates(disk_estimates_t *);
- int
- main(
- int argc,
- char ** argv)
- {
- int level;
- char *dumpdate;
- disk_estimates_t *est;
- disk_estimates_t *est1;
- disk_estimates_t *est_prev;
- char *line = NULL;
- char *s, *fp;
- int ch;
- char *err_extra = NULL;
- int done;
- int need_wait;
- int dumpsrunning;
- char *qdisk = NULL;
- char *qlist = NULL;
- char *qamdevice = NULL;
- dle_t *dle;
- GSList *errlist;
- (void)argc; /* Quiet unused parameter warning */
- (void)argv; /* Quiet unused parameter warning */
- /* initialize */
- /*
- * Configure program for internationalization:
- * 1) Only set the message locale for now.
- * 2) Set textdomain for all amanda related programs to "amanda"
- * We don't want to be forced to support dozens of message catalogs.
- */
- setlocale(LC_MESSAGES, "C");
- textdomain("amanda");
- safe_fd(-1, 0);
- safe_cd();
- set_pname("sendsize");
- /* Don't die when child closes pipe */
- signal(SIGPIPE, SIG_IGN);
- erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
- dbopen(DBG_SUBDIR_CLIENT);
- startclock();
- dbprintf(_("version %s\n"), version());
- our_features = am_init_feature_set();
- our_feature_string = am_feature_to_string(our_features);
- config_init(CONFIG_INIT_CLIENT, NULL);
- /* (check for config errors comes later) */
- check_running_as(RUNNING_AS_CLIENT_LOGIN);
- /* handle all service requests */
- for(; (line = agets(stdin)) != NULL; free(line)) {
- if (line[0] == '\0')
- continue;
- if(strncmp_const(line, "OPTIONS ") == 0) {
- g_options = parse_g_options(line+8, 1);
- if(!g_options->hostname) {
- g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);
- gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);
- g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';
- }
- g_printf("OPTIONS ");
- if(am_has_feature(g_options->features, fe_rep_options_features)) {
- g_printf("features=%s;", our_feature_string);
- }
- if(am_has_feature(g_options->features, fe_rep_options_maxdumps)) {
- g_printf("maxdumps=%d;", g_options->maxdumps);
- }
- if(am_has_feature(g_options->features, fe_rep_options_hostname)) {
- g_printf("hostname=%s;", g_options->hostname);
- }
- g_printf("\n");
- fflush(stdout);
- if (g_options->config) {
- /* overlay this configuration on the existing (nameless) configuration */
- config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY,
- g_options->config);
- dbrename(get_config_name(), DBG_SUBDIR_CLIENT);
- }
- /* check for any config errors now */
- if (config_errors(&errlist) >= CFGERR_ERRORS) {
- char *errstr = config_errors_to_error_string(errlist);
- g_printf("%s\n", errstr);
- dbclose();
- return 1;
- }
- if (am_has_feature(g_options->features, fe_req_xml)) {
- break;
- }
- continue;
- }
- dle = alloc_dle();
- s = line;
- ch = *s++;
- skip_whitespace(s, ch); /* find the program name */
- if(ch == '\0') {
- err_extra = stralloc(_("no program name"));
- goto err; /* no program name */
- }
- dle->program = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- dle->program_is_application_api=0;
- if(strncmp_const(dle->program, "CALCSIZE") == 0) {
- skip_whitespace(s, ch); /* find the program name */
- if(ch == '\0') {
- err_extra = stralloc(_("no program name"));
- goto err;
- }
- dle->calcsize = 1;
- dle->program = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- if (strcmp(dle->program,"APPLICATION") == 0) {
- dle->program_is_application_api=1;
- skip_whitespace(s, ch); /* find dumper name */
- if (ch == '\0') {
- goto err; /* no program */
- }
- dle->program = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- }
- }
- else {
- dle->calcsize = 0;
- if (strcmp(dle->program,"APPLICATION") == 0) {
- dle->program_is_application_api=1;
- skip_whitespace(s, ch); /* find dumper name */
- if (ch == '\0') {
- goto err; /* no program */
- }
- dle->program = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- }
- }
- dle->program = stralloc(dle->program);
- skip_whitespace(s, ch); /* find the disk name */
- if(ch == '\0') {
- err_extra = stralloc(_("no disk name"));
- goto err; /* no disk name */
- }
- if (qdisk != NULL)
- amfree(qdisk);
- fp = s - 1;
- skip_quoted_string(s, ch);
- s[-1] = '\0'; /* terminate the disk name */
- qdisk = stralloc(fp);
- dle->disk = unquote_string(qdisk);
- skip_whitespace(s, ch); /* find the device or level */
- if (ch == '\0') {
- err_extra = stralloc(_("bad level"));
- goto err;
- }
- if(!isdigit((int)s[-1])) {
- fp = s - 1;
- skip_quoted_string(s, ch);
- s[-1] = '\0';
- qamdevice = stralloc(fp);
- dle->device = unquote_string(qamdevice);
- skip_whitespace(s, ch); /* find level number */
- }
- else {
- dle->device = stralloc(dle->disk);
- qamdevice = stralloc(qdisk);
- }
- /* find the level number */
- if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
- err_extra = stralloc(_("bad level"));
- goto err; /* bad level */
- }
- if (level < 0 || level >= DUMP_LEVELS) {
- err_extra = stralloc(_("bad level"));
- goto err;
- }
- skip_integer(s, ch);
- dle->level = g_slist_append(dle->level, GINT_TO_POINTER(level));
- skip_whitespace(s, ch); /* find the dump date */
- if(ch == '\0') {
- err_extra = stralloc(_("no dumpdate"));
- goto err; /* no dumpdate */
- }
- dumpdate = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- (void)dumpdate; /* XXX: Set but not used */
- dle->spindle = 0; /* default spindle */
- skip_whitespace(s, ch); /* find the spindle */
- if(ch != '\0') {
- if(sscanf(s - 1, "%d", &dle->spindle) != 1) {
- err_extra = stralloc(_("bad spindle"));
- goto err; /* bad spindle */
- }
- skip_integer(s, ch);
- skip_whitespace(s, ch); /* find the parameters */
- if(ch != '\0') {
- if(strncmp_const(s-1, "OPTIONS |;") == 0) {
- parse_options(s + 8,
- dle,
- g_options->features,
- 0);
- }
- else {
- while (ch != '\0') {
- if(strncmp_const(s-1, "exclude-file=") == 0) {
- qlist = unquote_string(s+12);
- dle->exclude_file =
- append_sl(dle->exclude_file, qlist);
- amfree(qlist);
- } else if(strncmp_const(s-1, "exclude-list=") == 0) {
- qlist = unquote_string(s+12);
- dle->exclude_list =
- append_sl(dle->exclude_list, qlist);
- amfree(qlist);
- } else if(strncmp_const(s-1, "include-file=") == 0) {
- qlist = unquote_string(s+12);
- dle->include_file =
- append_sl(dle->include_file, qlist);
- amfree(qlist);
- } else if(strncmp_const(s-1, "include-list=") == 0) {
- qlist = unquote_string(s+12);
- dle->include_list =
- append_sl(dle->include_list, qlist);
- amfree(qlist);
- } else {
- err_extra = vstrallocf(_("Invalid parameter (%s)"), s-1);
- goto err; /* should have gotten to end */
- }
- skip_quoted_string(s, ch);
- skip_whitespace(s, ch); /* find the inclusion list */
- amfree(qlist);
- }
- }
- }
- }
- /*@ignore@*/
- dle_add_diskest(dle);
- /*@end@*/
- }
- if (g_options == NULL) {
- g_printf(_("ERROR [Missing OPTIONS line in sendsize input]\n"));
- error(_("Missing OPTIONS line in sendsize input\n"));
- /*NOTREACHED*/
- }
- amfree(line);
- if (am_has_feature(g_options->features, fe_req_xml)) {
- char *errmsg = NULL;
- dle_t *dles, *dle;
- dles = amxml_parse_node_FILE(stdin, &errmsg);
- if (errmsg) {
- err_extra = errmsg;
- goto err;
- }
- for (dle = dles; dle != NULL; dle = dle->next) {
- dle_add_diskest(dle);
- }
- }
- if (amandates_started) {
- finish_amandates();
- free_amandates();
- amandates_started = FALSE;
- }
- for(est = est_list; est != NULL; est = est->next) {
- run_client_scripts(EXECUTE_ON_PRE_HOST_ESTIMATE, g_options, est->dle,
- stdout);
- }
- dumpsrunning = 0;
- need_wait = 0;
- done = 0;
- while(! done) {
- done = 1;
- /*
- * See if we need to wait for a child before we can do anything
- * else in this pass.
- */
- if(need_wait) {
- pid_t child_pid;
- amwait_t child_status;
- need_wait = 0;
- dbprintf(_("waiting for any estimate child: %d running\n"),
- dumpsrunning);
- child_pid = wait(&child_status);
- if(child_pid == -1) {
- error(_("wait failed: %s"), strerror(errno));
- /*NOTREACHED*/
- }
- if (!WIFEXITED(child_status) || WEXITSTATUS(child_status) != 0) {
- char *child_name = vstrallocf(_("child %ld"), (long)child_pid);
- char *child_status_str = str_exit_status(child_name, child_status);
- dbprintf("%s\n", child_status_str);
- amfree(child_status_str);
- amfree(child_name);
- }
- /*
- * Find the child and mark it done.
- */
- for(est = est_list; est != NULL; est = est->next) {
- if(est->child == child_pid) {
- break;
- }
- }
- if(est == NULL) {
- dbprintf(_("unexpected child %ld\n"), (long)child_pid);
- } else {
- est->done = 1;
- est->child = 0;
- dumpsrunning--;
- run_client_scripts(EXECUTE_ON_POST_DLE_ESTIMATE, g_options,
- est->dle, stdout);
- }
- }
- /*
- * If we are already running the maximum number of children
- * go back and wait until one of them finishes.
- */
- if(dumpsrunning >= g_options->maxdumps) {
- done = 0;
- need_wait = 1;
- continue; /* have to wait first */
- }
- /*
- * Find a new child to start.
- */
- for(est = est_list; est != NULL; est = est->next) {
- if(est->done == 0) {
- done = 0; /* more to do */
- }
- if(est->child != 0 || est->done) {
- continue; /* child is running or done */
- }
- /*
- * Make sure there is no spindle conflict.
- */
- if(est->dle->spindle != -1) {
- for(est1 = est_list; est1 != NULL; est1 = est1->next) {
- if(est1->child == 0 || est == est1 || est1->done) {
- /*
- * Ignore anything not yet started, ourself,
- * and anything completed.
- */
- continue;
- }
- if(est1->dle->spindle == est->dle->spindle) {
- break; /* oops -- they match */
- }
- }
- if(est1 != NULL) {
- continue; /* spindle conflict */
- }
- }
- break; /* start this estimate */
- }
- if(est == NULL) {
- if(dumpsrunning > 0) {
- need_wait = 1; /* nothing to do but wait */
- }
- } else {
- done = 0;
- run_client_scripts(EXECUTE_ON_PRE_DLE_ESTIMATE, g_options,
- est->dle, stdout);
- if((est->child = fork()) == 0) {
- calc_estimates(est); /* child does the estimate */
- exit(0);
- } else if(est->child == -1) {
- error(_("calc_estimates fork failed: %s"), strerror(errno));
- /*NOTREACHED*/
- }
- dumpsrunning++; /* parent */
- }
- }
- for(est = est_list; est != NULL; est = est->next) {
- run_client_scripts(EXECUTE_ON_POST_HOST_ESTIMATE, g_options, est->dle,
- stdout);
- }
- est_prev = NULL;
- for(est = est_list; est != NULL; est = est->next) {
- free_estimates(est);
- amfree(est_prev);
- est_prev = est;
- }
- amfree(est_prev);
- amfree(our_feature_string);
- am_release_feature_set(our_features);
- our_features = NULL;
- free_g_options(g_options);
- dbclose();
- return 0;
- err:
- if (err_extra) {
- g_printf(_("ERROR FORMAT ERROR IN REQUEST PACKET '%s'\n"), err_extra);
- dbprintf(_("REQ packet is bogus: %s\n"), err_extra);
- amfree(err_extra);
- } else {
- g_printf(_("ERROR FORMAT ERROR IN REQUEST PACKET\n"));
- dbprintf(_("REQ packet is bogus\n"));
- }
- free_g_options(g_options);
- dbclose();
- return 1;
- }
- void
- dle_add_diskest(
- dle_t *dle)
- {
- disk_estimates_t *newp, *curp;
- amandates_t *amdp;
- int dumplev, estlev;
- time_t dumpdate;
- GSList *level;
- char *amandates_file;
- gboolean need_amandates = FALSE;
- level = dle->level;
- if (level == NULL) {
- g_printf(_("ERROR Missing level in request\n"));
- return;
- }
- /* should we use amandates for this? */
- if (dle->calcsize)
- need_amandates = TRUE;
- if (strcmp(dle->program, "GNUTAR") == 0) {
- /* GNUTAR only needs amandates if gnutar_list_dir is NULL */
- char *gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR);
- if (!gnutar_list_dir || !*gnutar_list_dir)
- need_amandates = TRUE;
- }
- /* start amandates here, before adding this DLE to est_list, in case
- * we encounter an error. */
- if (need_amandates) {
- if (!amandates_started) {
- amandates_file = getconf_str(CNF_AMANDATES);
- if(!start_amandates(amandates_file, 0)) {
- char *errstr = strerror(errno);
- char *qamname = quote_string(dle->disk);
- char *errmsg = vstrallocf(_("could not open %s: %s"), amandates_file, errstr);
- char *qerrmsg = quote_string(errmsg);
- g_printf(_("%s %d ERROR %s\n"), qamname, 0, qerrmsg);
- amfree(qamname);
- amfree(errmsg);
- amfree(qerrmsg);
- return;
- }
- amandates_started = TRUE;
- }
- }
- while (level != NULL) {
- if (GPOINTER_TO_INT(level->data) < 0)
- level->data = GINT_TO_POINTER(0);
- if (GPOINTER_TO_INT(level->data) >= DUMP_LEVELS)
- level->data = GINT_TO_POINTER(DUMP_LEVELS - 1);
- level = g_slist_next(level);
- }
- for(curp = est_list; curp != NULL; curp = curp->next) {
- if(strcmp(curp->dle->disk, dle->disk) == 0) {
- /* already have disk info, just note the level request */
- level = dle->level;
- while (level != NULL) {
- curp->est[GPOINTER_TO_INT(level->data)].needestimate = 1;
- level = g_slist_next(level);
- }
- return;
- }
- }
- newp = (disk_estimates_t *) alloc(SIZEOF(disk_estimates_t));
- memset(newp, 0, SIZEOF(*newp));
- newp->next = est_list;
- est_list = newp;
- newp->qamname = quote_string(dle->disk);
- if (dle->device) {
- newp->qamdevice = quote_string(dle->device);
- newp->dirname = amname_to_dirname(dle->device);
- newp->qdirname = quote_string(newp->dirname);
- } else {
- newp->qamdevice = stralloc("");
- newp->dirname = stralloc("");
- newp->qdirname = stralloc("");
- }
- level = dle->level;
- while (level != NULL) {
- newp->est[GPOINTER_TO_INT(level->data)].needestimate = 1;
- level = g_slist_next(level);
- }
- newp->dle = dle;
- /* fill in dump-since dates */
- if (need_amandates) {
- amdp = amandates_lookup(newp->dle->disk);
- newp->est[0].dumpsince = EPOCH;
- for(dumplev = 0; dumplev < DUMP_LEVELS; dumplev++) {
- dumpdate = amdp->dates[dumplev];
- for(estlev = dumplev+1; estlev < DUMP_LEVELS; estlev++) {
- if(dumpdate > newp->est[estlev].dumpsince)
- newp->est[estlev].dumpsince = dumpdate;
- }
- }
- } else {
- /* just zero everything out */
- for(dumplev = 0; dumplev < DUMP_LEVELS; dumplev++) {
- newp->est[dumplev].dumpsince = 0;
- }
- }
- }
- void
- free_estimates(
- disk_estimates_t * est)
- {
- amfree(est->qamname);
- amfree(est->qamdevice);
- amfree(est->dirname);
- amfree(est->qdirname);
- if(est->dle) {
- /* free DLE */
- }
- }
- /*
- * ------------------------------------------------------------------------
- *
- */
- void
- calc_estimates(
- disk_estimates_t * est)
- {
- dbprintf(_("calculating for amname %s, dirname %s, spindle %d %s\n"),
- est->qamname, est->qdirname, est->dle->spindle, est->dle->program);
- if(est->dle->program_is_application_api == 1)
- application_api_calc_estimate(est);
- else
- if(est->dle->calcsize == 1)
- if (est->dle->device[0] == '/' && est->dle->device[1] == '/')
- dbprintf(_("Can't use CALCSIZE for samba estimate: %s %s\n"),
- est->qamname, est->qdirname);
- else
- generic_calc_estimates(est);
- else
- #ifndef USE_GENERIC_CALCSIZE
- if(strcmp(est->dle->program, "DUMP") == 0)
- dump_calc_estimates(est);
- else
- #endif
- #ifdef SAMBA_CLIENT
- if (strcmp(est->dle->program, "GNUTAR") == 0 &&
- est->dle->device[0] == '/' && est->dle->device[1] == '/')
- smbtar_calc_estimates(est);
- else
- #endif
- #ifdef GNUTAR
- if (strcmp(est->dle->program, "GNUTAR") == 0)
- gnutar_calc_estimates(est);
- else
- #endif
- dbprintf(_("Invalid program: %s %s %s\n"),
- est->qamname, est->qdirname, est->dle->program);
- dbprintf(_("done with amname %s dirname %s spindle %d\n"),
- est->qamname, est->qdirname, est->dle->spindle);
- }
- /*
- * ------------------------------------------------------------------------
- *
- */
- /* local functions */
- off_t getsize_dump(dle_t *dle, int level, char **errmsg);
- off_t getsize_smbtar(dle_t *dle, int level, char **errmsg);
- off_t getsize_gnutar(dle_t *dle, int level, time_t dumpsince, char **errmsg);
- off_t getsize_star(dle_t *dle, int level, time_t dumpsince, char **errmsg);
- off_t getsize_application_api(disk_estimates_t *est, int nb_level,
- int *levels, backup_support_option_t *bsu);
- off_t handle_dumpline(char *str);
- double first_num(char *str);
- void
- application_api_calc_estimate(
- disk_estimates_t * est)
- {
- int level;
- int i;
- int levels[DUMP_LEVELS];
- int nb_level = 0;
- backup_support_option_t *bsu;
- GPtrArray *errarray;
- bsu = backup_support_option(est->dle->program, g_options, est->dle->disk,
- est->dle->device, &errarray);
- if (!bsu) {
- guint i;
- for (i=0; i < errarray->len; i++) {
- char *line;
- char *errmsg;
- char *qerrmsg;
- line = g_ptr_array_index(errarray, i);
- if(am_has_feature(g_options->features,
- fe_rep_sendsize_quoted_error)) {
- errmsg = g_strdup_printf(_("Application '%s': %s"),
- est->dle->program, line);
- qerrmsg = quote_string(errmsg);
- for (level = 0; level < DUMP_LEVELS; level++) {
- if (est->est[level].needestimate) {
- g_printf(_("%s %d ERROR %s\n"),
- est->dle->disk, level, qerrmsg);
- dbprintf(_("%s %d ERROR A %s\n"),
- est->qamname, level, qerrmsg);
- }
- }
- amfree(errmsg);
- amfree(qerrmsg);
- }
- }
- if (i == 0) { /* nothing in errarray */
- char *errmsg;
- char *qerrmsg;
- errmsg = g_strdup_printf(
- _("Application '%s': cannon execute support command"),
- est->dle->program);
- qerrmsg = quote_string(errmsg);
- for (level = 0; level < DUMP_LEVELS; level++) {
- if (est->est[level].needestimate) {
- g_printf(_("%s %d ERROR %s\n"),
- est->dle->disk, level, qerrmsg);
- dbprintf(_("%s %d ERROR %s\n"),
- est->qamname, level, qerrmsg);
- }
- }
- amfree(errmsg);
- amfree(qerrmsg);
- }
- for (level = 0; level < DUMP_LEVELS; level++) {
- est->est[level].needestimate = 0;
- }
- g_ptr_array_free(errarray, TRUE);
- }
- for(level = 0; level < DUMP_LEVELS; level++) {
- if (est->est[level].needestimate) {
- if (level > bsu->max_level) {
- /* planner will not even consider this level */
- g_printf("%s %d SIZE %lld\n", est->qamname, level,
- (long long)-2);
- est->est[level].needestimate = 0;
- } else if (est->dle->estimate == ES_SERVER) {
- /* planner will consider this level, */
- /* but use a server-side estimate */
- g_printf("%s %d SIZE %lld\n", est->qamname, level,
- (long long)-1);
- est->est[level].needestimate = 0;
- } else {
- levels[nb_level++] = level;
- }
- }
- }
- if (nb_level == 0)
- return;
- if (bsu->multi_estimate) {
- for (i=0;i<nb_level;i++) {
- dbprintf(_("getting size via application API for %s %s level %d\n"),
- est->qamname, est->qamdevice, levels[i]);
- }
- getsize_application_api(est, nb_level, levels, bsu);
- } else {
- for(level = 0; level < DUMP_LEVELS; level++) {
- if (est->est[level].needestimate) {
- dbprintf(
- _("getting size via application API for %s %s level %d\n"),
- est->qamname, est->qamdevice, level);
- levels[0] = level;
- getsize_application_api(est, 1, levels, bsu);
- }
- }
- }
- }
- void
- generic_calc_estimates(
- disk_estimates_t * est)
- {
- int pipefd = -1, nullfd = -1;
- char *cmd;
- char *cmdline;
- char *my_argv[DUMP_LEVELS*2+22];
- char number[NUM_STR_SIZE];
- int i, level, my_argc;
- pid_t calcpid;
- int nb_exclude = 0;
- int nb_include = 0;
- char *file_exclude = NULL;
- char *file_include = NULL;
- times_t start_time;
- FILE *dumpout = NULL;
- off_t size = (off_t)1;
- char *line = NULL;
- char *match_expr;
- amwait_t wait_status;
- char *errmsg = NULL, *qerrmsg;
- char tmppath[PATH_MAX];
- int len;
- cmd = vstralloc(amlibexecdir, "/", "calcsize", versionsuffix(), NULL);
- my_argc = 0;
- my_argv[my_argc++] = stralloc("calcsize");
- if (g_options->config)
- my_argv[my_argc++] = stralloc(g_options->config);
- else
- my_argv[my_argc++] = stralloc("NOCONFIG");
- my_argv[my_argc++] = stralloc(est->dle->program);
- canonicalize_pathname(est->dle->disk, tmppath);
- my_argv[my_argc++] = stralloc(tmppath);
- canonicalize_pathname(est->dirname, tmppath);
- my_argv[my_argc++] = stralloc(tmppath);
- if (est->dle->exclude_file)
- nb_exclude += est->dle->exclude_file->nb_element;
- if (est->dle->exclude_list)
- nb_exclude += est->dle->exclude_list->nb_element;
- if (est->dle->include_file)
- nb_include += est->dle->include_file->nb_element;
- if (est->dle->include_list)
- nb_include += est->dle->include_list->nb_element;
- if (nb_exclude > 0)
- file_exclude = build_exclude(est->dle, 0);
- if (nb_include > 0)
- file_include = build_include(est->dle, 0);
- if(file_exclude) {
- my_argv[my_argc++] = stralloc("-X");
- my_argv[my_argc++] = file_exclude;
- }
- if(file_include) {
- my_argv[my_argc++] = stralloc("-I");
- my_argv[my_argc++] = file_include;
- }
- start_time = curclock();
- cmdline = stralloc(my_argv[0]);
- for(i = 1; i < my_argc; i++)
- cmdline = vstrextend(&cmdline, " ", my_argv[i], NULL);
- dbprintf(_("running: \"%s\"\n"), cmdline);
- amfree(cmdline);
- for(level = 0; level < DUMP_LEVELS; level++) {
- if(est->est[level].needestimate) {
- g_snprintf(number, SIZEOF(number), "%d", level);
- my_argv[my_argc++] = stralloc(number);
- dbprintf(" %s", number);
- g_snprintf(number, SIZEOF(number),
- "%ld", (long)est->est[level].dumpsince);
- my_argv[my_argc++] = stralloc(number);
- dbprintf(" %s", number);
- }
- }
- my_argv[my_argc] = NULL;
- dbprintf("\n");
- fflush(stderr); fflush(stdout);
- if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
- errmsg = vstrallocf(_("Cannot access /dev/null : %s"),
- strerror(errno));
- dbprintf("%s\n", errmsg);
- goto common_exit;
- }
- calcpid = pipespawnv(cmd, STDERR_PIPE, 0,
- &nullfd, &nullfd, &pipefd, my_argv);
- amfree(cmd);
- dumpout = fdopen(pipefd,"r");
- if (!dumpout) {
- error(_("Can't fdopen: %s"), strerror(errno));
- /*NOTREACHED*/
- }
- match_expr = vstralloc(" %d SIZE %lld", NULL);
- len = strlen(est->qamname);
- for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
- long long size_ = (long long)0;
- if (line[0] == '\0' || (int)strlen(line) <= len)
- continue;
- /* Don't use sscanf for est->qamname because it can have a '%'. */
- if (strncmp(line, est->qamname, len) == 0 &&
- sscanf(line+len, match_expr, &level, &size_) == 2) {
- g_printf("%s\n", line); /* write to amandad */
- dbprintf(_("estimate size for %s level %d: %lld KB\n"),
- est->qamname,
- level,
- size_);
- }
- size = (off_t)size_;
- }
- amfree(match_expr);
- dbprintf(_("waiting for %s %s child (pid=%d)\n"),
- my_argv[0], est->qamdevice, (int)calcpid);
- waitpid(calcpid, &wait_status, 0);
- if (WIFSIGNALED(wait_status)) {
- errmsg = vstrallocf(_("%s terminated with signal %d: see %s"),
- "calcsize", WTERMSIG(wait_status),
- dbfn());
- } else if (WIFEXITED(wait_status)) {
- if (WEXITSTATUS(wait_status) != 0) {
- errmsg = vstrallocf(_("%s exited with status %d: see %s"),
- "calcsize", WEXITSTATUS(wait_status),
- dbfn());
- } else {
- /* Normal exit */
- }
- } else {
- errmsg = vstrallocf(_("%s got bad exit: see %s"),
- "calcsize", dbfn());
- }
- dbprintf(_("after %s %s wait: child pid=%d status=%d\n"),
- my_argv[0], est->qamdevice,
- (int)calcpid, WEXITSTATUS(wait_status));
- dbprintf(_(".....\n"));
- dbprintf(_("estimate time for %s: %s\n"),
- est->qamname,
- walltime_str(timessub(curclock(), start_time)));
- common_exit:
- if (errmsg && errmsg[0] != '\0') {
- if(am_has_feature(g_options->features, fe_rep_sendsize_quoted_error)) {
- qerrmsg = quote_string(errmsg);
- dbprintf(_("errmsg is %s\n"), errmsg);
- g_printf("%s %d ERROR %s\n",
- est->qamname, 0, qerrmsg);
- amfree(qerrmsg);
- }
- }
- amfree(errmsg);
- for(i = 0; i < my_argc; i++) {
- amfree(my_argv[i]);
- }
- amfree(cmd);
- }
- void
- dump_calc_estimates(
- disk_estimates_t * est)
- {
- int level;
- off_t size;
- char *errmsg=NULL, *qerrmsg;
- for(level = 0; level < DUMP_LEVELS; level++) {
- if(est->est[level].needestimate) {
- dbprintf(_("getting size via dump for %s level %d\n"),
- est->qamname, level);
- size = getsize_dump(est->dle, level, &errmsg);
- amflock(1, "size");
- g_printf(_("%s %d SIZE %lld\n"),
- est->qamname, level, (long long)size);
- if (errmsg && errmsg[0] != '\0') {
- if(am_has_feature(g_options->features,
- fe_rep_sendsize_quoted_error)) {
- qerrmsg = quote_string(errmsg);
- dbprintf(_("errmsg is %s\n"), errmsg);
- g_printf("%s %d ERROR %s\n",
- est->qamname, level, qerrmsg);
- amfree(qerrmsg);
- }
- }
- amfree(errmsg);
- fflush(stdout);
- amfunlock(1, "size");
- }
- }
- }
- #ifdef SAMBA_CLIENT
- void
- smbtar_calc_estimates(
- disk_estimates_t * est)
- {
- int level;
- off_t size;
- char *errmsg = NULL, *qerrmsg;
- for(level = 0; level < DUMP_LEVELS; level++) {
- if(est->est[level].needestimate) {
- dbprintf(_("getting size via smbclient for %s level %d\n"),
- est->qamname, level);
- size = getsize_smbtar(est->dle, level, &errmsg);
- amflock(1, "size");
- g_printf(_("%s %d SIZE %lld\n"),
- est->qamname, level, (long long)size);
- if (errmsg && errmsg[0] != '\0') {
- if(am_has_feature(g_options->features,
- fe_rep_sendsize_quoted_error)) {
- qerrmsg = quote_string(errmsg);
- dbprintf(_("errmsg is %s\n"), errmsg);
- g_printf("%s %d ERROR %s\n",
- est->qamname, level, qerrmsg);
- amfree(qerrmsg);
- }
- }
- amfree(errmsg);
- fflush(stdout);
- amfunlock(1, "size");
- }
- }
- }
- #endif
- #ifdef GNUTAR
- void
- gnutar_calc_estimates(
- disk_estimates_t * est)
- {
- int level;
- off_t size;
- char *errmsg = NULL, *qerrmsg;
- for(level = 0; level < DUMP_LEVELS; level++) {
- if (est->est[level].needestimate) {
- dbprintf(_("getting size via gnutar for %s level %d\n"),
- est->qamname, level);
- size = getsize_gnutar(est->dle, level,
- est->est[level].dumpsince,
- &errmsg);
- amflock(1, "size");
- g_printf(_("%s %d SIZE %lld\n"),
- est->qamname, level, (long long)size);
- if (errmsg && errmsg[0] != '\0') {
- if(am_has_feature(g_options->features,
- fe_rep_sendsize_quoted_error)) {
- qerrmsg = quote_string(errmsg);
- dbprintf(_("errmsg is %s\n"), errmsg);
- g_printf(_("%s %d ERROR %s\n"),
- est->qamname, level, qerrmsg);
- amfree(qerrmsg);
- }
- }
- amfree(errmsg);
- fflush(stdout);
- amfunlock(1, "size");
- }
- }
- }
- #endif
- typedef struct regex_s {
- char *regex;
- int scale;
- } regex_scale_t;
- /*@ignore@*/
- regex_scale_t re_size[] = {
- #ifdef DUMP
- {" DUMP: estimated -*[0-9][0-9]* tape blocks", 1024},
- {" DUMP: [Ee]stimated [0-9][0-9]* blocks", 512},
- {" DUMP: [Ee]stimated [0-9][0-9]* bytes", 1}, /* Ultrix 4.4 */
- {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* NEC EWS-UX */
- {"dump: Estimate: [0-9][0-9]* tape blocks", 1024}, /* OSF/1 */
- {"backup: There are an estimated [0-9][0-9]* tape blocks.",1024}, /* AIX */
- {"backup: estimated [0-9][0-9]* 1k blocks", 1024}, /* AIX */
- {"backup: estimated [0-9][0-9]* tape blocks", 1024}, /* AIX */
- {"backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",1024}, /* AIX */
- {"backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",1024}, /* AIX */
- {"dump: Estimate: [0-9][0-9]* blocks being output to pipe",1024},
- /* DU 4.0 dump */
- {"dump: Dumping [0-9][0-9]* bytes, ", 1}, /* DU 4.0 vdump */
- {"DUMP: estimated [0-9][0-9]* KB output", 1024}, /* HPUX */
- {"DUMP: estimated [0-9][0-9]* KB\\.", 1024}, /* NetApp */
- {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */
- #ifdef HAVE_DUMP_ESTIMATE
- {"[0-9][0-9]* blocks, [0-9][0-9]*.[0-9][0-9]* volumes", 1024},
- /* DU 3.2g dump -E */
- {"^[0-9][0-9]* blocks$", 1024}, /* DU 4.0 dump -E */
- {"^[0-9][0-9]*$", 1}, /* Solaris ufsdump -S */
- #endif
- #endif
- #ifdef VDUMP
- {"vdump: Dumping [0-9][0-9]* bytes, ", 1}, /* OSF/1 vdump */
- #endif
-
- #ifdef VXDUMP
- {"vxdump: estimated [0-9][0-9]* blocks", 512}, /* HPUX's vxdump */
- {" VXDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */
- #endif
- #ifdef XFSDUMP
- {"xfsdump: estimated dump size: [0-9][0-9]* bytes", 1}, /* Irix 6.2 xfs */
- #endif
- #ifdef GNUTAR
- {"Total bytes written: [0-9][0-9]*", 1}, /* Gnutar client */
- #endif
- #ifdef SAMBA_CLIENT
- #if SAMBA_VERSION >= 2
- #define SAMBA_DEBUG_LEVEL "0"
- {"Total number of bytes: [0-9][0-9]*", 1}, /* Samba du */
- #else
- #define SAMBA_DEBUG_LEVEL "3"
- {"Total bytes listed: [0-9][0-9]*", 1}, /* Samba dir */
- #endif
- #endif
- { NULL, 0 }
- };
- /*@end@*/
- off_t
- getsize_dump(
- dle_t *dle,
- int level,
- char **errmsg)
- {
- int pipefd[2], nullfd, stdoutfd, killctl[2];
- pid_t dumppid;
- off_t size;
- FILE *dumpout;
- char *dumpkeys = NULL;
- char *device = NULL;
- char *fstype = NULL;
- char *cmd = NULL;
- char *name = NULL;
- char *line = NULL;
- char *rundump_cmd = NULL;
- char level_str[NUM_STR_SIZE];
- int s;
- times_t start_time;
- char *qdisk = quote_string(dle->disk);
- char *qdevice;
- char *config;
- amwait_t wait_status;
- #if defined(DUMP) || defined(VDUMP) || defined(VXDUMP) || defined(XFSDUMP)
- int is_rundump = 1;
- #endif
- if (level > 9)
- return -2; /* planner will not even consider this level */
- if (dle->estimate == ES_SERVER)
- return -1; /* planner will consider this level, */
- /* but use a server-side estimate */
- g_snprintf(level_str, SIZEOF(level_str), "%d", level);
- device = amname_to_devname(dle->device);
- qdevice = quote_string(device);
- fstype = amname_to_fstype(dle->device);
- dbprintf(_("calculating for device %s with %s\n"),
- qdevice, fstype);
- cmd = vstralloc(amlibexecdir, "/rundump", versionsuffix(), NULL);
- rundump_cmd = stralloc(cmd);
- if (g_options->config)
- config = g_options->config;
- else
- config = "NOCONFIG";
- if ((stdoutfd = nullfd = open("/dev/null", O_RDWR)) == -1) {
- *errmsg = vstrallocf(_("getsize_dump could not open /dev/null: %s"),
- strerror(errno));
- dbprintf("%s\n", *errmsg);
- amfree(cmd);
- amfree(rundump_cmd);
- amfree(fstype);
- amfree(device);
- amfree(qdevice);
- amfree(qdisk);
- return(-1);
- }
- pipefd[0] = pipefd[1] = killctl[0] = killctl[1] = -1;
- if (pipe(pipefd) < 0) {
- *errmsg = vstrallocf(_("getsize_dump could create data pipes: %s"),
- strerror(errno));
- dbprintf("%s\n", *errmsg);
- amfree(cmd);
- amfree(rundump_cmd);
- amfree(fstype);
- amfree(device);
- amfree(qdevice);
- amfree(qdisk);
- return(-1);
- }
- #ifdef XFSDUMP /* { */
- #ifdef DUMP /* { */
- if (strcmp(fstype, "xfs") == 0)
- #else /* } { */
- if (1)
- #endif /* } */
- {
- name = stralloc(" (xfsdump)");
- dbprintf(_("running \"%s%s -F -J -l %s - %s\"\n"),
- cmd, name, level_str, qdevice);
- }
- else
- #endif /* } */
- #ifdef VXDUMP /* { */
- #ifdef DUMP /* { */
- if (strcmp(fstype, "vxfs") == 0)
- #else /* } { */
- if (1)
- #endif /* } */
- {
- #ifdef USE_RUNDUMP
- name = stralloc(" (vxdump)");
- #else
- name = stralloc("");
- cmd = newstralloc(cmd, VXDUMP);
- config = skip_argument;
- is_rundump = 0;
- #endif
- dumpkeys = vstralloc(level_str, "s", "f", NULL);
- dbprintf(_("running \"%s%s %s 1048576 - %s\"\n"),
- cmd, name, dumpkeys, qdevice);
- }
- else
- #endif /* } */
- #ifdef VDUMP /* { */
- #ifdef DUMP /* { */
- if (strcmp(fstype, "advfs") == 0)
- #else /* } { */
- if (1)
- #endif /* } */
- {
- name = stralloc(" (vdump)");
- dumpkeys = vstralloc(level_str, "b", "f", NULL);
- dbprintf(_("running \"%s%s %s 60 - %s\"\n"),
- cmd, name, dumpkeys, qdevice);
- }
- else
- #endif /* } */
- #ifdef DUMP /* { */
- if (1) {
- # ifdef USE_RUNDUMP /* { */
- # ifdef AIX_BACKUP /* { */
- name = stralloc(" (backup)");
- # else /* } { */
- name = vstralloc(" (", DUMP, ")", NULL);
- # endif /* } */
- # else /* } { */
- name = stralloc("");
- cmd = newstralloc(cmd, DUMP);
- config = skip_argument;
- is_rundump = 0;
- # endif /* } */
- # ifdef AIX_BACKUP /* { */
- dumpkeys = vstralloc("-", level_str, "f", NULL);
- dbprintf(_("running \"%s%s %s - %s\"\n"),
- cmd, name, dumpkeys, qdevice);
- # else /* } { */
- # ifdef HAVE_DUMP_ESTIMATE
- # define PARAM_DUMP_ESTIMATE HAVE_DUMP_ESTIMATE
- # else
- # define PARAM_DUMP_ESTIMATE ""
- # endif
- # ifdef HAVE_HONOR_NODUMP
- # define PARAM_HONOR_NODUMP "h"
- # else
- # define PARAM_HONOR_NODUMP ""
- # endif
- dumpkeys = vstralloc(level_str,
- PARAM_DUMP_ESTIMATE,
- PARAM_HONOR_NODUMP,
- "s", "f", NULL);
- # ifdef HAVE_DUMP_ESTIMATE
- stdoutfd = pipefd[1];
- # endif
- # ifdef HAVE_HONOR_NODUMP /* { */
- dbprintf(_("running \"%s%s %s 0 1048576 - %s\"\n"),
- cmd, name, dumpkeys, qdevice);
- # else /* } { */
- dbprintf(_("running \"%s%s %s 1048576 - %s\"\n"),
- cmd, name, dumpkeys, qdevice);
- # endif /* } */
- # endif /* } */
- }
- else
- #endif /* } */
- {
- error(_("no dump program available"));
- /*NOTREACHED*/
- }
- if (pipe(killctl) < 0) {
- dbprintf(_("Could not create pipe: %s\n"), strerror(errno));
- /* Message will be printed later... */
- killctl[0] = killctl[1] = -1;
- }
- start_time = curclock();
- switch(dumppid = fork()) {
- case -1:
- *errmsg = vstrallocf(_("cannot fork for killpgrp: %s"),
- strerror(errno));
- dbprintf("%s\n", *errmsg);
- amfree(dumpkeys);
- amfree(cmd);
- amfree(rundump_cmd);
- amfree(device);
- amfree(qdevice);
- amfree(qdisk);
- amfree(name);
- amfree(fstype);
- return -1;
- default:
- break;
- case 0: /* child process */
- if(SETPGRP == -1)
- SETPGRP_FAILED();
- else if (killctl[0] == -1 || killctl[1] == -1)
- dbprintf(_("Trying without killpgrp\n"));
- else {
- switch(fork()) {
- case -1:
- dbprintf(_("fork failed, trying without killpgrp\n"));
- break;
- default:
- {
- char *config;
- char *killpgrp_cmd = vstralloc(amlibexecdir, "/killpgrp",
- versionsuffix(), NULL);
- dbprintf(_("running %s\n"), killpgrp_cmd);
- dup2(killctl[0], 0);
- dup2(nullfd, 1);
- dup2(nullfd, 2);
- close(pipefd[0]);
- close(pipefd[1]);
- close(killctl[1]);
- close(nullfd);
- if (g_options->config)
- config = g_options->config;
- else
- config = "NOCONFIG";
- safe_fd(-1, 0);
- execle(killpgrp_cmd, killpgrp_cmd, config, (char *)0,
- safe_env());
- dbprintf(_("cannot execute %s: %s\n"),
- killpgrp_cmd, strerror(errno));
- exit(-1);
- }
- case 0: /* child process */
- break;
- }
- }
- dup2(nullfd, 0);
- dup2(stdoutfd, 1);
- dup2(pipefd[1], 2);
- aclose(pipefd[0]);
- if (killctl[0] != -1)
- aclose(killctl[0]);
- if (killctl[1] != -1)
- aclose(killctl[1]);
- safe_fd(-1, 0);
- #ifdef XFSDUMP
- #ifdef DUMP
- if (strcmp(fstype, "xfs") == 0)
- #else
- if (1)
- #endif
- if (is_rundump)
- execle(cmd, "rundump", config, "xfsdump", "-F", "-J", "-l",
- level_str, "-", device, (char *)0, safe_env());
- else
- execle(cmd, "xfsdump", "-F", "-J", "-l",
- level_str, "-", device, (char *)0, safe_env());
- else
- #endif
- #ifdef VXDUMP
- #ifdef DUMP
- if (strcmp(fstype, "vxfs") == 0)
- #else
- if (1)
- #endif
- if (is_rundump)
- execle(cmd, "rundump", config, "vxdump", dumpkeys, "1048576",
- "-", device, (char *)0, safe_env());
- else
- execle(cmd, "vxdump", dumpkeys, "1048576", "-",
- device, (char *)0, safe_env());
- else
- #endif
- #ifdef VDUMP
- #ifdef DUMP
- if (strcmp(fstype, "advfs") == 0)
- #else
- if (1)
- #endif
- if (is_rundump)
- execle(cmd, "rundump", config, "vdump", dumpkeys, "60", "-",
- device, (char *)0, safe_env());
- else
- execle(cmd, "vdump", dumpkeys, "60", "-",
- device, (char *)0, safe_env());
- else
- #endif
- #ifdef DUMP
- # ifdef AIX_BACKUP
- if (is_rundump)
- execle(cmd, "rundump", config, "backup", dumpkeys, "-",
- device, (char *)0, safe_env());
- else
- execle(cmd, "backup", dumpkeys, "-",
- device, (char *)0, safe_env());
- # else
- if (is_rundump) {
- execle(cmd, "rundump", config, "dump", dumpkeys,
- #ifdef HAVE_HONOR_NODUMP
- "0",
- #endif
- "1048576", "-", device, (char *)0, safe_env());
- } else {
- execle(cmd, "dump", dumpkeys,
- #ifdef HAVE_HONOR_NODUMP
- "0",
- #endif
- "1048576", "-", device, (char *)0, safe_env());
- }
- # endif
- #endif
- {
- error(_("exec %s failed or no dump program available: %s"),
- cmd, strerror(errno));
- /*NOTREACHED*/
- }
- }
- amfree(dumpkeys);
- amfree(rundump_cmd);
- aclose(pipefd[1]);
- if (killctl[0] != -1)
- aclose(killctl[0]);
- dumpout = fdopen(pipefd[0],"r");
- if (!dumpout) {
- error(_("Can't fdopen: %s"), strerror(errno));
- /*NOTREACHED*/
- }
- for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
- if (line[0] == '\0')
- continue;
- dbprintf("%s\n", line);
- size = handle_dumpline(line);
- if(size > (off_t)-1) {
- amfree(line);
- while ((line = agets(dumpout)) != NULL) {
- if (line[0] != '\0')
- break;
- amfree(line);
- }
- if (line != NULL) {
- dbprintf("%s\n", line);
- }
- break;
- }
- }
- amfree(line);
- dbprintf(".....\n");
- dbprintf(_("estimate time for %s level %d: %s\n"),
- qdisk,
- level,
- walltime_str(timessub(curclock(), start_time)));
- if(size == (off_t)-1) {
- *errmsg = vstrallocf(_("no size line match in %s%s output"),
- cmd, name);
- dbprintf(_("%s for %s\n"),
- *errmsg, qdisk);
- dbprintf(".....\n");
- dbprintf(_("Run %s%s manually to check for errors\n"),
- cmd, name);
- } else if(size == (off_t)0 && level == 0) {
- dbprintf(_("possible %s%s problem -- is \"%s\" really empty?\n"),
- cmd, name, dle->disk);
- dbprintf(".....\n");
- } else {
- dbprintf(_("estimate size for %s level %d: %lld KB\n"),
- qdisk,
- level,
- (long long)size);
- }
- if (killctl[1] != -1) {
- dbprintf(_("asking killpgrp to terminate\n"));
- aclose(killctl[1]);
- for(s = 5; s > 0; --s) {
- sleep(1);
- if (waitpid(dumppid, NULL, WNOHANG) != -1)
- goto terminated;
- }
- }
-
- /*
- * First, try to kill the dump process nicely. If it ignores us
- * for several seconds, hit it harder.
- */
- dbprintf(_("sending SIGTERM to process group %ld\n"), (long)dumppid);
- if (kill(-dumppid, SIGTERM) == -1) {
- dbprintf(_("kill failed: %s\n"), strerror(errno));
- }
- /* Now check whether it dies */
- for(s = 5; s > 0; --s) {
- sleep(1);
- if (waitpid(dumppid, NULL, WNOHANG) != -1)
- goto terminated;
- }
- dbprintf(_("sending SIGKILL to process group %ld\n"), (long)dumppid);
- if (kill(-dumppid, SIGKILL) == -1) {
- dbprintf(_("kill failed: %s\n"), strerror(errno));
- }
- for(s = 5; s > 0; --s) {
- sleep(1);
- if (waitpid(dumppid, NULL, WNOHANG) != -1)
- goto terminated;
- }
- dbprintf(_("waiting for %s%s \"%s\" child\n"), cmd, name, qdisk);
- waitpid(dumppid, &wait_status, 0);
- if (WIFSIGNALED(wait_status)) {
- *errmsg = vstrallocf(_("%s terminated with signal %d: see %s"),
- cmd, WTERMSIG(wait_status), dbfn());
- } else if (WIFEXITED(wait_status)) {
- if (WEXITSTATUS(wait_status) != 0) {
- *errmsg = vstrallocf(_("%s exited with status %d: see %s"),
- cmd, WEXITSTATUS(wait_status), dbfn());
- } else {
- /* Normal exit */
- }
- } else {
- *errmsg = vstrallocf(_("%s got bad exit: see %s"),
- cmd, dbfn());
- }
- dbprintf(_("after %s%s %s wait\n"), cmd, name, qdisk);
- terminated:
- aclose(nullfd);
- afclose(dumpout);
- amfree(device);
- amfree(qdevice);
- amfree(qdisk);
- amfree(fstype);
- amfree(cmd);
- amfree(name);
- return size;
- }
- #ifdef SAMBA_CLIENT
- off_t
- getsize_smbtar(
- dle_t *dle,
- int level,
- char **errmsg)
- {
- int pipefd = -1, nullfd = -1, passwdfd = -1;
- pid_t dumppid;
- off_t size;
- FILE *dumpout;
- char *tarkeys, *sharename, *user_and_password = NULL, *domain = NULL;
- char *share = NULL, *subdir = NULL;
- size_t lpass;
- char *pwtext;
- size_t pwtext_len;
- char *line;
- char *pw_fd_env;
- times_t start_time;
- char *error_pn = NULL;
- char *qdisk = quote_string(dle->disk);
- amwait_t wait_status;
- error_pn = stralloc2(get_pname(), "-smbclient");
- if (level > 1)
- return -2; /* planner will not even consider this level */
- if (dle->estimate == ES_SERVER)
- return -1; /* planner will consider this level, */
- /* but use a server-side estimate */
- parsesharename(dle->device, &share, &subdir);
- if (!share) {
- amfree(share);
- amfree(subdir);
- set_pname(error_pn);
- amfree(error_pn);
- error(_("cannot parse disk entry %s for share/subdir"), qdisk);
- /*NOTREACHED*/
- }
- if ((subdir) && (SAMBA_VERSION < 2)) {
- amfree(share);
- amfree(subdir);
- set_pname(error_pn);
- amfree(error_pn);
- error(_("subdirectory specified for share %s but samba not v2 or better"), qdisk);
- /*NOTREACHED*/
- }
- if ((user_and_password = findpass(share, &domain)) == NULL) {
- if(domain) {
- memset(domain, '\0', strlen(domain));
- amfree(domain);
- }
- set_pname(error_pn);
- amfree(error_pn);
- error(_("cannot find password for %s"), dle->disk);
- /*NOTREACHED*/
- }
- lpass = strlen(user_and_password);
- if ((pwtext = strchr(user_and_password, '%')) == NULL) {
- memset(user_and_password, '\0', (size_t)lpass);
- amfree(user_and_password);
- if(domain) {
- memset(domain, '\0', strlen(domain));
- amfree(domain);
- }
- set_pname(error_pn);
- amfree(error_pn);
- error(_("password field not \'user%%pass\' for %s"), dle->disk);
- /*NOTREACHED*/
- }
- *pwtext++ = '\0';
- pwtext_len = strlen(pwtext);
- if ((sharename = makesharename(share, 0)) == NULL) {
- memset(user_and_password, '\0', (size_t)lpass);
- amfree(user_and_password);
- if(domain) {
- memset(domain, '\0', strlen(domain));
- amfree(domain);
- }
- set_pname(error_pn);
- amfree(error_pn);
- error(_("cannot make share name of %s"), share);
- /*NOTREACHED*/
- }
- if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
- memset(user_and_password, '\0', (size_t)lpass);
- amfree(user_and_password);
- if(domain) {
- memset(domain, '\0', strlen(domain));
- amfree(domain);
- }
- set_pname(error_pn);
- amfree(error_pn);
- amfree(sharename);
- error(_("could not open /dev/null: %s\n"),
- strerror(errno));
- /*NOTREACHED*/
- }
- #if SAMBA_VERSION >= 2
- if (level == 0)
- tarkeys = "archive 0;recurse;du";
- else
- tarkeys = "archive 1;recurse;du";
- #else
- if (level == 0)
- tarkeys = "archive 0;recurse;dir";
- else
- tarkeys = "archive 1;recurse;dir";
- #endif
- start_time = curclock();
- if (pwtext_len > 0) {
- pw_fd_env = "PASSWD_FD";
- } else {
- pw_fd_env = "dummy_PASSWD_FD";
- }
- dumppid = pipespawn(SAMBA_CLIENT, STDERR_PIPE|PASSWD_PIPE, 0,
- &nullfd, &nullfd, &pipefd,
- pw_fd_env, &passwdfd,
- "smbclient",
- sharename,
- "-d", SAMBA_DEBUG_LEVEL,
- *user_and_password ? "-U" : skip_argument,
- *user_and_password ? user_and_password : skip_argument,
- "-E",
- domain ? "-W" : skip_argument,
- domain ? domain : skip_argument,
- #if SAMBA_VERSION >= 2
- subdir ? "-D" : skip_argument,
- subdir ? subdir : skip_argument,
- #endif
- "-c", tarkeys,
- NULL);
- if(domain) {
- memset(domain, '\0', strlen(domain));
- amfree(domain);
- }
- aclose(nullfd);
- if(pwtext_len > 0 && full_write(passwdfd, pwtext, pwtext_len) < pwtext_len) {
- int save_errno = errno;
- memset(user_and_password, '\0', (size_t)lpass);
- amfree(user_and_password);
- aclose(passwdfd);
- set_pname(error_pn);
- amfree(error_pn);
- error(_("password write failed: %s"), strerror(save_errno));
- /*NOTREACHED*/
- }
- memset(user_and_password, '\0', (size_t)lpass);
- amfree(user_and_password);
- aclose(passwdfd);
- amfree(sharename);
- amfree(share);
- amfree(subdir);
- amfree(error_pn);
- dumpout = fdopen(pipefd,"r");
- if (!dumpout) {
- error(_("Can't fdopen: %s"), strerror(errno));
- /*NOTREACHED*/
- }
- for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
- if (line[0] == '\0')
- continue;
- dbprintf("%s\n", line);
- size = handle_dumpline(line);
- if(size > -1) {
- amfree(line);
- while ((line = agets(dumpout)) != NULL) {
- if (line[0] != '\0')
- break;
- amfree(line);
- }
- if(line != NULL) {
- dbprintf("%s\n", line);
- }
- break;
- }
- }
- amfree(line);
- dbprintf(".....\n");
- dbprintf(_("estimate time for %s level %d: %s\n"),
- qdisk,
- level,
- walltime_str(timessub(curclock(), start_time)));
- if(size == (off_t)-1) {
- *errmsg = vstrallocf(_("no size line match in %s output"),
- SAMBA_CLIENT);
- dbprintf(_("%s for %s\n"),
- *errmsg, qdisk);
- dbprintf(".....\n");
- } else if(size == (off_t)0 && level == 0) {
- dbprintf(_("possible %s problem -- is \"%s\" really empty?\n"),
- SAMBA_CLIENT, dle->disk);
- dbprintf(".....\n");
- }
- dbprintf(_("estimate size for %s level %d: %lld KB\n"),
- qdisk,
- level,
- (long long)size);
- kill(-dumppid, SIGTERM);
- dbprintf(_("waiting for %s \"%s\" child\n"), SAMBA_CLIENT, qdisk);
- waitpid(dumppid, &wait_status, 0);
- if (WIFSIGNALED(wait_status)) {
- *errmsg = vstrallocf(_("%s terminated with signal %d: see %s"),
- SAMBA_CLIENT, WTERMSIG(wait_status), dbfn());
- } else if (WIFEXITED(wait_status)) {
- if (WEXITSTATUS(wait_status) != 0) {
- *errmsg = vstrallocf(_("%s exited with status %d: see %s"),
- SAMBA_CLIENT, WEXITSTATUS(wait_status),
- dbfn());
- } else {
- /* Normal exit */
- }
- } else {
- *errmsg = vstrallocf(_("%s got bad exit: see %s"),
- SAMBA_CLIENT, dbfn());
- }
- dbprintf(_("after %s %s wait\n"), SAMBA_CLIENT, qdisk);
- afclose(dumpout);
- pipefd = -1;
- amfree(error_pn);
- amfree(qdisk);
- return size;
- }
- #endif
- #ifdef GNUTAR
- off_t
- getsize_gnutar(
- dle_t *dle,
- int level,
- time_t dumpsince,
- char **errmsg)
- {
- int pipefd = -…
Large files files are truncated, but you can click here to view the full file