⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 output-rait.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
/* NOTE: this driver is *deprecated* and should not be used.  See the Device API * in device-src/ for the new implementation. */#ifdef NO_AMANDA#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/ioctl.h>#else#include "amanda.h"#include "tapeio.h"#endif#include "output-rait.h"#include "output-tape.h"#ifdef NO_AMANDA#define	amfree(x)	do {						\	if (x) {							\	    int save_errno = errno;					\	    free(x);							\	    (x) = NULL;							\	    errno = save_errno;						\	}} while(0)#define	tape_open	open#define tapefd_read	read#define tapefd_write	write#define tapefd_close	close#define tape_access	access#define tape_stat	stat#define tapefd_fsf	tape_tapefd_fsf#define tapefd_rewind	tape_tapefd_rewind#define tapefd_status	tape_tapefd_status#define tapefd_unload	tape_tapefd_unload#define tapefd_weof	tape_tapefd_weofint tapeio_init_devname (char * dev,			 char **dev_left,			 char **dev_right,			 char **dev_next);char *tapeio_next_devname (char * dev_left,			   char * dev_right,			   char **dev_next);#endif/*** RAIT -- redundant array of (inexpensive?) tapes**** Author: Marc Mengel <mengel@fnal.gov>**** This package provides for striping input/output across** multiple tape drives.**		 Table of Contents  rait.c..................................................1	MAX_RAITS.........................................2        rait_table........................................2	rait_open(char *dev, int flags, mode_t mode)......2	rait_close(int fd)................................3	rait_lseek(int fd, long pos, int whence)..........4	rait_write(int fd, const char *buf, size_t len) ..5	rait_read(int fd, char *buf, size_t len)..........6	rait_ioctl(int fd, int op, void *p)...............8	rait_access(devname, R_OK|W_OK)...................8	rait_stat(devname, struct statbuf*)...............8	rait_copy(char *f1, char *f2).....................9	ifndef NO_AMANDA	    rait_tapefd_fsf(rait_tapefd, count)..........10	    rait_tapefd_rewind(rait_tapefd)..............10	    rait_tapefd_resetofs(rait_tapefd)............10	    rait_tapefd_unload(rait_tapefd)..............10	    rait_tapefd_status(rait_tapefd, stat)........10	    rait_tapefd_weof(rait_tapefd, count).........10   rait.h.................................................1        typedef RAIT......................................1        ifdef RAIT_REDIRECT...............................1             open.........................................1	     close........................................1             ioctl........................................1	     read.........................................1             write........................................1*//**//*** rait_open takes a string like:** "/dev/rmt/tps0d{3,5,7,19}nrnsv"** and opens** "/dev/rmt/tps0d3nrnsv"** "/dev/rmt/tps0d5nrnsv"** "/dev/rmt/tps0d7nrnsv"** "/dev/rmt/tps0d19nrnsv"** as a RAIT.**** If it has no curly brace, we treat it as a plain device,** and do a normal open, and do normal operations on it.*/#ifdef RAIT_DEBUG#define rait_debug(...) do {						\  int save_errno = errno;						\									\  if (0 != getenv("RAIT_DEBUG")) {					\    dbprintf(__VA_ARGS__);						\  }									\  errno = save_errno;							\} while (0)#else#define rait_debug(...)#endifstatic RAIT *rait_table = 0;		/* table to keep track of RAITS */static size_t rait_table_count;#ifdef NO_AMANDA/* * amtable_alloc -- (re)allocate enough space for some number of elements. * * input:	table -- pointer to pointer to table *		current -- pointer to current number of elements *		elsize -- size of a table element *		count -- desired number of elements *		bump -- round up factor * output:	table -- possibly adjusted to point to new table area *		current -- possibly adjusted to new number of elements */static intamtable_alloc(    void **	table,    int *	current,    size_t	elsize,    int		count,    int		bump,    void *	dummy){    void *table_new;    int table_count_new;    if (count >= *current) {	table_count_new = ((count + bump) / bump) * bump;	table_new = alloc(table_count_new * elsize);	if (0 != *table) {	    memcpy(table_new, *table, *current * elsize);	    amfree(*table);	}	*table = table_new;	memset(((char *)*table) + *current * elsize,	       0,	       (table_count_new - *current) * elsize);	*current = table_count_new;    }    return 0;}/* * amtable_free -- release a table. * * input:	table -- pointer to pointer to table *		current -- pointer to current number of elements * output:	table -- possibly adjusted to point to new table area *		current -- possibly adjusted to new number of elements */voidamtable_free(    void **	table,    int *	current){    amfree(*table);    *current = 0;}#endif#define rait_table_alloc(fd)	amtable_alloc((void **)rait_table_p,	     \					      &rait_table_count,	     \					      SIZEOF(*rait_table),   \					      (size_t)(fd),		     \					      10,			     \					      NULL)intrait_open(    char *	dev,    int		flags,    mode_t	mask){    int fd;			/* the file descriptor number to return */    RAIT *res;			/* resulting RAIT structure */    char *dev_left;		/* string before { */    char *dev_right;		/* string after } */    char *dev_next;		/* string inside {} */    char *dev_real;		/* parsed device name */    int rait_flag;		/* true if RAIT syntax in dev */    int save_errno;    int r;    RAIT **rait_table_p = &rait_table;    int **fds_p;    rait_debug(stderr,_("rait_open( %s, %d, %d )\n"), dev, flags, mask);    rait_flag = (0 != strchr(dev, '{'));    if (rait_flag) {	/*	** we have to return a valid file descriptor, so use	** a dummy one to /dev/null	*/	fd = open("/dev/null",flags,mask);    } else {	/*	** call the normal tape_open function if we are not	** going to do RAIT	*/	fd = tape_open(dev,flags,mask);    }    if(-1 == fd) {	rait_debug(stderr, _("rait_open:returning %d: %s\n"),			    fd,			    strerror(errno));	return fd;    }    if(0 != rait_table_alloc(fd + 1)) {	save_errno = errno;	(void)tapefd_close(fd);	errno = save_errno;	rait_debug(stderr, _("rait_open:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    res = &rait_table[fd];    memset(res, 0, SIZEOF(*res));    res->nopen = 1;    res->fd_count = 0;    if (rait_flag) {	/* copy and parse the dev string so we can scribble on it */	dev = stralloc(dev);	if (0 == dev) {	    rait_debug(stderr, _("rait_open:returning %d: %s\n"),			        -1,			        _("out of stralloc memory"));	    return -1;        }        if (0 != tapeio_init_devname(dev, &dev_left, &dev_right, &dev_next)) {	    rait_debug(stderr, _("rait_open:returning %d: %s\n"),			        -1,			        strerror(errno));	    return -1;        }	while (0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {            fds_p = &(res->fds);	    r = amtable_alloc((void **)fds_p,			    &res->fd_count,			    SIZEOF(*res->fds),			    (size_t)res->nfds + 1,			    10,			    NULL);	    if (0 != r) {		(void)rait_close(fd);		fd = -1;		amfree(dev_real);		break;	    }	    res->fds[ res->nfds ] = tape_open(dev_real,flags,mask);	    rait_debug(stderr,_("rait_open:opening %s yields %d\n"),			dev_real, res->fds[res->nfds] );	    if ( res->fds[res->nfds] < 0 ) {		save_errno = errno;		(void)rait_close(fd);		amfree(dev_real);		errno = save_errno;		fd = -1;		break;	    }	    tapefd_set_master_fd(res->fds[res->nfds], fd);	    amfree(dev_real);	    res->nfds++;	}	/* clean up our copied string */	amfree(dev);    } else {	/*	** set things up to treat this as a normal tape if we ever	** come in here again	*/	res->nfds = 0;        fds_p = &(res->fds);	r = amtable_alloc((void **)fds_p,			  &res->fd_count,			  SIZEOF(*res->fds),			  (size_t)res->nfds + 1,			  1,			  NULL);	if (0 != r) {	    (void)tapefd_close(fd);	    memset(res, 0, SIZEOF(*res));	    errno = ENOMEM;	    fd = -1;	} else {	    res->fds[res->nfds] = fd;	    res->nfds++;	}    }    if (fd >= 0 && res->nfds > 0) {	res->readres = alloc(res->nfds * SIZEOF(*res->readres));	memset(res->readres, 0, res->nfds * SIZEOF(*res->readres));    }    rait_debug(stderr, _("rait_open:returning %d%s%s\n"),			fd,			(fd < 0) ? ": " : "",			(fd < 0) ? strerror(errno) : "");    return fd;}#ifdef NO_AMANDAinttapeio_init_devname(    char *	dev,    char **	dev_left,    char **	dev_right,    char **	dev_next){    /*    ** find the first { and then the first } that follows it    */    if ( 0 == (*dev_next = strchr(dev, '{'))	 || 0 == (*dev_right = strchr(*dev_next + 1, '}')) ) {	/* we dont have a {} pair */	amfree(dev);	errno = EINVAL;	return -1;    }    *dev_left = dev;				/* before the { */    **dev_next = 0;				/* zap the { */    (*dev_next)++;    (*dev_right)++;				/* after the } */    return 0;}char *tapeio_next_devname(    char *	dev_left,    char *	dev_right,    char **	dev_next){    char *dev_real = 0;    char *next;    int len;    next = *dev_next;    if (0 != (*dev_next = strchr(next, ','))	|| 0 != (*dev_next = strchr(next, '}'))){	**dev_next = 0;				/* zap the terminator */	(*dev_next)++;	/*	** we have one string picked out, build it into the buffer	*/	len = strlen(dev_left) + strlen(next) + strlen(dev_right) + 1;	dev_real = alloc(len);	strcpy(dev_real, dev_left);		/* safe */	strcat(dev_real, next);		/* safe */	strcat(dev_real, dev_right);	/* safe */    }    return dev_real;}#endif/*** close everything we opened and free our memory.*/intrait_close(    int fd){    int i;			/* index into RAIT drives */    int j;			/* individual tapefd_close result */    int res;			/* result from close */    RAIT *pr;			/* RAIT entry from table */    int save_errno = errno;    pid_t kid;    int **fds_p;    rait_debug(stderr,_("rait_close( %d )\n"), fd);    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {	errno = EBADF;	rait_debug(stderr, _("rait_close:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    pr = &rait_table[fd];    if (0 == pr->nopen) {	errno = EBADF;	rait_debug(stderr, _("rait_close:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    if (0 == pr->readres && 0 < pr->nfds) {	pr->readres = alloc(pr->nfds * SIZEOF(*pr->readres));	memset(pr->readres, 0, pr->nfds * SIZEOF(*pr->readres));    }    res = 0;    /*    ** this looks strange, but we start kids who are going to close the    ** drives in parallel just after the parent has closed their copy of    ** the descriptor. ('cause closing tape devices usually causes slow    ** activities like filemark writes, etc.)    */    for( i = 0; i < pr->nfds; i++ ) {	if(tapefd_can_fork(pr->fds[i])) {	    if ((kid = fork()) == 0) {		/* we are the child process */		sleep(0);		j = tapefd_close(pr->fds[i]);		exit(j);            } else {		/* remember who the child is or that an error happened */	  	pr->readres[i] = (ssize_t)kid;            }	}	else {	    j = tapefd_close(pr->fds[i]);	    if ( j != 0 )		res = j;	    pr->readres[i] = -1;	}    }    for( i = 0; i < pr->nfds; i++ ) {	j = tapefd_close(pr->fds[i]);	if ( j != 0 )           res = j;    }    for( i = 0; i < pr->nfds; i++ ) {        int stat;	if(pr->readres[i] != -1) {	    waitpid((pid_t)pr->readres[i], &stat, 0);	    if( WEXITSTATUS(stat) != 0 ) {		res = WEXITSTATUS(stat);		if( res == 255 )		    res = -1;	    }        }    }    if (pr->nfds > 1) {	(void)close(fd);	/* close the dummy /dev/null descriptor */    }    if (0 != pr->fds) {        fds_p = &pr->fds;	amtable_free((void **)fds_p, &pr->fd_count);    }    if (0 != pr->readres) {	amfree(pr->readres);    }    if (0 != pr->xorbuf) {	amfree(pr->xorbuf);    }    pr->nopen = 0;    errno = save_errno;    rait_debug(stderr, _("rait_close:returning %d%s%s\n"),			res,			(res < 0) ? ": " : "",			(res < 0) ? strerror(errno) : "");    return res;}/**//*** seek out to the nth byte on the RAIT set.** this is assumed to be evenly divided across all the stripes*/off_trait_lseek(    int		fd,    off_t	pos,    int		whence){    int i;			/* drive number in RAIT */    off_t res, 			/* result of lseeks */	 total;			/* total of results */    RAIT *pr;			/* RAIT slot in table */    rait_debug(stderr, _("rait_lseek(%d, %lld, %d)\n"),		fd, (long long)pos, whence);    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {	errno = EBADF;	rait_debug(stderr, _("rait_lseek:returning %d: %s\n"),			    -1,			    strerror(errno));	return (off_t)-1;    }    pr = &rait_table[fd];    if (0 == pr->nopen) {	errno = EBADF;	rait_debug(stderr, _("rait_lseek:returning %d: %s\n"),			    -1,			    strerror(errno));	return (off_t)-1;    }    if ((pr->nfds > 1) && ((pos % (off_t)(pr->nfds-1)) != (off_t)0)) {	errno = EDOM;	total = (off_t)-1;    } else {	total = (off_t)0;	pos = pos / (off_t)pr->nfds;	for( i = 0; i < pr->nfds; i++ ) {	    if ((off_t)0 >= (res = lseek(pr->fds[i], pos, whence))) {		total = res;		break;	    }	    total += res;	}    }    rait_debug(stderr, _("rait_lseek:returning %ld%s%s\n"),			total,			(total < 0) ? ": " : "",			(total < 0) ? strerror(errno) : "");    return total;}/**//*** if we only have one stream, just do a write,** otherwise compute an xor sum, and do several** writes...*/ssize_trait_write(    int		fd,    const void *bufptr,    size_t	len){    const char *buf = bufptr;    int i;	/* drive number */    size_t j;	/* byte offset */    RAIT *pr;	/* RAIT structure for this RAIT */    ssize_t res;    ssize_t total = 0;    int data_fds;	/* number of data stream file descriptors */    rait_debug(stderr, _("rait_write(%d,%lx,%d)\n"),fd,(unsigned long)buf,len);    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {	errno = EBADF;	rait_debug(stderr, _("rait_write:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    pr = &rait_table[fd];    if (0 == pr->nopen) {	errno = EBADF;	rait_debug(stderr, _("rait_write:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    /* need to be able to slice it up evenly... */    if (pr->nfds > 1) {	data_fds = pr->nfds - 1;	if (0 != len % data_fds) {	    errno = EDOM;	    rait_debug(stderr, _("rait_write:returning %d: %s\n"),			        -1,			        strerror(errno));	    return -1;	}	/* each slice gets an even portion */	len = len / data_fds;	/* make sure we have enough buffer space */	if (len > (size_t)pr->xorbuflen) {	    if (0 != pr->xorbuf) {		amfree(pr->xorbuf);	    }	    pr->xorbuf = alloc(len);	    pr->xorbuflen = len;	}	/* compute the sum */	memcpy(pr->xorbuf, buf, len);	for( i = 1; i < data_fds; i++ ) {	    for( j = 0; j < len; j++ ) {		pr->xorbuf[j] ^= buf[len * i + j];	    }	}    } else {	data_fds = pr->nfds;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -