[prev in list] [next in list] [prev in thread] [next in thread] 

List:       amanda-users
Subject:    Re: Amanda on IBM-AIX 4.1.4
From:       Stefan Walder <sw () wtech ! ruhr-uni-bochum ! de>
Date:       1996-06-24 6:23:21
[Download RAW message or body]

On Fri, 21 Jun 1996, Cristina Maria Zanini #200503# wrote:

> Date: Fri, 21 Jun 1996 16:03:17 -0300 (EST)
> From: Cristina Maria Zanini #200503# <zanini@obelix.unicamp.br>
> To: amanda-users@cs.umd.edu
> Cc: amanda-hackers@cs.umd.edu
> Subject: Amanda on IBM-AIX 4.1.4
>
> Hello All.
>
>   I've compiled the Amanda package on a machine running IBM-AIX 4.1.4,
> but I'm not getting to run it. It always gives me the following messages:
>
>
> These dumps were to tape BCKDIA1_200696.
> Tonight's dumps should go onto tape BCKDIA1_290396 or a new tape.
>
> FAILURE AND STRANGE DUMP SUMMARY:
>   scon.cmp   lv00 lev 1 STRANGE
>

I'm using amanda and AIX 3.2.5 and AIX 4.1.4. My tape-host is a AIX 3.2.5
host and so I'm only using the client under AIX 4.1.4.

There I have changed some line's in this files:

	-> ./client-src/sendsize.c
	-> ./client-src/sendsize-dump.c
	-> ./client-src/sendbackup-dump.c

The output of the backup-program has changes from AIX 3.2 to 4.1 and so the
client can't estimate the size of the backup. I have attached the files to
this mail and hope it helps.

Stefan Walder


+----------------------------------------------------------------------+
|Dipl. Ing. Stefan Walder  (techn. Ang. in der EDV-Systemtechnik)      |
+----------------------------------------------------------------------+
|Universitaetsstrasse 150     E-Mail: Stefan.Walder@ruhr-uni-bochum.de |
|Werkstofftechnik IA 2/47     Tel.:   (0)49(0)234-700-5952             |
|D-44780 Bochum               Fax:    (0)49(0)234-7094-104             |
+----------------------------------------------------------------------+
 ! Neu: PGP-Key auf Anfrage !

["sendbackup-dump.c" (TEXT/PLAIN)]

/*
 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
 * Copyright (c) 1991,1994 University of Maryland
 * 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.
 *
 * Author: James da Silva, Systems Design and Analysis Group
 *			   Computer Science Department
 *			   University of Maryland at College Park
 */
/* 
 * sendbackup-dump.c - send backup data using BSD dump
 */
#define DEBUG_CODE

#include "sendbackup-common.h"

#ifdef KRB4_SECURITY
#include "sendbackup-krb4.c"
#else					/* I'd tell you what this does */
#define NAUGHTY_BITS			/* but then I'd have to kill you */
#endif


regex_t re_table[] = {
  /* the various encodings of dump size */
  { DMP_SIZE, 
	"DUMP: DUMP: [0-9][0-9]* tape blocks",				1024},
  { DMP_SIZE,
	"dump: Actual: [0-9][0-9]* tape blocks",
                                                                        1024},
  { DMP_SIZE,
        "backup: There are [0-9][0-9]* tape blocks on [0-9]* tapes",    1024},

  { DMP_SIZE,
        "backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",       1024},

  { DMP_SIZE,
        "backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",       1024},

  { DMP_SIZE,
	"DUMP: [0-9][0-9]* blocks ([0-9][0-9]*KB) on [0-9][0-9]* volume", 512},
  { DMP_SIZE,
"DUMP: [0-9][0-9]* blocks ([0-9][0-9]*\\.[0-9][0-9]*MB) on [0-9][0-9]* volume",
                                                                          512},
  { DMP_SIZE, "DUMP: [0-9][0-9]* blocks",                                 512},
  { DMP_SIZE, "DUMP: [0-9][0-9]* bytes were dumped",		            1},

  { DMP_SIZE, "vdump: Dumped  [0-9][0-9]* of [0-9][0-9]* bytes",	    1}, 
		/* OSF's vdump */

  /* strange dump lines */
  { DMP_STRANGE, "should not happen" },
  { DMP_STRANGE, "Cannot open" },
  { DMP_STRANGE, "[Ee]rror" },
  { DMP_STRANGE, "[Ff]ail" },
  /* XXX add more ERROR entries here by scanning dump sources? */

  /* any blank or non-strange DUMP: lines are marked as normal */
  { DMP_NORMAL, "^  DUMP:" },
  { DMP_NORMAL, "^dump:" },					/* OSF/1 */
  { DMP_NORMAL, "^vdump:" },					/* OSF/1 */

#ifdef OSF1_VDUMP	/* this is for OSF/1 3.2's vdump for advfs */
  { DMP_NORMAL, "^The -s option is ignored"},			/* OSF/1 */
  { DMP_NORMAL, "^path"},					/* OSF/1 */
  { DMP_NORMAL, "^dev/fset"},					/* OSF/1 */
  { DMP_NORMAL, "^type"},					/* OSF/1 */
  { DMP_NORMAL, "^advfs id"},					/* OSF/1 */
  { DMP_NORMAL, "^[A-Z][a-z][a-z] [A-Z][a-z][a-z] .[0-9] [0-9]"}, /* OSF/1 */
#endif

  { DMP_NORMAL, "^backup:" },					/* AIX */
  { DMP_NORMAL, "^        Use the umount command to unmount the filesystem" },

  { DMP_NORMAL, "^[ \t]*\\\n" },

  /* catch-all; DMP_STRANGE is returned for all other lines */
  { DMP_STRANGE, NULL, 0}
};

