- Document fixing tape file after crash (update Media set VolFiles=xx
where MediaId=yy; update status to append).
- Document fifo and | and <
+- Document g++ needed
Testing to do: (painful)
- blocksize recognition code.
For 1.29 release:
+- Priority job to go to top of list.
+- Add Bar code reading capabilities (new mtx-changer)
- Add include list to end of chain in findlib
- Look into Pruning/purging problems or why there seem to
be so many files listed each night.
applied for the backup.
====================================
+=========================================
+Proposal by Bill Sellers
+
+Return-Path: <w.a.sellers@larc.nasa.gov>
+Received: from post.larc.nasa.gov (post.larc.nasa.gov [128.155.4.45]) by matou.sibbald.com (8.11.6/8.11.6) with ESMTP id h0ELUIm07622 for <kern@sibbald.com>; Tue, 14 Jan 2003 22:30:18 +0100
+Received: from Baron.larc.nasa.gov (baron.larc.nasa.gov [128.155.40.132]) by post.larc.nasa.gov (pohub4.6) with ESMTP id QAA09768 for <kern@sibbald.com>; Tue, 14 Jan 2003 16:30:14 -0500 (EST)
+Message-Id: <5.1.0.14.2.20030114153452.028dbae8@pop.larc.nasa.gov>
+X-Sender: w.a.sellers@pop.larc.nasa.gov
+X-Mailer: QUALCOMM Windows Eudora Version 5.1
+Date: Tue, 14 Jan 2003 16:30:18 -0500
+To: Kern Sibbald <kern@sibbald.com>
+From: Bill Sellers <w.a.sellers@larc.nasa.gov>
+Subject: Re: [Bacula-users] Bacula remote storage?
+In-Reply-To: <1042565382.1845.177.camel@rufus>
+References: <5.1.0.14.2.20030114113004.0293a210@pop.larc.nasa.gov> <5.1.0.14.2.20030113170650.028dad88@pop.larc.nasa.gov> <5.1.0.14.2.20030113170650.028dad88@pop.larc.nasa.gov> <5.1.0.14.2.20030114113004.0293a210@pop.larc.nasa.gov>
+Mime-Version: 1.0
+Content-Type: text/plain; charset="us-ascii"; format=flowed
+X-Annoyance-Filter-Junk-Probability: 0
+X-Annoyance-Filter-Classification: Mail
+At 06:29 PM 1/14/2003 +0100, you wrote:
+>Hello Bill,
+>
+>Well, if you cannot put a Bacula client on the machine,
+>then it is a big problem. If you know of some software
+>that can do what you want, let me know, because I
+>really just don't know how to do it -- at least not
+>directly.
+
+
+Hi Kern,
+
+We have been able to get Amanda to use the HSM as a storage
+device. Someone here wrote a driver for Amanda. BUT, Amanda doesn't
+handle Windows systems very well (or at all without Samba). So I am
+looking for a backup system that has a Windows client. I really like the
+Windows integration of Bacula.
+
+From the command line, its rather trivial to move the data around. We use
+something like-
+
+tar cf - ./files | gzip -c | rsh hsm dd of=path/file.tgz
+
+or if you use GNU tar:
+
+tar czf hsm:path/file.tgz ./files
+
+One idea for you to consider; Sendmail offers pipes in the aliases file;
+(mailpipe: "|/usr/bin/vacation root") and Perl supports pipes in the
+"open" statement (open FILE, "|/bin/nroff -man";) Could you could make a
+pipe available, as a storage device? Then we could use any command that
+handles stdin as a storage destination.
+
+Something like-
+
+Storage {
+ Name = HSM-RSH
+ Address = hsm
+ #Password is not used in rsh, but might be used in ftp.
+ Device = "| gzip -c | rsh hsm dd of=path/file.tgz"
+ MediaType = Pipe
+}
+
+Storage {
+ Name = HSM-FTP
+ Address = hsm
+ Password = "foobar&-"
+ Device = "| ncftpput -c hsm /path/file.bacula"
+ MediaType = Pipe
+}
+
+>If you have some local storage available, you could
+>use Bacula to backup to disk volumes, then use some
+>other software (ftp, scp) to move them to the HSM
+>machine. However, this is a bit kludgy.
+
+
+It is, but maybe worth a try. Is there some function in Bacula to put
+variables in filenames? i.e. backup.2003-01-15.root
+
+Thanks!
+Bill
+
+
+
+---
+Bill Sellers
+w.a.sellers@larc.nasa.gov
+
+==============================================
+
Done: (see kernsdone for more)
#define Dmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13)
#endif /* DEBUG */
+#ifdef TRACE_FILE
+#define Tmsg0(lvl, msg) t_msg(__FILE__, __LINE__, lvl, msg)
+#define Tmsg1(lvl, msg, a1) t_msg(__FILE__, __LINE__, lvl, msg, a1)
+#define Tmsg2(lvl, msg, a1, a2) t_msg(__FILE__, __LINE__, lvl, msg, a1, a2)
+#define Tmsg3(lvl, msg, a1, a2, a3) t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3)
+#define Tmsg4(lvl, msg, arg1, arg2, arg3, arg4) t_msg(__FILE__, __LINE__, lvl, msg, arg1, arg2, arg3, arg4)
+#define Tmsg5(lvl, msg, a1, a2, a3, a4, a5) t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5)
+#define Tmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6)
+#define Tmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7)
+#define Tmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8)
+#define Tmsg9(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9) t_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9)
+#define Tmsg10(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) t_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
+#define Tmsg11(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) t_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)
+#define Tmsg12(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) t_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
+#define Tmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) t_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13)
+#else
+#define Tmsg0(lvl, msg)
+#define Tmsg1(lvl, msg, a1)
+#define Tmsg2(lvl, msg, a1, a2)
+#define Tmsg3(lvl, msg, a1, a2, a3)
+#define Tmsg4(lvl, msg, arg1, arg2, arg3, arg4)
+#define Tmsg5(lvl, msg, a1, a2, a3, a4, a5)
+#define Tmsg6(lvl, msg, a1, a2, a3, a4, a5, a6)
+#define Tmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7)
+#define Tmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8)
+#define Tmsg11(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)
+#define Tmsg12(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
+#define Tmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13)
+#endif /* TRACE_FILE */
+
+
/* Messages that are printed (uses d_msg) */
#define Pmsg0(lvl, msg) d_msg(__FILE__, __LINE__, lvl, msg)
*/
/*
- Copyright (C) 2002 Kern Sibbald and John Walker
+ Copyright (C) 2002-2003 Kern Sibbald and John Walker
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
/* Count Files to be deleted */
strcpy(query, cnt_DelCand);
Dmsg1(100, "select sql=%s\n", query);
+ cnt.count = 0;
if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) {
bsendmsg(ua, "%s", db_strerror(ua->db));
Dmsg0(050, "Count failed\n");
FILE *con_fd = NULL;
brwlock_t con_lock;
+#ifdef TRACE_FILE
+FILE *trace_fd = NULL;
+#endif
+
/* Forward referenced functions */
/* Imported functions */
memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
}
Dmsg2(050, "Copy message resource 0x%x to 0x%x\n", msg, temp_chain);
+
}
/* Initialize so that the console (User Agent) can
free(exename);
exename = NULL;
}
+ if (trace_fd) {
+ fclose(trace_fd);
+ trace_fd = NULL;
+ }
}
void dispatch_message(void *vjcr, int type, int level, char *msg)
{
DEST *d;
- char cmd[MAXSTRING];
+ char dt[MAX_TIME_LENGTH];
POOLMEM *mcmd;
JCR *jcr = (JCR *) vjcr;
int len;
Dmsg2(200, "Enter dispatch_msg type=%d msg=%s\n", type, msg);
if (type == M_ABORT || type == M_ERROR_TERM) {
- fprintf(stdout, "%s", msg); /* print this here to INSURE that it is printed */
+ fputs(msg, stdout); /* print this here to INSURE that it is printed */
}
/* Now figure out where to send the message */
if (con_fd) {
Pw(con_lock); /* get write lock on console message file */
errno = 0;
- bstrftime(cmd, sizeof(cmd), time(NULL));
- len = strlen(cmd);
- cmd[len++] = ' ';
- fwrite(cmd, len, 1, con_fd);
+ bstrftime(dt, sizeof(dt), time(NULL));
+ len = strlen(dt);
+ dt[len++] = ' ';
+ fwrite(dt, len, 1, con_fd);
len = strlen(msg);
- if (len > 0 && msg[len-1] != '\n') {
- msg[len++] = '\n';
- msg[len] = 0;
+ if (len > 0) {
+ fwrite(msg, len, 1, con_fd);
+ if (msg[len-1] != '\n') {
+ fwrite("\n", 2, 1, con_fd);
+ }
+ } else {
+ fwrite("\n", 2, 1, con_fd);
}
- fwrite(msg, len, 1, con_fd);
fflush(con_fd);
console_msg_pending = TRUE;
Vw(con_lock);
case MD_STDOUT:
Dmsg1(400, "STDOUT for following msg: %s", msg);
if (type != M_ABORT && type != M_ERROR_TERM) /* already printed */
- fprintf(stdout, "%s", msg);
+ fputs(msg, stdout);
break;
case MD_STDERR:
Dmsg1(400, "STDERR for following msg: %s", msg);
- fprintf(stderr, "%s", msg);
+ fputs(msg, stderr);
break;
default:
break;
void
d_msg(char *file, int line, int level, char *fmt,...)
{
- char buf[2000];
+ char buf[5000];
int i;
va_list arg_ptr;
int details = TRUE;
}
if (level <= debug_level) {
+#ifdef FULL_LOCATION
+ if (details) {
+ i= sprintf(buf, "%s: %s:%d ", my_name, file, line);
+ } else {
+ i = 0;
+ }
+#else
+ i = 0;
+#endif
+ va_start(arg_ptr, fmt);
+ bvsnprintf(buf+i, sizeof(buf)-i, (char *)fmt, arg_ptr);
+ va_end(arg_ptr);
+
+ fputs(buf, stdout);
+ }
+}
+
+
+/*********************************************************************
+ *
+ * subroutine writes a debug message to the trace file if the level number
+ * is less than or equal the debug_level. File and line numbers
+ * are included for more detail if desired, but not currently
+ * printed.
+ *
+ * If the level is negative, the details of file and line number
+ * are not printed.
+ */
+void
+t_msg(char *file, int line, int level, char *fmt,...)
+{
+ char buf[5000];
+ int i;
+ va_list arg_ptr;
+ int details = TRUE;
+
+ return;
+
+ if (level < 0) {
+ details = FALSE;
+ level = -level;
+ }
+
+ if (level <= debug_level) {
+ if (!trace_fd) {
+ trace_fd = fopen("bacula.trace", "a+");
+ if (!trace_fd) {
+ Emsg1(M_ABORT, 0, _("Cannot open bacula.trace: ERR=%s\n"),
+ strerror(errno));
+ }
+ }
+
#ifdef FULL_LOCATION
if (details) {
sprintf(buf, "%s: %s:%d ", my_name, file, line);
bvsnprintf(buf+i, sizeof(buf)-i, (char *)fmt, arg_ptr);
va_end(arg_ptr);
- fprintf(stdout, "%s", buf);
+ fputs(buf, trace_fd);
+ fflush(trace_fd);
}
}
+
/* *********************************************************
*
* print an error message
void
e_msg(char *file, int line, int type, int level, char *fmt,...)
{
- char buf[2000];
+ char buf[5000];
va_list arg_ptr;
int i;
* We always report M_ABORT and M_ERROR_TERM
*/
if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) &&
- !bit_is_set(type, daemon_msgs->send_msg)))
+ !bit_is_set(type, daemon_msgs->send_msg))) {
return; /* no destination */
+ }
switch (type) {
case M_ABORT:
sprintf(buf, "%s: ABORTING due to ERROR in %s:%d\n",
* Check if we have a message destination defined.
* We always report M_ABORT and M_ERROR_TERM
*/
- if ((type != M_ABORT && type != M_ERROR_TERM) && msgs && !bit_is_set(type, msgs->send_msg)) {
+
+/*
+ * Tmsg5(000, "jcr=%x msgs=%x type=%d send_msg=%x *msg=%x\n",
+ * jcr, msgs, type, msgs->send_msg, (int)msgs->send_msg[0]);
+ */
+
+ if ((type != M_ABORT && type != M_ERROR_TERM) && msgs &&
+ !bit_is_set(type, msgs->send_msg)) {
Dmsg1(200, "No bit set for type %d\n", type);
return; /* no destination */
}
init_dev(DEVICE *dev, DEVRES *device)
{
struct stat statp;
- int tape;
+ int tape, fifo;
int errstat;
/* Check that device is available */
return NULL;
}
tape = FALSE;
+ fifo = FALSE;
if (S_ISDIR(statp.st_mode)) {
tape = FALSE;
} else if (S_ISCHR(statp.st_mode)) {
tape = TRUE;
+ } else if (S_ISFIFO(statp.st_mode)) {
+ fifo = TRUE;
} else {
if (dev) {
dev->dev_errno = ENODEV;
} else {
memset(dev, 0, sizeof(DEVICE));
}
- if (tape) {
- dev->state |= ST_TAPE;
- }
/* Copy user supplied device parameters from Resource */
dev->dev_name = get_memory(strlen(device->device_name)+1);
dev->max_open_wait = device->max_open_wait;
dev->device = device;
+ if (tape) {
+ dev->state |= ST_TAPE;
+ } else if (fifo) {
+ dev->state |= ST_FIFO;
+ dev->capabilities |= CAP_STREAM; /* set stream device */
+ } else {
+ dev->state |= ST_FILE;
+ }
+
if (dev->max_block_size > 1000000) {
Emsg3(M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
dev->max_block_size, dev->dev_name, DEFAULT_BLOCK_SIZE);
Dmsg3(29, "open_dev: tape=%d dev_name=%s vol=%s\n", dev_is_tape(dev),
dev->dev_name, dev->VolCatInfo.VolCatName);
dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
- if (dev->state & ST_TAPE) {
+ if (dev->state & (ST_TAPE|ST_FIFO)) {
int timeout;
Dmsg0(29, "open_dev: device is tape\n");
if (mode == READ_WRITE) {
}
break;
}
- } else {
+ } else if (dev->state & ST_FILE) {
if (lseek(dev->fd, (off_t)0, SEEK_SET) < 0) {
dev->dev_errno = errno;
Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
dev->state &= ~(ST_EOF); /* remove EOF flags */
dev->block_num = dev->file = 0;
dev->file_addr = 0;
+ if (dev->state & (ST_FIFO | ST_PROG)) {
+ return 1;
+ }
if (!(dev->state & ST_TAPE)) {
pos = lseek(dev->fd, (off_t)0, SEEK_END);
// Dmsg1(000, "====== Seek to %lld\n", pos);
}
/*
- * Set the position of the device.
+ * Set the position of the device -- only for files
+ * For other devices, there is no generic way to do it.
* Returns: 1 on succes
* 0 on error
*/
int update_pos_dev(DEVICE *dev)
{
-#ifdef xxxx
- struct mtget mt_stat;
-#endif
off_t pos;
int stat = 0;
}
/* Find out where we are */
- if (!(dev->state & ST_TAPE)) {
+ if (dev->state & ST_FILE) {
dev->file = 0;
dev->file_addr = 0;
pos = lseek(dev->fd, (off_t)0, SEEK_CUR);
}
return stat;
}
-
-#ifdef REALLY_IMPLEMENTED
- if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
- Dmsg1(50, "MTIOCGET error: %s\n", strerror(dev->dev_errno));
- dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
- dev->dev_name, strerror(dev->dev_errno));
- } else {
- stat = 1;
- }
- return stat;
-#endif
return 1;
}
free_pool_memory(dev->errmsg);
dev->errmsg = NULL;
}
-#ifdef NEW_LOCK
- rwl_destroy(&dev->lock);
-#endif
pthread_mutex_destroy(&dev->mutex);
pthread_cond_destroy(&dev->wait);
pthread_cond_destroy(&dev->wait_next_vol);
/* Bits for device capabilities */
-#define CAP_EOF 0x0001 /* has MTWEOF */
-#define CAP_BSR 0x0002 /* has MTBSR */
-#define CAP_BSF 0x0004 /* has MTBSF */
-#define CAP_FSR 0x0008 /* has MTFSR */
-#define CAP_FSF 0x0010 /* has MTFSF */
-#define CAP_EOM 0x0020 /* has MTEOM */
-#define CAP_REM 0x0040 /* is removable media */
-#define CAP_RACCESS 0x0080 /* is random access device */
-#define CAP_AUTOMOUNT 0x0100 /* Read device at start to see what is there */
-#define CAP_LABEL 0x0200 /* Label blank tapes */
-#define CAP_ANONVOLS 0x0400 /* Mount without knowing volume name */
-#define CAP_ALWAYSOPEN 0x0800 /* always keep device open */
-#define CAP_AUTOCHANGER 0x1000 /* AutoChanger */
+#define CAP_EOF 0x0001 /* has MTWEOF */
+#define CAP_BSR 0x0002 /* has MTBSR */
+#define CAP_BSF 0x0004 /* has MTBSF */
+#define CAP_FSR 0x0008 /* has MTFSR */
+#define CAP_FSF 0x0010 /* has MTFSF */
+#define CAP_EOM 0x0020 /* has MTEOM */
+#define CAP_REM 0x0040 /* is removable media */
+#define CAP_RACCESS 0x0080 /* is random access device */
+#define CAP_AUTOMOUNT 0x0100 /* Read device at start to see what is there */
+#define CAP_LABEL 0x0200 /* Label blank tapes */
+#define CAP_ANONVOLS 0x0400 /* Mount without knowing volume name */
+#define CAP_ALWAYSOPEN 0x0800 /* always keep device open */
+#define CAP_AUTOCHANGER 0x1000 /* AutoChanger */
#define CAP_OFFLINEUNMOUNT 0x2000 /* Offline before unmount */
-
-
-/* Tape state bits */
-#define ST_OPENED 0x001 /* set when device opened */
-#define ST_TAPE 0x002 /* is a tape device */
-#define ST_LABEL 0x004 /* label found */
-#define ST_MALLOC 0x008 /* dev packet malloc'ed in init_dev() */
-#define ST_APPEND 0x010 /* ready for Bacula append */
-#define ST_READ 0x020 /* ready for Bacula read */
-#define ST_EOT 0x040 /* at end of tape */
-#define ST_WEOT 0x080 /* Got EOT on write */
-#define ST_EOF 0x100 /* Read EOF i.e. zero bytes */
-#define ST_NEXTVOL 0x200 /* Start writing on next volume */
-#define ST_SHORT 0x400 /* Short block read */
+#define CAP_STREAM 0x4000 /* Stream device */
+
+
+/* Device state bits */
+#define ST_OPENED 0x0001 /* set when device opened */
+#define ST_TAPE 0x0002 /* is a tape device */
+#define ST_FILE 0x0004 /* is a file device */
+#define ST_FIFO 0x0008 /* is a fifo device */
+#define ST_PROG 0x0010 /* is a program device */
+#define ST_LABEL 0x0020 /* label found */
+#define ST_MALLOC 0x0040 /* dev packet malloc'ed in init_dev() */
+#define ST_APPEND 0x0080 /* ready for Bacula append */
+#define ST_READ 0x0100 /* ready for Bacula read */
+#define ST_EOT 0x0200 /* at end of tape */
+#define ST_WEOT 0x0400 /* Got EOT on write */
+#define ST_EOF 0x0800 /* Read EOF i.e. zero bytes */
+#define ST_NEXTVOL 0x1000 /* Start writing on next volume */
+#define ST_SHORT 0x2000 /* Short block read */
/* dev_blocked states (mutually exclusive) */
#define BST_NOT_BLOCKED 0 /* not blocked */
/* */
#define VERSION "1.29"
#define VSTRING "1"
-#define DATE "15 January 2003"
-#define LSMDATE "15Jan03"
+#define DATE "16 January 2003"
+#define LSMDATE "16Jan03"
/* Debug flags */
#define DEBUG 1
#define TRACEBACK 1
#define SMCHECK
+#define TRACE_FILE 1
/* IF you undefine this, Bacula will run 10X slower */
#define NO_POLL_TEST 1