2 ===================================================================
3 --- src/baconfig.h (revision 7116)
4 +++ src/baconfig.h (working copy)
6 void InitWinAPIWrapper();
8 #define OSDependentInit() InitWinAPIWrapper()
9 -#define tape_open win32_tape_open
10 -#define tape_ioctl win32_tape_ioctl
11 -#define tape_read win32_tape_read
12 -#define tape_write win32_tape_write
13 -#define tape_close win32_tape_close
14 -#define IS_TAPE(x) S_ISCHR(x)
20 #define OSDependentInit()
22 -#if defined(USE_FAKETAPE)
23 -# define tape_open faketape_open
24 -# define tape_ioctl faketape_ioctl
25 -# define tape_read faketape_read
26 -# define tape_write faketape_write
27 -# define tape_close faketape_close
28 -# define IS_TAPE(x) S_ISREG(x)
29 -#else /* UNIX && !FAKETAPE */
30 -# define tape_open ::open
31 -# define tape_ioctl ::ioctl
32 -# define tape_read ::read
33 -# define tape_write ::write
34 -# define tape_close ::close
35 -# define IS_TAPE(x) S_ISCHR(x)
38 #endif /* HAVE_WIN32 */
41 Index: src/stored/stored.h
42 ===================================================================
43 --- src/stored/stored.h (revision 7116)
44 +++ src/stored/stored.h (working copy)
46 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
50 -# include "faketape.h"
52 +#include "faketape.h"
55 /* Daemon globals from stored.c */
56 extern STORES *me; /* "Global" daemon resource */
57 extern bool forge_on; /* proceed inspite of I/O errors */
58 Index: src/stored/stored_conf.c
59 ===================================================================
60 --- src/stored/stored_conf.c (revision 7116)
61 +++ src/stored/stored_conf.c (working copy)
66 + {"faketape", B_FAKETAPE_DEV},
70 Index: src/stored/btape.c
71 ===================================================================
72 --- src/stored/btape.c (revision 7116)
73 +++ src/stored/btape.c (working copy)
74 @@ -2504,11 +2504,7 @@
75 Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
78 - if (dev->is_tape()) {
79 - stat = tape_write(dev->fd(), block->buf, block->buf_len);
81 - stat = write(dev->fd(), block->buf, block->buf_len);
83 + stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
84 if (stat == (int)block->buf_len) {
85 if ((block_num++ % 100) == 0) {
87 Index: src/stored/dev.c
88 ===================================================================
89 --- src/stored/dev.c (revision 7116)
90 +++ src/stored/dev.c (working copy)
93 if (S_ISDIR(statp.st_mode)) {
94 device->dev_type = B_FILE_DEV;
95 - } else if (IS_TAPE(statp.st_mode)) { /* char device or fake tape */
96 + } else if (S_ISCHR(statp.st_mode)) {
97 device->dev_type = B_TAPE_DEV;
98 } else if (S_ISFIFO(statp.st_mode)) {
99 device->dev_type = B_FIFO_DEV;
101 + /* must set DeviceType = Faketape
102 + * in normal mode, autodetection is disabled
104 + } else if (S_ISREG(statp.st_mode)) {
105 + device->dev_type = B_FAKETAPE_DEV;
107 } else if (!(device->cap_bits & CAP_REQMOUNT)) {
108 Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory\n"
109 " or have RequiresMount=yes for DVD. st_mode=%x\n"),
111 dev->drive_index = device->drive_index;
112 dev->autoselect = device->autoselect;
113 dev->dev_type = device->dev_type;
114 + dev->init_backend();
115 if (dev->is_tape()) { /* No parts on tapes */
116 dev->max_part_size = 0;
122 +/* Choose the right backend */
123 +void DEVICE::init_backend()
125 + if (is_faketape()) {
126 + d_open = faketape_open;
127 + d_write = faketape_write;
128 + d_close = faketape_close;
129 + d_ioctl = faketape_ioctl;
130 + d_read = faketape_read;
133 + } else if (is_tape()) {
134 + d_open = win32_tape_open;
135 + d_write = win32_tape_write;
136 + d_close = win32_tape_close;
137 + d_ioctl = win32_tape_ioctl;
138 + d_read = win32_tape_read;
151 * Open the device with the operating system and
152 * initialize buffer pointers.
154 if (openmode == omode) {
164 Dmsg0(100, "Close fd for mode change.\n");
165 preserve = state & (ST_LABEL|ST_APPEND|ST_READ);
167 #if defined(HAVE_WIN32)
170 - if ((m_fd = tape_open(dev_name, mode)) < 0) {
171 + if ((m_fd = d_open(dev_name, mode)) < 0) {
176 /* If busy retry each second for max_open_wait seconds */
178 /* Try non-blocking open */
179 - m_fd = tape_open(dev_name, mode+O_NONBLOCK);
180 + m_fd = d_open(dev_name, mode+O_NONBLOCK);
184 @@ -390,10 +422,10 @@
185 mt_com.mt_op = MTREW;
187 /* rewind only if dev is a tape */
188 - if (is_tape() && (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
189 + if (is_tape() && (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
191 dev_errno = errno; /* set error status from rewind */
195 Dmsg2(100, "Rewind error on %s close: ERR=%s\n", print_name(),
196 be.bstrerror(dev_errno));
200 /* Got fd and rewind worked, so we must have medium in drive */
202 - m_fd = tape_open(dev_name, mode); /* open normally */
204 + m_fd = d_open(dev_name, mode); /* open normally */
210 Dmsg1(100, "open failed: %s", errmsg);
211 /* Use system close() */
216 part_size = filestat.st_size;
218 * retrying every 5 seconds.
220 for (i=max_rewind_wait; ; i -= 5) {
221 - if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
222 + if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
225 if (i == max_rewind_wait) {
229 int open_mode = openmode;
233 open(dcr, open_mode);
239 - if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
240 + if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
242 clrerror(mt_com.mt_op);
243 Dmsg1(50, "ioctl error: %s\n", be.bstrerror());
244 @@ -1030,7 +1062,7 @@
246 Pmsg0(-20,_(" Bacula status:"));
247 Pmsg2(-20,_(" file=%d block=%d\n"), dev->file, dev->block_num);
248 - if (tape_ioctl(dev->fd(), MTIOCGET, (char *)&mt_stat) < 0) {
249 + if (dev->d_ioctl(dev->fd(), MTIOCGET, (char *)&mt_stat) < 0) {
251 dev->dev_errno = errno;
252 Mmsg2(dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
253 @@ -1157,7 +1189,7 @@
255 mt_com.mt_op = MTLOAD;
257 - if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
258 + if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
260 dev->dev_errno = errno;
261 Mmsg2(dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"),
262 @@ -1188,7 +1220,7 @@
264 mt_com.mt_op = MTOFFL;
266 - if (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
267 + if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
270 Mmsg2(errmsg, _("ioctl MTOFFL error on %s. ERR=%s.\n"),
271 @@ -1263,7 +1295,7 @@
273 mt_com.mt_op = MTFSF;
274 mt_com.mt_count = num;
275 - stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
276 + stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
278 my_errno = errno; /* save errno */
279 } else if ((os_file=get_os_tape_file()) < 0) {
280 @@ -1344,7 +1376,7 @@
283 Dmsg0(100, "Doing MTFSF\n");
284 - stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
285 + stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
286 if (stat < 0) { /* error => EOT */
289 @@ -1418,7 +1450,7 @@
291 mt_com.mt_op = MTBSF;
292 mt_com.mt_count = num;
293 - stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
294 + stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
298 @@ -1458,7 +1490,7 @@
299 Dmsg1(100, "fsr %d\n", num);
300 mt_com.mt_op = MTFSR;
301 mt_com.mt_count = num;
302 - stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
303 + stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
307 @@ -1517,7 +1549,7 @@
309 mt_com.mt_op = MTBSR;
310 mt_com.mt_count = num;
311 - stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
312 + stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
316 @@ -1533,7 +1565,7 @@
318 mt_com.mt_op = MTLOCK;
320 - tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
321 + d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
325 @@ -1543,7 +1575,7 @@
327 mt_com.mt_op = MTUNLOCK;
329 - tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
330 + d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
334 @@ -1668,7 +1700,7 @@
336 mt_com.mt_op = MTWEOF;
337 mt_com.mt_count = num;
338 - stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
339 + stat = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
343 @@ -1799,7 +1831,7 @@
344 /* Found on Solaris */
347 - tape_ioctl(m_fd, MTIOCLRERR);
348 + d_ioctl(m_fd, MTIOCLRERR);
349 Dmsg0(200, "Did MTIOCLRERR\n");
352 @@ -1812,7 +1844,7 @@
353 union mterrstat mt_errstat;
354 Dmsg2(200, "Doing MTIOCERRSTAT errno=%d ERR=%s\n", dev_errno,
355 be.bstrerror(dev_errno));
356 - tape_ioctl(m_fd, MTIOCERRSTAT, (char *)&mt_errstat);
357 + d_ioctl(m_fd, MTIOCERRSTAT, (char *)&mt_errstat);
361 @@ -1823,7 +1855,7 @@
362 mt_com.mt_op = MTCSE;
364 /* Clear any error condition on the tape */
365 - tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
366 + d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
367 Dmsg0(200, "Did MTCSE\n");
370 @@ -1860,10 +1892,8 @@
381 /* Clean up device packet so it can be reused */
382 @@ -2262,11 +2292,7 @@
386 - if (this->is_tape()) {
387 - read_len = tape_read(m_fd, buf, len);
389 - read_len = ::read(m_fd, buf, len);
391 + read_len = d_read(m_fd, buf, len);
393 last_tick = get_timer_count();
395 @@ -2287,11 +2313,7 @@
399 - if (this->is_tape()) {
400 - write_len = tape_write(m_fd, buf, len);
402 - write_len = ::write(m_fd, buf, len);
404 + write_len = d_write(m_fd, buf, len);
406 last_tick = get_timer_count();
408 @@ -2317,7 +2339,7 @@
409 struct mtget mt_stat;
411 if (has_cap(CAP_MTIOCGET) &&
412 - tape_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) {
413 + d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) {
414 return mt_stat.mt_fileno;
417 @@ -2442,7 +2464,7 @@
418 mt_com.mt_op = MTSETBLK;
420 Dmsg0(100, "Set block size to zero\n");
421 - if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
422 + if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
423 dev->clrerror(MTSETBLK);
426 @@ -2458,7 +2480,7 @@
427 mt_com.mt_count |= MT_ST_FAST_MTEOM;
429 Dmsg0(100, "MTSETDRVBUFFER\n");
430 - if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
431 + if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
432 dev->clrerror(MTSETDRVBUFFER);
435 @@ -2472,13 +2494,13 @@
436 dev->min_block_size == 0) { /* variable block mode */
437 mt_com.mt_op = MTSETBSIZ;
439 - if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
440 + if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
441 dev->clrerror(MTSETBSIZ);
443 /* Get notified at logical end of tape */
444 mt_com.mt_op = MTEWARN;
446 - if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
447 + if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
448 dev->clrerror(MTEWARN);
451 @@ -2491,7 +2513,7 @@
452 dev->min_block_size == 0) { /* variable block mode */
453 mt_com.mt_op = MTSETBSIZ;
455 - if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
456 + if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
457 dev->clrerror(MTSETBSIZ);
460 @@ -2502,7 +2524,7 @@
464 - if (tape_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
465 + if (dev->d_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
467 dev->dev_errno = errno; /* save errno */
468 Mmsg2(dev->errmsg, _("Unable to set eotmodel on device %s: ERR=%s\n"),
469 @@ -2519,7 +2541,7 @@
470 dev->min_block_size == 0) { /* variable block mode */
471 mt_com.mt_op = MTSRSZ;
473 - if (tape_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
474 + if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) {
475 dev->clrerror(MTSRSZ);
478 @@ -2531,7 +2553,7 @@
480 Dmsg0(100, "dev_get_os_pos\n");
481 return dev->has_cap(CAP_MTIOCGET) &&
482 - tape_ioctl(dev->fd(), MTIOCGET, (char *)mt_stat) == 0 &&
483 + dev->d_ioctl(dev->fd(), MTIOCGET, (char *)mt_stat) == 0 &&
484 mt_stat->mt_fileno >= 0;
487 Index: src/stored/faketape.c
488 ===================================================================
489 --- src/stored/faketape.c (revision 7116)
490 +++ src/stored/faketape.c (working copy)
492 #include "bacula.h" /* define 64bit file usage */
496 #include "faketape.h"
498 static int dbglevel = 100;
500 atEOF, atEOT, atEOD, atBOT);
503 -#endif /* USE_FAKETAPE */
504 Index: src/stored/dev.h
505 ===================================================================
506 --- src/stored/dev.h (revision 7116)
507 +++ src/stored/dev.h (working copy)
513 + B_FAKETAPE_DEV, /* change to B_TAPE_DEV after init */
517 /* Generic status bits returned from status_dev() */
518 @@ -307,11 +308,13 @@
519 int is_autochanger() const { return capabilities & CAP_AUTOCHANGER; }
520 int requires_mount() const { return capabilities & CAP_REQMOUNT; }
521 int is_removable() const { return capabilities & CAP_REM; }
522 - int is_tape() const { return dev_type == B_TAPE_DEV; }
523 + int is_tape() const { return (dev_type == B_TAPE_DEV ||
524 + dev_type == B_FAKETAPE_DEV); }
525 int is_file() const { return dev_type == B_FILE_DEV; }
526 int is_fifo() const { return dev_type == B_FIFO_DEV; }
527 int is_dvd() const { return dev_type == B_DVD_DEV; }
528 int is_vtl() const { return dev_type == B_VTL_DEV; }
529 + int is_faketape() const { return dev_type == B_FAKETAPE_DEV; }
530 int is_open() const { return m_fd >= 0; }
531 int is_offline() const { return state & ST_OFFLINE; }
532 int is_labeled() const { return state & ST_LABEL; }
534 uint32_t get_block_num() const { return block_num; };
535 int fd() const { return m_fd; };
537 + /* low level operations */
538 + void init_backend();
539 + int (*d_open)(const char *pathname, int flags, ...);
540 + int (*d_read)(int fd, void *buffer, unsigned int count);
541 + int (*d_write)(int fd, const void *buffer, unsigned int count);
542 + int (*d_close)(int fd);
543 + int (*d_ioctl)(int fd, unsigned long int request, ...);
546 * Locking and blocking calls
548 Index: src/stored/faketape.h
549 ===================================================================
550 --- src/stored/faketape.h (revision 7116)
551 +++ src/stored/faketape.h (working copy)
558 #define FTAPE_MAX_DRIVE 50
562 void check_eof() { if(needEOF) weof();};
564 bool read_fm(FT_READ_FM_MODE readfirst);
565 - void set_eot() { eot_count=0; atEOT=true;};
566 + void set_eot() { atEOT=true;};
571 int tape_pos(struct mtpos *mt_com);
574 -#endif /* USE_FAKETAPE */
575 #endif /* !FAKETAPE_H */
577 ===================================================================
578 --- src/version.h (revision 7116)
579 +++ src/version.h (working copy)
584 -//#define USE_FAKETAPE
585 +#define USE_FAKETAPE