char *backup_program_name = "dump";	/* for printing */
char *restore_program_name = "restore";
char *amanda_backup_program = "DUMP";	/* for the header */

void start_backup(disk, level, datestamp, dataf, mesgf)
char *disk, *datestamp;
int level, dataf, mesgf;
{
    int dumpin, dumpout;
    char host[80], dumpkeys[80];
    char device[80], *domain;

    if(gethostname(host, sizeof host) == -1)
        error("error [gethostname: %s]", strerror(errno));
    if((domain = strchr(host, '.'))) *domain++ = '\0';

    fprintf(stderr, "%s: start [%s:%s level %d datestamp %s]\n",
	    pname, host, disk, level, datestamp);

    NAUGHTY_BITS;

    write_tapeheader(host, disk, level, compress, datestamp, dataf);

    if(compress)
	comppid = pipespawn(COMPRESS_PATH, &dumpout, dataf, mesgf,
			    COMPRESS_PATH, 
			    compress == COMPR_BEST? 
			        COMPRESS_BEST_OPT : COMPRESS_FAST_OPT,
			    (char *)0);
    else {
	dumpout = dataf;
	comppid = -1;
    }

    /* invoke dump */

    if(disk[0] == '/')
	strcpy(device, disk);
    else
	sprintf(device, "%s%s", DEV_PREFIX, disk);

#ifndef AIX_BACKUP
    /* normal dump */
    sprintf(dumpkeys, "%d%ssf", level, no_record ? "" : "u");

    dumppid = pipespawn(DUMP, &dumpin, dumpout, mesgf, 
			"dump", dumpkeys, "100000", "-", device, (char *)0);
#else
    /* AIX backup program */

    sprintf(dumpkeys, "-%d%sf", level, no_record ? "" : "u");
    dumppid = pipespawn(DUMP, &dumpin, dumpout, mesgf, 
			"backup", dumpkeys, "-", device, (char *)0);
#endif

    /* close the write ends of the pipes */

    close(dumpin);
    close(dumpout);
    close(dataf);
    close(mesgf);
}

void end_backup(status)
int status;
{
    /* don't need to do anything for dump */
}

["sendsize-dump.c" (TEXT/PLAIN)]

/*
 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
 * Copyright (c) 1991,1993 University of Maryland
 * 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.
 *
 * Author: James da Silva, Systems Design and Analysis Group
 *			   Computer Science Department
 *			   University of Maryland at College Park
 */
/* 
 * sendsize-dump.c - send estimated backup sizes using dump
 */
#define DEBUG_CODE

#include "amanda.h"
#include "statfs.h"

#ifdef SYSV_SETPGRP
#  define SETPGRP	setpgrp()
#else
#  define SETPGRP	setpgrp(0,getpid())
#endif

#define MAXLINE 4096

typedef struct regex_s {
    char *regex;
    int scale;
} regex_t;

regex_t re_size[] = {
    {"  DUMP: estimated [0-9][0-9]* tape blocks", 1024},
    {"  DUMP: [Ee]stimated [0-9][0-9]* blocks", 512},
    {"vdump: Dumping [0-9][0-9]* bytes, ", 1},		      /* OSF/1 vdump */
    {"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: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",1024},
    {"backup: estimated [0-9][0-9]* 1k blocks.",1024},
    {"backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",1024},

    { NULL, 0 }
};


char line[MAXLINE];
char *pname = "sendsize-dump";

/* local functions */
void main P((int argc, char **argv));
long getsize P((char *disk, int level));
long handle_dumpline P((char *str));
double first_num P((char *str));
long fast_size P((char *str));


