Example #1
0
static int
ForkIoctl(usd_handle_t fd, int op, int count)
{
    usd_tapeop_t tapeop;

    /* Issue requested tape control */
    tapeop.tp_op = op;
    tapeop.tp_count = count;

    return (USD_IOCTL(fd, USD_IOCTL_TAPEOPERATION, (void *)&tapeop));
}
Example #2
0
/* write an EOF marker */
int
fileMark(usd_handle_t hTape)
{
    usd_tapeop_t tapeop;
    int rcode;

    tapeop.tp_op = USDTAPE_WEOF;
    tapeop.tp_count = 1;
    rcode = USD_IOCTL(hTape, USD_IOCTL_TAPEOPERATION, (void *)&tapeop);
    return rcode;
}
Example #3
0
/* rewindTape() - rewinds tape to beginning */
afs_int32
rewindTape(usd_handle_t hTape)
{
    usd_tapeop_t tapeop;
    int rcode;

    tapeop.tp_op = USDTAPE_REW;
    tapeop.tp_count = 1;
    rcode = USD_IOCTL(hTape, USD_IOCTL_TAPEOPERATION, (void *)&tapeop);
    return rcode;
}
Example #4
0
void
incPosition(struct butm_tapeInfo *info, usd_handle_t fid, afs_uint32 dataSize)
{
    /* Add this to the amount of data written to the tape */
    incSize(info, dataSize);

    info->posCount += dataSize;

    if (info->posCount >= 2147467264) {	/* 2GB - 16K */
	info->posCount = 0;
#if (defined(AFS_SUN_ENV) || defined(AFS_LINUX24_ENV))
	if (!isafile) {
	    afs_int64 off;

	    off = 0;
	    USD_IOCTL(fid, USD_IOCTL_SETSIZE, &off);
	}
#endif
    }
}
Example #5
0
int
openOutFile(struct volumeHeader *headerPtr)
{
    afs_int32 len;
    int ch;
    int rc;
    int oflag;
    int skip, first;
    afs_hyper_t size;

    /* If we were asked to skip this volume, then skip it */
    if (nskip) {
	nskip--;
	return 0;
    }
    /* Skip if we are not to restore any */
    if (!nrestore)
	return 0;

    /* Get the volume name and strip off the BK or RO extension */
    if (outfile) {
	strcpy(filename, outfile);
    } else {
	strcpy(filename, headerPtr->volumeName);
	len = strlen(filename);
	if ((len > 7) && (strcmp(".backup", filename + len - 7) == 0)) {
	    filename[len - 7] = 0;
	} else if ((len > 9)
		   && (strcmp(".readonly", filename + len - 9) == 0)) {
	    filename[len - 9] = 0;
	}
    }

    if (ask) {
	first = 1;
	skip = 0;
	printf("Press return to retreive volume %s (%u) to file %s; " "s"
	       " to skip\n", headerPtr->volumeName, headerPtr->volumeID,
	       filename);
	do {
	    ch = getchar();
	    if ((first == 1) && (ch == 's'))
		skip = 1;
	    if ((first == 1) && (ch == 'q'))
		exit(0);
	    first = 0;
	} while (ch != '\n');
	if (skip) {
	    printf("Will not restore volume %s\n", headerPtr->volumeName);
	    return 0;
	}
    } else {
	printf("Retrieve volume %s (%u) to file %s\n", headerPtr->volumeName,
	       headerPtr->volumeID, filename);
    }

    /* Should I append the date onto the end of the name? */

    /* Open the file to write to */
    if (headerPtr->contd == TC_VOLCONTD) {
	/* Continuation of dump */
	oflag = USD_OPEN_RDWR;
    } else {
	/* An all new dump */
	oflag = USD_OPEN_RDWR | USD_OPEN_CREATE;
    }
    rc = usd_Open(filename, oflag, 0664, &ofd);
    if (rc != 0) {
	fprintf(stderr, "Unable to open file %s. Skipping. Code = %d\n",
		filename, rc);
	nrestore--;
	return 0;
    }
    if (headerPtr->contd != TC_VOLCONTD) {
	hzero(size);
	rc = USD_IOCTL(ofd, USD_IOCTL_SETSIZE, &size);
	if (rc != 0) {
	    fprintf(stderr, "Unable to open file %s. Skipping. Code = %d\n",
		    filename, rc);
	    USD_CLOSE(ofd);
	    nrestore--;
	    return 0;
	}
    }
    ofdIsOpen = 1;
    return 0;
}
Example #6
0
static int
ForkIoctl(usd_handle_t fd, int op, int count)
{
    int rc;			/* return code from system calls */
    int i;			/* loop index */
    int pid;			/* process ID of child process */
    int status;			/* exit status of child process */
    int ioctl_rc;		/* return code from ioctl call */
    int pipefd[2];		/* pipe for child return status */
    int forkflag;		/* flag set when ready to fork */
    usd_tapeop_t tapeop;	/* tape operation specification */
    int unixfd;

#ifdef AFS_PTHREAD_ENV
    forkflag = 0;		/* No need to fork if using pthreads */
#else
    forkflag = 1;
#endif

    /* initialize tape command structure */
    tapeop.tp_op = op;
    tapeop.tp_count = count;

    /* create pipe for getting return code from child */
    if (forkflag) {
	rc = pipe(pipefd);
	if (rc < 0) {
	    printf("butm:  Can't open pipe for IOCTL process. Error %d\n",
		   errno);
	    forkflag = 0;
	}
    }

    if (forkflag) {
	pid = fork();
	if (pid < 0) {
	    close(pipefd[0]);
	    close(pipefd[1]);
	    printf("butm:  Can't fork IOCTL process. Error %d\n", errno);
	    forkflag = 0;

	}
    }

    if (!forkflag) {		/* problem starting child process */
	/* do the ioctl anyway, it will probably work */
	ioctl_rc = USD_IOCTL(fd, USD_IOCTL_TAPEOPERATION, (void *)&tapeop);
    } else if (pid == 0) {	/* child process */
	/* close all unneccessary file descriptors */
	/* note: as painful as it is, we have to reach under the covers of
	 *       the usd package to implement this functionality.
	 */
	unixfd = (intptr_t)(fd->handle);

	for (i = 3; i < _POSIX_OPEN_MAX; i++) {
	    if (i != unixfd && i != pipefd[1]) {
		close(i);
	    }
	}

	/* do the ioctl call */
	ioctl_rc = USD_IOCTL(fd, USD_IOCTL_TAPEOPERATION, (void *)&tapeop);

	/*
	 * Send the return code back to the parent.
	 * If this fails, there's nothing we can do, but we must test
	 * it in order to avoid complier warnings on some platforms.
	 */
	if (write(pipefd[1], &ioctl_rc, sizeof(int)) < 0)
	    ; /* don't care */

	exit(0);
    } else {			/* parent process */

	close(pipefd[1]);
	POLL();
	/* read the result from the child process */
	rc = read(pipefd[0], &ioctl_rc, sizeof(int));
	if (rc != sizeof(int)) {
	    /* tape is now in unknown state */
	    printf("butm:  Can't determine IOCTL child status. Error %d\n",
		   errno);
	    ioctl_rc = EFAULT;
	}

	close(pipefd[0]);

	/* get the completion status from the child process */
	rc = waitpid(pid, &status, 0);
	while (rc < 0 && errno == EINTR) {
	    rc = waitpid(pid, &status, 0);
	}
	if (rc < 0) {
	    printf("butm:  Can't determine IOCTL child status. Error %d\n",
		   errno);
	} else if (status != 0) {
	    printf
		("butm: Unexpected IOCTL process status 0x%04x . Error %d\n",
		 status, errno);
	}
	SLEEP(1);
    }

    return (ioctl_rc);
}
Example #7
0
static afs_int32
file_WriteLabel(struct butm_tapeInfo *info, struct butm_tapeLabel *label,
		afs_int32 rewind)
{
    afs_int32 code = 0;
    afs_int32 fcode;
    struct tapeLabel *tlabel;
    struct progress *p;
    afs_int64 off;		/* offset */

    if (info->debug)
	printf("butm: Write tape label\n");

    POLL();
    info->error = 0;

    code = check(info, WRITE_OP);
    if (code)
	ERROR_EXIT(code);
    if (!label)
	ERROR_EXIT(BUTM_BADARGUMENT);
    if (label->structVersion != CUR_TAPE_VERSION)
	ERROR_EXIT(BUTM_OLDINTERFACE);

    if (rewind) {		/* Not appending, so rewind */
	code = rewindFile(info);
	if (code)
	    ERROR_EXIT(code);

	if (isafile) {
	    p = (struct progress *)info->tmRock;
	    off = 0;
	    code = USD_IOCTL(p->fid, USD_IOCTL_SETSIZE, &off);
	    if (code)
		ERROR_EXIT(BUTM_POSITION);
	}
    } else {
	if (READS || WRITES)
	    ERROR_EXIT(BUTM_BADOP);
    }

    /* Copy the label into the tape block
     * ---------------------------------- */
    memset(tapeBlock, 0, BUTM_BLOCKSIZE);

    if (!label->creationTime)
	label->creationTime = time(0);

    tlabel = (struct tapeLabel *)tapeBlock;
    memcpy(&tlabel->label, label, sizeof(struct butm_tapeLabel));
    tlabel->label.structVersion = htonl(CUR_TAPE_VERSION);
    tlabel->label.creationTime = htonl(tlabel->label.creationTime);
    tlabel->label.expirationDate = htonl(tlabel->label.expirationDate);
    tlabel->label.size = htonl(tlabel->label.size);
    tlabel->label.useCount = htonl(tlabel->label.useCount);
    tlabel->label.dumpid = htonl(tlabel->label.dumpid);

    /*
     * write the tape label - For appends, the write may need to skip
     * over 1 or 2 EOF marks that were written when tape was closed after
     * the last dump. Plus, some AIX tape drives require we try forwarding
     * over the last EOF and take an error before we can write the new label.
     * ---------------------------------------------------------------------- */
    code = WriteTapeBlock(info, tapeBlock, BUTM_BLOCKSIZE, BLOCK_LABEL);
    if (!isafile && !rewind && (code == BUTM_IO))
	do {			/* do if write failed */
	    fcode = SeekFile(info, 1);	/* skip over the EOF */
	    if (fcode)
		break;		/* leave if error */

	    code =
		WriteTapeBlock(info, tapeBlock, BUTM_BLOCKSIZE, BLOCK_LABEL);
	    if (code != BUTM_IO)
		break;		/* continue if write failed */

	    fcode = SeekFile(info, 1);	/* skip over the EOF */
	    if (fcode) {	/* retry 1 write if couldn't skip */
		code =
		    WriteTapeBlock(info, tapeBlock, BUTM_BLOCKSIZE,
				   BLOCK_LABEL);
		break;
	    }

	    code =
		WriteTapeBlock(info, tapeBlock, BUTM_BLOCKSIZE, BLOCK_LABEL);
	    if (code != BUTM_IO)
		break;		/* continue if write failed */

	    fcode = SeekFile(info, 1);	/* skip over the EOF */
	    if (fcode) {	/* retry 1 write if couldn't skip */
		code =
		    WriteTapeBlock(info, tapeBlock, BUTM_BLOCKSIZE,
				   BLOCK_LABEL);
		break;
	    }
	    break;
	} while (0);

    /* clear the write error status a failed WriteTapeBlock may have produced */
    if (!code)
	info->status &= ~BUTM_STATUS_WRITEERROR;

  error_exit:
    return code;
}