void Rename_RSTN_SET() { int j, k; read_fm(Rename_scrd,1); Rename_scrd = ntohl ( Rename_scrd ); read_fm(Rename_sset[1],Rename_scrd); convert_arr_ntohl(Rename_sset,1,Rename_scrd); }
/* BSF => just before last EOF * EOF + BSF => just before EOF * file 0 + BSF => BOT + errno */ int vtape::bsf() { ASSERT(online); ASSERT(current_file >= 0); Dmsg2(dbglevel, "bsf %i:%i count=%i\n", current_file, current_block); int ret = 0; check_eof(); atBOT = atEOF = atEOT = atEOD = false; if (current_file == 0) {/* BOT + errno */ lseek(fd, 0, SEEK_SET); read_fm(VT_READ_EOF); current_file = 0; current_block = 0; atBOT = true; errno = EIO; ret = -1; } else { Dmsg1(dbglevel, "bsf last=%lli\n", last_FM); lseek(fd, cur_FM, SEEK_SET); current_file--; current_block=-1; } return ret; }
void Rename_RSTN_FNC() { int j, k; read_fm(Rename_Vfnc[1],Rename_VfncP2); convert_arr_ntohl(Rename_Vfnc,1,Rename_VfncP2); }
void CfgDepBase_RSTN_FNC() { int j, k; read_fm(CfgDepBase_Vfnc[1],CfgDepBase_VffncP2); convert_arr_ntohl(CfgDepBase_Vfnc,1,CfgDepBase_VffncP2); }
/* * TODO: Check fsr with EOF */ int vtape::fsr(int count) { ASSERT(online); ASSERT(current_file >= 0); ASSERT(fd >= 0); int i,nb, ret=0; // boffset_t where=0; uint32_t s; Dmsg4(dbglevel, "fsr %i:%i EOF=%i c=%i\n", current_file,current_block,atEOF,count); check_eof(); if (atEOT) { errno = EIO; current_block = -1; return -1; } if (atEOD) { errno = EIO; return -1; } atBOT = atEOF = false; /* check all block record */ for(i=0; (i < count) && !atEOF ; i++) { nb = ::read(fd, &s, sizeof(uint32_t)); /* get size of next block */ if (nb == sizeof(uint32_t) && s) { current_block++; lseek(fd, s, SEEK_CUR); /* seek after this block */ } else { Dmsg4(dbglevel, "read EOF %i:%i nb=%i s=%i\n", current_file, current_block, nb,s); errno = EIO; ret = -1; if (next_FM) { current_file++; read_fm(VT_SKIP_EOF); } atEOF = true; /* stop the loop */ } } return ret; }
/* * Go to next FM */ int vtape::fsf() { ASSERT(online); ASSERT(current_file >= 0); ASSERT(fd >= 0); /* * 1 0 -> fsf -> 2 0 -> fsf -> 2 -1 */ int ret=0; if (atEOT || atEOD) { errno = EIO; current_block = -1; return -1; } atBOT = false; Dmsg2(dbglevel+1, "fsf %i <= %i\n", current_file, last_file); if (next_FM > cur_FM) { /* not the last file */ lseek(fd, next_FM, SEEK_SET); read_fm(VT_READ_EOF); current_file++; atEOF = true; ret = 0; } else if (atEOF) { /* last file mark */ current_block=-1; errno = EIO; atEOF = false; atEOD = true; } else { /* last file, but no at the end */ fsr(100000); Dmsg0(dbglevel, "Try to FSF after EOT\n"); errno = EIO; current_file = last_file ; current_block = -1; atEOD=true; ret = -1; } return ret; }
int vtape::d_open(const char *pathname, int flags, int mode) { Dmsg2(dbglevel, "vtape::d_open(%s, %i)\n", pathname, flags); online = true; /* assume that drive contains a tape */ struct stat statp; if (stat(pathname, &statp) != 0) { fd = -1; Dmsg1(dbglevel, "Can't stat on %s\n", pathname); if (flags & O_NONBLOCK) { online = false; fd = ::open("/dev/null", O_CREAT | O_RDWR | O_LARGEFILE, 0600); } } else { fd = ::open(pathname, O_CREAT | O_RDWR | O_LARGEFILE, 0600); } if (fd < 0) { errno = ENOMEDIUM; return -1; } file_block = 0; current_block = 0; current_file = 0; cur_FM = next_FM = last_FM = 0; needEOF = false; atBOT = true; atEOT = atEOD = false; /* If the vtape is empty, start by writing a EOF */ if (online && !read_fm(VT_READ_EOF)) { lseek(fd, 0, SEEK_SET); /* rewind */ cur_FM = next_FM = last_FM = 0; /* reset */ weof(); /* write the first EOF */ last_file = current_file=0; } return fd; }
/* Redefine DEVICE virtual function */ int vtape::d_open(const char *pathname, int uflags) { Dmsg2(dbglevel, "vtape::d_open(%s, %i)\n", pathname, uflags); online = true; /* assume that drive contains a tape */ struct flock lock; struct stat statp; if (stat(pathname, &statp) != 0) { fd = -1; Dmsg1(dbglevel, "Can't stat on %s\n", pathname); if (uflags & O_NONBLOCK) { online = false; fd = ::open("/dev/null", O_RDWR | O_LARGEFILE, 0600); } } else { fd = ::open(pathname, O_RDWR | O_LARGEFILE, 0600); } if (fd < 0) { berrno be; Dmsg2(0, "Unable to open vtape device %s ERR=%s\n", pathname, be.bstrerror()); errno = ENOMEDIUM; return -1; } lockfile = (char *)malloc(strlen(pathname) + 3); strcpy(lockfile, pathname); strcat(lockfile, ".l"); lockfd = ::open(lockfile, O_CREAT | O_RDWR | O_LARGEFILE, 0600); if (lockfd < 0) { berrno be; Dmsg2(0, "Unable to open vtape device lock %s ERR=%s\n", lockfile, be.bstrerror()); } else { lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; lock.l_pid = getpid(); ASSERT(fcntl(lockfd, F_SETLK, &lock) != -1); } file_block = 0; current_block = 0; current_file = 0; cur_FM = next_FM = last_FM = 0; needEOF = false; atBOT = true; atEOT = atEOD = false; /* If the vtape is empty, start by writing a EOF */ if (online && !read_fm(VT_READ_EOF)) { lseek(fd, 0, SEEK_SET); /* rewind */ cur_FM = next_FM = last_FM = 0; /* reset */ weof(); /* write the first EOF */ last_file = current_file=0; } return fd; }
void Rename_RST_SET() { read_fm(Rename_scrd,1); read_fm(Rename_sset[1],Rename_scrd); }
int vtape::tape_op(struct mtop *mt_com) { int result=0; int count = mt_com->mt_count; if (!online) { errno = ENOMEDIUM; return -1; } switch (mt_com->mt_op) { case MTRESET: case MTNOP: case MTSETDRVBUFFER: break; default: case MTRAS1: case MTRAS2: case MTRAS3: case MTSETDENSITY: errno = ENOTTY; result = -1; break; case MTFSF: /* Forward space over mt_count filemarks. */ do { result = fsf(); } while (--count > 0 && result == 0); break; case MTBSF: /* Backward space over mt_count filemarks. */ do { result = bsf(); } while (--count > 0 && result == 0); break; case MTFSR: /* Forward space over mt_count records (tape blocks). */ /* file number = 1 block number = 0 file number = 1 block number = 1 mt: /dev/lto2: Erreur d'entree/sortie file number = 2 block number = 0 */ /* tester si on se trouve a la fin du fichier */ result = fsr(mt_com->mt_count); break; case MTBSR: /* Backward space over mt_count records (tape blocks). */ result = bsr(mt_com->mt_count); break; case MTWEOF: /* Write mt_count filemarks. */ do { result = weof(); } while (result == 0 && --count > 0); break; case MTREW: /* Rewind. */ Dmsg0(dbglevel, "rewind vtape\n"); check_eof(); atEOF = atEOD = false; atBOT = true; current_file = 0; current_block = 0; lseek(fd, 0, SEEK_SET); result = !read_fm(VT_READ_EOF); break; case MTOFFL: /* put tape offline */ result = offline(); break; case MTRETEN: /* Re-tension tape. */ result = 0; break; case MTBSFM: /* not used by bareos */ errno = EIO; result = -1; break; case MTFSFM: /* not used by bareos */ errno = EIO; result = -1; break; case MTEOM:/* Go to the end of the recorded media (for appending files). */ while (next_FM) { lseek(fd, next_FM, SEEK_SET); if (read_fm(VT_READ_EOF)) { current_file++; } } boffset_t l; while (::read(fd, &l, sizeof(l)) > 0) { if (l) { lseek(fd, l, SEEK_CUR); } else { ASSERT(0); } Dmsg0(dbglevel, "skip 1 block\n"); } current_block = -1; atEOF = false; atEOD = true; /* file number = 3 block number = -1 */ /* Can be at EOM */ break; case MTERASE: /* not used by bareos */ atEOD = true; atEOF = false; atEOT = false; current_file = 0; current_block = -1; lseek(fd, 0, SEEK_SET); read_fm(VT_READ_EOF); truncate_file(); break; case MTSETBLK: break; case MTSEEK: break; case MTTELL: break; case MTFSS: break; case MTBSS: break; case MTWSM: break; case MTLOCK: break; case MTUNLOCK: break; case MTLOAD: break; case MTUNLOAD: break; case MTCOMPRESSION: break; case MTSETPART: break; case MTMKPART: break; } return result == 0 ? 0 : -1; }
restore_bplatform_bin_file () { int rr; /* 0 */ read_fm( rr, 1 ); read_fm(vnbs,1); read_fm(ttms,1); read_fm(vad(1),vnbs+1); restore_alloc ( vad(vnbs+1) ); read_fm(mmts[1],vad(vnbs+1)); read_fm(vtt(1),vnbs); read_fm(tmbs[1],ttms); mtt(vnbs+1,0); /* !!! */ mad(vnbs+2,max_mem); /* !!! */ /* 1 */ read_fm( rr, 1 ); read_fm(sym,1); read_fm(stri[1],sym); read_fm(lexi[1],sym); read_fm(edit[1],sym); read_fm(prio[1],sym); read_fm(righ[1],sym); read_fm(clos[1],sym); read_fm(arity[1],sym); /* 2 */ read_fm( rr, 1 ); read_fm(hcod[1],max_sym); /* 3 */ read_fm( rr, 1 ); read_fm(rul,1); read_fm(ant[1],rul); read_fm(cns[1],rul); read_fm(rth[1],rul); read_fm(num[1],rul); read_fm(trl[1],rul); read_fm(lsb[1],rul); read_fm(pvd[1],rul); read_fm(sts[1],rul); /* 4 */ read_fm( rr, 1 ); read_fm(rttm,1); read_fm(rtmb[1],rttm); /* 7 */ read_fm( rr, 1 ); read_fm(the,1); read_fm(tru[1],the); read_fm(tna[1],the); read_fm(tnm[1],the); read_fm(ttc[1],the); read_fm(tft[1],the); /* 8 */ read_fm( rr, 1 ); read_fm(tttm,1); read_fm(ttmb[1],tttm); /* 9 */ read_fm( rr, 1 ); read_fm(ttdi,1); read_fm(tdir[1],ttdi); }
/* * When a filemark is encountered while reading, the following happens. If * there are data remaining in the buffer when the filemark is found, the * buffered data is returned. The next read returns zero bytes. The following * read returns data from the next file. The end of recorded data is signaled * by returning zero bytes for two consecutive read calls. The third read * returns an error. */ ssize_t vtape::d_read(int, void *buffer, size_t count) { ASSERT(online); ASSERT(current_file >= 0); ssize_t nb; uint32_t s; Dmsg2(dbglevel*2, "read %i:%i\n", current_file, current_block); if (atEOT || atEOD) { errno = EIO; return -1; } if (atEOF) { if (!next_FM) { atEOD = true; atEOF = false; current_block=-1; return 0; } atEOF=false; } check_eof(); atEOD = atBOT = false; /* reading size of data */ nb = ::read(fd, &s, sizeof(uint32_t)); if (nb <= 0) { atEOF = true; /* TODO: check this */ return 0; } if (s > count) { /* not enough buffer to read block */ Dmsg2(dbglevel, "Need more buffer to read next block %i > %i\n",s,count); lseek(fd, s, SEEK_CUR); errno = ENOMEM; return -1; } if (!s) { /* EOF */ atEOF = true; if (read_fm(VT_SKIP_EOF)) { current_file++; } return 0; } /* reading data itself */ nb = ::read(fd, buffer, s); if (nb != (ssize_t)s) { /* read error */ errno=EIO; atEOT=true; current_block = -1; Dmsg0(dbglevel, "EOT during reading\n"); return -1; } /* read ok */ if (current_block >= 0) { current_block++; } return nb; }
/* * BSR + EOF => begin of EOF + EIO * BSR + BSR + EOF => last block * current_block = -1 */ int vtape::bsr(int count) { ASSERT(online); ASSERT(current_file >= 0); ASSERT(count == 1); ASSERT(fd >= 0); check_eof(); if (!count) { return 0; } int ret=0; int last_f=0; int last_b=0; boffset_t last=-1, last2=-1; boffset_t orig = lseek(fd, 0, SEEK_CUR); int orig_f = current_file; int orig_b = current_block; Dmsg4(dbglevel, "bsr(%i) cur_blk=%i orig=%lli cur_FM=%lli\n", count, current_block, orig, cur_FM); /* begin of tape, do nothing */ if (atBOT) { errno = EIO; return -1; } /* at EOF 0:-1 BOT=0 EOD=0 EOF=0 ERR: Input/output error */ if (atEOF) { lseek(fd, cur_FM, SEEK_SET); atEOF = false; if (current_file > 0) { current_file--; } current_block=-1; errno = EIO; return -1; } /* * First, go to cur/last_FM and read all blocks to find the good one */ if (cur_FM == orig) { /* already just before EOF */ lseek(fd, last_FM, SEEK_SET); } else { lseek(fd, cur_FM, SEEK_SET); } ret = read_fm(VT_READ_EOF); do { if (!atEOF) { last2 = last; /* keep track of the 2 last blocs position */ last = lseek(fd, 0, SEEK_CUR); last_f = current_file; last_b = current_block; Dmsg6(dbglevel, "EOF=%i last2=%lli last=%lli < orig=%lli %i:%i\n", atEOF, last2, last, orig, current_file, current_block); } ret = fsr(1); } while ((lseek(fd, 0, SEEK_CUR) < orig) && (ret == 0)); if (last2 > 0 && atEOF) { /* we take the previous position */ lseek(fd, last2, SEEK_SET); current_file = last_f; current_block = last_b - 1; Dmsg3(dbglevel, "1 set offset2=%lli %i:%i\n", last, current_file, current_block); } else if (last > 0) { lseek(fd, last, SEEK_SET); current_file = last_f; current_block = last_b; Dmsg3(dbglevel, "2 set offset=%lli %i:%i\n", last, current_file, current_block); } else { lseek(fd, orig, SEEK_SET); current_file = orig_f; current_block = orig_b; return -1; } Dmsg2(dbglevel, "bsr %i:%i\n", current_file, current_block); errno=0; atEOT = atEOF = atEOD = false; atBOT = (lseek(fd, 0, SEEK_CUR) - (sizeof(uint32_t)+2*sizeof(boffset_t))) == 0; if (orig_b == -1) { current_block = orig_b; } return 0; }
void CfgDepBase_RST_FNC() { read_fm(CfgDepBase_Vfnc[1],CfgDepBase_VffncP2); }
void Rename_RST_FNC() { read_fm(Rename_Vfnc[1],Rename_VfncP2); }
void Rename_RSTN_NVAR() { read_fm(Rename_Nscv,1); Rename_Nscv = ntohl ( Rename_Nscv ); }
void Rename_RST_NVAR() { read_fm(Rename_Nscv,1); }