void main(argc, argv)
int argc;
char **argv;
{
    int level;
    long size;
    char disk[256];

    /* initialize */

    chdir("/tmp");
    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
    umask(0);
    dbopen("/tmp/sendsize.debug");

    /* handle all service requests */

    while(fgets(line, MAXLINE, stdin)) {
	if(!strncmp(line, "OPTIONS", 7)) {
	    /* we don't recognize any options yet */
	    printf("OPTIONS ;\n");
	    continue;
	}

	if(sscanf(line, "%s %d\n", disk, &level) != 2) goto err;

	size = getsize(disk, level);
	/* XXX handle errors differently */
	printf("%s %d SIZE %ld\n", disk, level, size);
    }

    dbclose();
    exit(0);
 err:
    printf("FORMAT ERROR IN REQUEST PACKET\n");
    dbprintf(("REQ packet is bogus\n"));
    dbclose();
    exit(1);
}

long getsize(disk, level)
char *disk;
int level;
{
    int pipefd[2], nullfd, dumppid;
    long size;
    FILE *dumpout;
    char dumpkeys[10], device[256];

    if(disk[0] == '/') strcpy(device, disk);
    else sprintf(device, "%s%s", DEV_PREFIX, disk);

#ifdef FAST_SIZE_CHECK
    if(level == 0)				/* shortcut for level 0s */
	if((size = fast_size(device)) != -1)
	    return size;
#endif

    nullfd = open("/dev/null", O_RDWR);
    pipe(pipefd);
    sprintf(dumpkeys, "%dsf", level);

    dbprintf(("sendsize: running \"%s %s 100000 - %s\"\n",
	      DUMP, dumpkeys, device));

    switch(dumppid = fork()) {
    case -1: return -1;
    default: break; 
    case 0:	/* child process */
	if(SETPGRP == -1)
	    dbprintf(("setpgrp(0,%d) failed: %s\n",getpid(),strerror(errno)));

	dup2(nullfd, 0);
	dup2(nullfd, 1);
	dup2(pipefd[1], 2);
	close(pipefd[0]);

#ifndef AIX_BACKUP
	sprintf(dumpkeys, "%dsf", level);
	execl(DUMP, "dump", dumpkeys, "100000", "-", device, 0);
#else
	sprintf(dumpkeys, "-%df", level);
	execl(DUMP, "backup", dumpkeys, "-", device, 0);
#endif
	exit(1);
    }
    close(pipefd[1]);
    dumpout = fdopen(pipefd[0],"r");

    size = -1;
    while(fgets(line,MAXLINE,dumpout) != NULL) {
	dbprintf(("%s",line));
	size = handle_dumpline(line);
	if(size > -1) {
	    if(fgets(line, MAXLINE, dumpout) != NULL)
		dbprintf(("%s",line));
	    break;
	}
    }

    dbprintf((".....\n"));
    if(size == -1)
	dbprintf(("(no size line match in above dump output)\n.....\n"));

#ifdef OSF1_HANG_BUG
    sleep(5);
#endif

    kill(-dumppid, SIGTERM);

    close(nullfd);
    fclose(dumpout);

    return size;
}


double first_num(str)
char *str;
/*
 * Returns the value of the first integer in a string.
 */
{
    char tmp[16], *tp;

    tp = tmp;
    while(*str && !isdigit(*str)) str++;
    while(*str && isdigit(*str)) *tp++ = *str++;
    *tp = '\0';

    return atof(tmp);
}


long handle_dumpline(str)
char *str;
/*
 * Checks the dump output line against the error and size regex tables.
 */
{
    regex_t *rp;
    
    /* check for size match */
    for(rp = re_size; rp->regex != NULL; rp++) {
	if(match(rp->regex, str))
	    return (long) ((first_num(str)*rp->scale+1023.0)/1024.0);
    }
    return -1;
}

["sendsize.c" (TEXT/PLAIN)]

/*
 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
 * Copyright (c) 1991, 1996 University of Maryland
 * 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.
 *
 * Author: James da Silva, Systems Design and Analysis Group
 *			   Computer Science Department
 *			   University of Maryland at College Park
 */
/* 
 * sendsize.c - send estimated backup sizes using dump
 */
#define DEBUG_CODE

#include "amanda.h"
#include "amandates.h"
#include "getfsent.h"
#include "version.h"

#ifdef SYSV_SETPGRP
#  define SETPGRP	setpgrp()
#else
#  define SETPGRP	setpgrp(0,getpid())
#endif

#define MAXLINE 4096
char line[MAXLINE];
char *pname = "sendsize";

