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