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

📄 server.c

📁 一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX, FreeBSD, Digital Unix (OSF1), Solaris and HP-UX.
💻 C
📖 第 1 页 / 共 5 页
字号:
  tapefd = -1;  tapeaccessmode = NOT_OPEN;  return(ret);}Int32write_tape_buffer(Int32 * bufferpos, Int32 * bytes_flushed){  Int32		nextidx, r;  if(streamerbuffer){#ifdef	HAVE_POSIX_THREADS	/* prevent other thread from reconfiguring */    pthread_mutex_lock(&may_reconfig_buffer_mutex);	/* the buffer */    pthread_mutex_lock(&may_modify_buffer_ptrs);#endif    nextidx = streamerbuf_insert_idx + 1;    if(nextidx >= streamerbufferlen)	nextidx = 0;#ifdef	HAVE_POSIX_THREADS    if(nextidx == streamerbuf_processed_idx){	/* let other thread process */	streamerbuf_writing = YES; 	/* not really necessary, if highmark */					/* is set reasonably */	pthread_mutex_unlock(&may_reconfig_buffer_mutex);	if(buffer_thread_running)	  pthread_cond_wait(&can_write_to_buffer,	/* wait for space */				&may_modify_buffer_ptrs);	pthread_mutex_lock(&may_reconfig_buffer_mutex);	nextidx = streamerbuf_insert_idx + 1;	/* buffer might have been */	if(nextidx >= streamerbufferlen)	/* reconfigured */	  nextidx = 0;    }#else    while(nextidx == streamerbuf_processed_idx){	process_tape_ops(NO, YES);	if(tapefd < 0 && (tapeaccessmode & OPENED_RAW_ACCESS))	  return(WRITE_FAILED);    }#endif    memcpy(streamerbuffer + streamerbuf_insert_idx * tapeblocksize,			tapebuffer, sizeof(UChar) * tapeblocksize);    streamerbuf_insert_idx = nextidx;    *bytes_flushed = tapeblocksize;    *bufferpos = 0;#ifdef	HAVE_POSIX_THREADS    if(num_blocks_in_streamerbuf >= streamerbuf_highmark){      streamerbuf_writing = YES;      pthread_cond_signal(&buffer_contains_data);    }    pthread_mutex_unlock(&may_modify_buffer_ptrs);    pthread_mutex_unlock(&may_reconfig_buffer_mutex);    if(tapefd < 0 && (tapeaccessmode & OPENED_RAW_ACCESS))	return(-errno);#endif    return(0);  }  else{    if(iauxtapebuffer){	Int32	i, iauxbufpos, iauxbytes_in_tapefile;	for(i = r = 0; i < iauxtapebufferlen; i += tapeblocksize){	  r = flush_buffer_to_tape(iauxtapebuffer + i,					&iauxbufpos, &iauxbytes_in_tapefile);	  if(r || iauxbufpos != 0 || iauxbytes_in_tapefile != tapeblocksize){	    r = (r ? r : FATAL_ERROR);	    break;	  }	}	ZFREE(iauxtapebuffer);	iauxtapebufferlen = 0;	if(r)	  return(r);    }    return(flush_buffer_to_tape(tapebuffer, bufferpos, bytes_flushed));  }}/* write tapebuffer to tape, evtl. start a new file or change cartridge */Int32flush_buffer_to_tape(  UChar		*tapebuf,  Int32		*bufferpos,		/* only to return the new value */  Int32		*flushed_bytes){  static Flag	write_error = NO;  Int32		i, newcart, newfile, written, w, ret = NO_ERROR;  Int32		cart_bef_change, files_on_tape;  UChar		*filename;  Flag		eom, do_reopen = NO, dont_write = NO;  int		filemode;  filenum_incr_by_eof = NO;  files_on_tape = actfilenum;  if(!(tapeaccessmode & OPENED_RAW_ACCESS)){    if(maxbytes_per_tape && bytes_on_tape + (Real64) tapeblocksize					> maxbytes_per_tape[actcart - 1]){	eom = YES;	statusmsg(T_("Current cartridge no. %d is already full\n"), (int) actcart);	goto change_tape;	/* sorry, otherwise huge complication */    }    if(maxbytes_per_file && bytes_in_tapefile + tapeblocksize > maxbytes_per_file){	do_reopen = YES;    }    if(streamerbuffer){      if(reqnewfilebuf[streamerbuf_processed_idx]){	if(bytes_in_tapefile > 0)	/* only reopen, if nothing has been */	  do_reopen = YES;	/* written to the current tape file yet */	reqnewfilebuf[streamerbuf_processed_idx] = NO;      }    }    else{      if(newfilerequested){	if(bytes_in_tapefile > 0)	/* same as above */	  do_reopen = YES;	newfilerequested = NO;      }    }    if(do_reopen){      if(reopentapewr()){	logmsg(LOG_ERR, T_("Error: Cannot reopen device for writing.\n"));	ret = REOPEN_FAILED;	GETOUT;      }      files_on_tape = actfilenum;    }  }  errno = 0;	/* set errno unconditionally here, cause return values */		/* on FreeBSD below are different compared to other OSes */		/* so errno must be evaluated to and thus be reset here */  written = write_forced(tapefd, tapebuf, tapeblocksize);  w = (written > 0 ? written : 0);  bytes_in_tapefile += w;  bytes_on_tape += (Real64) w;	/* status report */  write_rate += w;  if(!write_meas_time){    write_meas_time = time(NULL);    write_rate = 0;  }  else{    actime = time(NULL);    if(actime >= write_meas_time + 10){	statusmsg(T_("Device %s is writing with %d KB/s to cartridge %d, file %d.\n"),		(char *) devicename,		(int)((((write_rate >> 9) + 1) >> 1) / (actime - write_meas_time)),		(int) actcart, (int) actfilenum);	write_meas_time = actime;	write_rate = 0;    }  }  *flushed_bytes = w;  if(written == tapeblocksize){		/* the normal case */    write_error = NO;    *bufferpos = 0;    tape_rewound = NO;    tape_moved = YES;    return(0);  }  if(written > 0 && written < tapeblocksize){	/* block not fully written */    memmove(tapebuf, tapebuf + written,				(tapeblocksize - written) * sizeof(UChar));    *bufferpos = written;			/* we try not to be afraid */    write_error = NO;    return(0);  }  if(tapeaccessmode & OPENED_RAW_ACCESS){	/* In raw access mode */    if(tapefd >= 0)				/* it is always an error, */	close(tapefd);			/* if nothing could be written */    tapefd = -1;    *bufferpos = 0;    return(ENDOFTAPEREACHED);  }#ifdef	__FreeBSD_version#if	__FreeBSD_version >= 470000#define	FREE_BSD_470000_OR_HIGHER	1#endif#endif#ifdef	FREE_BSD_470000_OR_HIGHER	/* hooray, the FreeBSD 'SA' driver behaviour has changed with */	/* FreeBSD 4.7 towards one closer to System-V style. Sigh. */	/* Modification suggested and tested by Rudolf Cejka at */	/* Brno University of Technology */  eom = (written == 0) ? YES : NO;  if(written < 0){				/* tape operation failed */#else  eom = NO;  if(written <= 0){				/* tape operation failed */#endif    i = errno;		/* this assignment is for debugging purposes */#ifdef	sun    if(!END_OF_TAPE(errno)){	/* on full filesystem END_OF_TAPE is true */	struct mtget	mtstat;		/* so here we get only with tapes */	i = ioctl(tapefd, MTIOCGET, &mtstat);	if(i){	  logmsg(LOG_ERR, T_("Error: Cannot get tape status after write failure.\n"));	  errno = ENOSPC;	}	else{	  if(mtstat.mt_erreg)	/* mt_erreg is UNDOCUMENTED, even on Sun- */	    errno = ENOSPC;	/* solve. So we assume end of tape on any */	}						/* error != 0 */    }		/* suspicions are: 0x13==EOT, 0x12==EOF, 0x05==illegal-req */			/* 0x08==blank-check(EOR) */#endif#if	defined(__hpux) || defined(hpux)#ifdef	MTIOCGET    if(!END_OF_TAPE(errno)){	/* on full filesystem END_OF_TAPE is true */	struct mtget	mtgetst;	/* so here we get only with tapes */	i = ioctl(tapefd, MTIOCGET, &mtgetst);	if(i){	  logmsg(LOG_ERR, T_("Error: Cannot get tape status after write failure.\n"));	  errno = ENOSPC;	}	else{	  if(GMT_EOT(mtgetst.mt_gstat))	/* see man 7 mt on HPUX */	    errno = ENOSPC;	}						/* error != 0 */    }#endif#endif    if(END_OF_TAPE(errno)){	eom = YES;	errno = 0;    }    else if(errno ==#ifdef	_AIX			EMEDIA || errno == #endif				EIO){      if(write_error){	logmsg(LOG_ERR, T_("Error: Repeated faults writing to tape, now: %s.\n"),				strerror(errno));	ret = FATAL_ERROR;	GETOUT;      }      logmsg(LOG_WARNING, T_("Warning: A media error occured (%d), trying to reposition and reopen.\n"),			errno);      files_on_tape = actfilenum;#if 0	/* this may not be done here, cause by definition tapeaccessmode */      tapeaccessmode = NOT_OPEN;	/* reflects the status seen by the */#endif			/* client regardless of server internal problems. */	/* tapeaccessmode = NOT_OPEN will be set if recovery is impossible */      if(tapefd >= 0)		/* streamers usually rewind on an EIO, e.g. */	close(tapefd);		/* due to a SCSI bus reset. It would not be */      				/* a cool idea to simply */      tapefd = -1;				/* reopen and write on, */      i = (bytes_in_tapefile > 0 ? 1 : 0);	/* thus overwriting stuff */      if(set_filenum(actfilenum + i, NO, NO))	/* written before. So we */	eom = YES;		/* try to re-position to the next file. If */      else			/* that fails, we load the next cartridge. */	files_on_tape = actfilenum;	/* If the current tapefile is still */					/* empty, reposition to the same */      write_error = YES;    }    else{	logmsg(LOG_ERR, T_("Error: Writing to tape: %s.\n"), strerror(errno));	ret = FATAL_ERROR;	GETOUT;    }  }  if(!eom){    i = reopentapewr();		/* try again into the next tape file */    if(!i){      files_on_tape = actfilenum;      errno = 0;		/* see above for comment */      written = write_forced(tapefd, tapebuf, tapeblocksize);      w = (written > 0 ? written : 0);      bytes_in_tapefile += w;      bytes_on_tape += (Real64) w;      write_rate += w;		/* for status report */      *flushed_bytes = w;      if(written == tapeblocksize){		/* that worked */	write_error = NO;	*bufferpos = 0;	tape_moved = YES;	tape_rewound = NO;	return(0);      }      if(written > 0 && written < tapeblocksize){	memmove(tapebuf, tapebuf + written,				(tapeblocksize - written) * sizeof(UChar));	*bufferpos = written;		/* keep fingers crossed */	write_error = NO;	return(0);      }      eom = YES;	/* some other problems with the tape, assume EOM */      logmsg(LOG_WARNING, T_("Warning: An unexpected error (%d) occured, changing cartridge. Proceeding with fingers crossed.\n"),				errno);      write_error = YES;    }    else{			/* reopen failed */	logmsg(LOG_WARNING, T_("Warning: Reopen failed (%d), changing cartridge. Proceeding with fingers crossed.\n"),				errno);	eom = YES;    }  } change_tape:  if(eom){			/* TAPE FULL */	if(tapefd >= 0)	  close(tapefd);	/* we change the cartridge and try again */	tapefd = -1;	tape_full_actions(actcart);	if( (i = save_bytes_per_tape_msg(bytesontape_file, actcart,			bytes_on_tape, files_on_tape, YES, time(NULL))) ){	  ret = REOPEN_FAILED;	  GETOUT;	}	if(interrupted)	  do_exit(1);	bytes_in_tapefile = 0;	endofrec = NO;	if(!AUTOCHCART)	  return(ENDOFTAPEREACHED);	cart_bef_change = actcart;	i = find_next_free_pos(&newcart, &newfile,				inscart[active_cartset], active_cartset);	if(i){	  logmsg(LOG_ERR, T_("Error: Cannot find a new cartridge for writing.\n"));	  ret = REOPEN_FAILED;	  GETOUT;	}	i = set_cartridge(- newcart, YES);	/* a clone tape is accepted here */	if(i){					/* only after repeated tries */	  logmsg(LOG_ERR, T_("Error: Cannot change to cartridge %d for writing.\n"),			newcart);	  ret = REOPEN_FAILED;	  GETOUT;	}		/* now actcart is newcart is tape in drive */ 	if(actcart != newcart && var_append)	/* other cartridge inserted */	  newfile = insfilenum[active_cartset];	i = save_cart_order(cart_bef_change, actcart, newfile);	if(i){		/* this is no longer done in find_next_free_pos */	  ret = REOPEN_FAILED;	  GETOUT;	}	if(newfile == 1)	  bytes_on_tape = 0.0;	else	  i = get_bytes_per_tape_msg(bytesontape_file, actcart,					&bytes_on_tape, NULL, NULL, NULL);	if(newfile == 1){	  i = rewindtape(YES, NO);	  actfilenum = 1;	}	else	  i = set_filenum(newfile, YES, NO);	if(i){	  logmsg(LOG_ERR, T_("Error: Cannot move to file %d for writing.\n"), (int) newfile);	  ret = i;	  GETOUT;	}#ifdef	HAVE_POSIX_THREADS	if(streamerbuffer)	  pthread_mutex_lock(&tapepos_mutex);#endif	inscart[active_cartset] = rdcart = actcart;	insfilenum[active_cartset] = rdfilenum = actfilenum;#ifdef	HAVE_POSIX_THREADS	if(streamerbuffer)	  pthread_mutex_unlock(&tapepos_mutex);#endif	if(actcart != newcart && !var_append)	  logmsg(LOG_CRIT, T_("Internal Error: Wrong tape %d accepted in drive for %d, please report.\n"),			actcart, newcart);	if(actfilenum != newfile)	  logmsg(LOG_CRIT, T_("Internal Error: Wrong file number %d set instead of %d, please report.\n"),			actfilenum, newfile);	if(interrupted)	  do_exit(1);	add_to_written_tapes(actcart /* == newcart */);	if(newfile == 1){	  i = erasetape();	  if(i)	    logmsg(LOG_WARNING, T_("Warning: Cannot erase tape.\n"));	  if(interrupted)	    do_exit(1);	  if(newfile == 1){	    i = rewindtape(YES, NO);	    actfilenum = 1;	  }	  else	    i = set_filenum(newfile, YES, NO);	  if(i){	    logmsg(LOG_ERR, T_("Error: Cannot move to file %d for writing.\n"), (int) newfile);	    ret = i;	    GETOUT;	  }	}	if(interrupted)	  do_exit(1);	if(inscart[active_cartset] != actcart /* == newcart */)	  logmsg(LOG_CRIT, T_("Internal Error: Wrong tape for writing in drive, please report.\n"));	if(actfilenum == 1){	  i = write_infobuffer(inscart[active_cartset] /* == newcart */);	  if(i){	    logmsg(LOG_ERR, T_("Error: Cannot write label to tape.\n"));	    ret = i;	    GETOUT;	  }	  insfilenum[active_cartset] = actfilenum = 1;	}	if(write_tapepos_file_msg()){	  ret = REOPEN_FAILED;	  GETOUT;	}	if( (i = save_bytes_per_tape_msg(bytesontape_file, actcart,				bytes_on_tape, actfilenum, NO, time(NULL))) ){	  ret = REOPEN_FAILED;	  GETOUT;	}	if(IS_REGFILE(devstatb) || IS_DIRECTORY(devstatb)){	  if( (i = update_devicesettings(insfilenum[active_cartset], YES)) ){	    logmsg(LOG_ERR, T_("Error: Cannot change to file %d for writing.\n"),				insfilenum[active_cartset]);	    ret = i;	    GETOUT;	  }	}	filename = devicename;	filemode = O_WRONLY | O_BINARY;	if(IS_DIRECTORY(devstatb)){	  filename = storefile;	  filemode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;

⌨️ 快捷键说明

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