typedef struct level_estimates_s {
    int dumpsince;
    int estsize;
    int needestimate;
} level_estimate_t;

typedef struct disk_estimates_s {
    struct disk_estimates_s *next;
    char *amname;
    char *dirname;
    char *program;
    int platter;
    level_estimate_t est[DUMP_LEVELS];
} disk_estimates_t;

disk_estimates_t *est_list;

int maxdumps = 2;

/* local functions */
void main P((int argc, char **argv));
void add_diskest P((char *disk, int level, int platter, char *prog));
void calc_estimates P((disk_estimates_t *est));


void main(argc, argv)
int argc;
char **argv;
{
    int level, new_maxdumps, platter;
    char disk[256], prog[256], opt[256], *str;
    disk_estimates_t *est;

    /* initialize */

    chdir("/tmp");
    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
    umask(0);
    dbopen("/tmp/sendsize.debug");

    /* handle all service requests */

    start_amandates(0);

    while(fgets(line, MAXLINE, stdin)) {
	if(!strncmp(line, "OPTIONS", 7)) {
	    if((str = strstr(line, "MAXDUMPS=")) != NULL &&
	       sscanf(str, "MAXDUMPS=%d", &new_maxdumps) == 1)
		maxdumps = new_maxdumps;
	    sprintf(opt, "OPTIONS MAXDUMPS=%d;\n", maxdumps);
	    write(1, opt, strlen(opt));
	    continue;
	}

	if(sscanf(line, "%s %d %d %s\n", disk, &level, &platter, prog) != 4) {
	    platter = -1;
	    strcpy(prog, "DUMP");
	    if(sscanf(line, "%s %d\n", disk, &level) != 2) goto err;
	}
	add_diskest(disk, level, platter, prog);
    }

    finish_amandates();
    free_amandates();

    for(est = est_list; est != NULL; est = est->next)
	calc_estimates(est);

    dbclose();
    exit(0);
 err:
    printf("FORMAT ERROR IN REQUEST PACKET\n");
    dbprintf(("REQ packet is bogus\n"));
    dbclose();
    exit(1);
}


void add_diskest(disk, level, platter, prog)
char *disk, *prog;
int level, platter;
{
    disk_estimates_t *newp, *curp;
    amandates_t *amdp;
    int dumplev, estlev;
    time_t dumpdate;

    for(curp = est_list; curp != NULL; curp = curp->next) {
	if(!strcmp(curp->amname, disk)) {
	    /* already have disk info, just note the level request */
	    curp->est[level].needestimate = 1;
	    return;
	}
    }

    newp = (disk_estimates_t *) alloc(sizeof(disk_estimates_t));
    memset(newp, 0, sizeof(*newp));
    newp->next = est_list;
    est_list = newp;
    newp->amname = stralloc(disk);
    newp->dirname = stralloc(amname_to_dirname(newp->amname));
    newp->program = stralloc(prog);
    newp->platter = platter;
    newp->est[level].needestimate = 1;

    /* fill in dump-since dates */

    amdp = amandates_lookup(newp->amname);

    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;
	}
    }
}


/*
 * ------------------------------------------------------------------------
 *
 */

void calc_estimates P((disk_estimates_t *est));
void dump_calc_estimates P((disk_estimates_t *));
void generic_calc_estimates P((disk_estimates_t *));

void calc_estimates(est)
disk_estimates_t *est;
{
#ifndef USE_GENERIC_CALCSIZE
    if(!strcmp(est->program, "DUMP"))
	dump_calc_estimates(est);
    else
#endif
	generic_calc_estimates(est);
}

void generic_calc_estimates(est)
disk_estimates_t *est;
{
    char cmd[256], line[2048], *str;
    char *argv[DUMP_LEVELS*2+8];
    int level, argc, calcpid;

#ifdef USE_VERSION_SUFFIXES
    sprintf(cmd, "%s/calcsize-%d.%d.%d", LIBEXEC_DIR,
	    VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
#else
    sprintf(cmd, "%s/calcsize", LIBEXEC_DIR);
#endif

    argv[0] = "calcsize";
    argv[1] = est->program;
    argv[2] = est->amname;
    argv[3] = est->dirname;
    
    argc = 4;
    str = line;

    dbprintf(("%s: running cmd: %s %s %s %s",
	      pname, argv[0], argv[1], argv[2], argv[3]));

    for(level = 0; level < DUMP_LEVELS; level++) {
	if(est->est[level].needestimate) {
	    sprintf(str, "%d", level);
	    argv[argc++] = str; 
	    dbprintf((" %s", str));
	    str += strlen(str) + 1;
	    sprintf(str, "%d", est->est[level].dumpsince);
	    dbprintf((" %s", str));
	    argv[argc++] = str;
	    str += strlen(str) + 1;
	}
    }
    argv[argc] = 0;
    dbprintf(("\n"));

    fflush(stderr); fflush(stdout);	/* XXX necessary? */

    switch(calcpid = fork()) {
    case -1:
        error("fork returned: %s", cmd, strerror(errno));
    default:
        break;
    case 0:
	execve(cmd, argv, NULL);
	dbprintf(("%s: execve %s returned: %s", cmd, strerror(errno)));
	exit(1);
    }

    wait(NULL);
}


/*
 * ------------------------------------------------------------------------
 *
 */

/* local functions */
void dump_calc_estimates P((disk_estimates_t *est));
long getsize_dump P((char *disk, int level));
long handle_dumpline P((char *str));
double first_num P((char *str));

void dump_calc_estimates(est)
disk_estimates_t *est;
{
    int level;
    long size;
    char result[1024];

    for(level = 0; level < DUMP_LEVELS; level++) {
	if(est->est[level].needestimate) {
	    dbprintf(("%s: getting size via dump for %s level %d\n",
		      pname, est->amname, level));
	    size = getsize_dump(est->amname, level);
	    sprintf(result, "%s %d SIZE %ld\n", est->amname, level, size);
	    write(1, result, strlen(result));
	}
    }
}
	    
#define MAXLINE 4096

typedef struct regex_s {
    char *regex;
    int scale;
} regex_t;

regex_t re_size[] = {
    {"  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 */
    {"vdump: Dumping [0-9][0-9]* bytes, ", 1},		      /* OSF/1 vdump */
    {"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: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",1024},
    {"backup: estimated [0-9][0-9]* 1k blocks.",1024},
    {"backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",1024},

    { NULL, 0 }
};


char line[MAXLINE];


long getsize_dump(disk, level)
char *disk;
int level;
{
    int pipefd[2], nullfd, dumppid;
    long size;
    FILE *dumpout;
    char dumpkeys[10], device[256];

    if(disk[0] == '/') strcpy(device, disk);
    else sprintf(device, "%s%s", DEV_PREFIX, disk);

    nullfd = open("/dev/null", O_RDWR);
    pipe(pipefd);
    sprintf(dumpkeys, "%dsf", level);

    dbprintf(("%s: running \"%s %s 100000 - %s\"\n",
	      pname, DUMP, dumpkeys, device));

    switch(dumppid = fork()) {
    case -1: return -1;
    default: break; 
    case 0:	/* child process */
	if(SETPGRP == -1)
	    dbprintf(("setpgrp(0,%d) failed: %s\n",getpid(),strerror(errno)));

	dup2(nullfd, 0);
	dup2(nullfd, 1);
	dup2(pipefd[1], 2);
	close(pipefd[0]);

#ifndef AIX_BACKUP
	sprintf(dumpkeys, "%dsf", level);
	execl(DUMP, "dump", dumpkeys, "100000", "-", device, 0);
#else
	sprintf(dumpkeys, "-%df", level);
	execl(DUMP, "backup", dumpkeys, "-", device, 0);
#endif
	exit(1);
    }
    close(pipefd[1]);
    dumpout = fdopen(pipefd[0],"r");

    size = -1;
    while(fgets(line,MAXLINE,dumpout) != NULL) {
	dbprintf(("%s",line));
	size = handle_dumpline(line);
	if(size > -1) {
	    if(fgets(line, MAXLINE, dumpout) != NULL)
		dbprintf(("%s",line));
	    break;
	}
    }

    dbprintf((".....\n"));
    if(size == -1)
	dbprintf(("(no size line match in above dump output)\n.....\n"));

#ifdef OSF1_HANG_BUG
    sleep(5);
#endif

    kill(-dumppid, SIGTERM);

    close(nullfd);
    fclose(dumpout);

    return size;
}


double first_num(str)
char *str;
/*
 * Returns the value of the first integer in a string.
 */
{
    char tmp[16], *tp;

    tp = tmp;
    while(*str && !isdigit(*str)) str++;
    while(*str && isdigit(*str)) *tp++ = *str++;
    *tp = '\0';

    return atof(tmp);
}


long handle_dumpline(str)
char *str;
/*
 * Checks the dump output line against the error and size regex tables.
 */
{
    regex_t *rp;
    
    /* check for size match */
    for(rp = re_size; rp->regex != NULL; rp++) {
	if(match(rp->regex, str))
	    return (long) ((first_num(str)*rp->scale+1023.0)/1024.0);
    }
    return -1;
}


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic