From 4fdf53e67e489beef502bab24a989cff20e7d255 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 24 Aug 2004 12:18:45 +0000 Subject: [PATCH] - Applied a patch from Peter Eriksson that removes a dynamic stack allocation (replaced by alloca) and fixes some const problems. - Fixed a free() of a static variable in the new IP code bnet.c - Got the new Bacula Rescue CDROM booting. - Replaced a dynamic template by a simple store when using the native C compiler. - Reworked some of the block.c error handling. - Changed a Dmsgx(000, to Dmsgx(100 in dev.c that was dumping debug output on a user. - Integrated patch from 1.34.6 block.c to 1.35 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1553 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 23 ++++++++++--- bacula/src/dird/bacula-dir.conf.in | 4 +-- bacula/src/filed/status.c | 6 ++-- bacula/src/findlib/attribs.c | 4 +++ bacula/src/findlib/bfile.c | 2 +- bacula/src/lib/bnet.c | 53 ++++++++++++++++++++---------- bacula/src/lib/bsys.c | 2 +- bacula/src/lib/tree.h | 2 +- bacula/src/stored/block.c | 40 +++++++++++++--------- bacula/src/stored/dev.c | 2 +- bacula/src/stored/status.c | 6 ++-- bacula/src/version.h | 4 +-- 12 files changed, 98 insertions(+), 50 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index c80bec7902..5463c7ca23 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -11,14 +11,13 @@ Version 1.35 Kern (see below) ======================================================== 1.35 Items to do for release: -- Knoppix CDROM +- Bacula rescue CDROM +- Fix error handling in spooling both data and attribute. - Perhaps add read/write programs and/or plugins to FileSets. - Add new DCR calling sequences everywhere in SD. This will permit simultaneous use of multiple devices by a single job. -- Fix restore ++++ that get intermingled with "Building directory tree" - +- Look at Chris' patch for bscan bug. -- Test Win32 errno handling. - Add bscan to four-concurrent-jobs regression. - Doc new IPv6 syntax - Add IPv6 to regression @@ -31,6 +30,7 @@ Version 1.35 Kern (see below) - Doc update AllFromVol - Doc dbcheck eliminate orphaned clients. - Doc new duration time input editing. +- Doc -p option in stored Documentation to do: (any release a little bit at a time) @@ -69,6 +69,14 @@ For 1.37 Testing/Documentation: non-existent directories will not be restored properly. Wish list: +- see lzma401.zip in others directory for new compression + algorithm/library. +- Minimal autochanger handling in Bacula and in btape. +- Look into how tar does not save sockets and the possiblity of + not saving them in Bacula (Martin Simmons reported this). + The next two lines will show them. + localmounts=`awk '/ext/ { print $2 }' /proc/mounts` # or whatever + find $localmounts -xdev -type s -ls - Fix restore jobs so that multiple jobs can run if they are not using the same tape(s). - Allow the user to select JobType for manual pruning/purging. @@ -1177,3 +1185,10 @@ Block Position: 0 - Solve the termcap.h problem on Solaris configure. - Make Verify jobs require exclusive use of Volume as Restore jobs do. +- Fix restore ++++ that get intermingled with "Building directory tree" +- Fix doc in dirdconf.html for @, where the file must + have not a list of files, but + file = xxx + file = yyy +- Test Win32 errno handling. +- port 1.34.6-block.patch to 1.35 diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index ab7eab8a73..fad5ea8a47 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -227,6 +227,4 @@ Console { Name = @hostname@-mon Password = "@mon_dir_password@" CommandACL = status, .status - ClientACL = "" - StorageACL = "" -} \ No newline at end of file +} diff --git a/bacula/src/filed/status.c b/bacula/src/filed/status.c index 557d0c718d..0e02b35388 100755 --- a/bacula/src/filed/status.c +++ b/bacula/src/filed/status.c @@ -278,10 +278,12 @@ int status_cmd(JCR *jcr) int qstatus_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; - char time[dir->msglen+1]; + char *time; JCR *njcr; s_last_job* job; - + + time = (char *) alloca(dir->msglen+1); + if (sscanf(dir->msg, qstatus, time) != 1) { pm_strcpy(&jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg); diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index 0037c7bad8..a24f147497 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -151,8 +151,12 @@ void encode_stat(char *buf, FF_PKT *ff_pkt, int data_stream) /* Do casting according to unknown type to keep compiler happy */ +#if !HAVE_GCC & HAVE_SUN_OS +#define plug(st, val) st = val /* brain damaged compiler */ +#else template void plug(T &st, uint64_t val) { st = static_cast(val); } +#endif /* Decode a stat packet from base64 characters */ diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index c47afde496..cb56294937 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -509,7 +509,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) if (bfd->prog) { POOLMEM *ecmd = get_pool_memory(PM_FNAME); ecmd = edit_job_codes(bfd->jcr, ecmd, bfd->prog, fname); - char *pmode; + const char *pmode; if (flags & O_RDONLY) { pmode = "r"; } else { diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 9d52383d72..1cdd33520f 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -519,22 +519,30 @@ int bnet_wait_data_intr(BSOCK * bsock, int sec) */ static const char *gethost_strerror() { + const char *msg; switch (h_errno) { case NETDB_INTERNAL: - return strerror(errno); + msg = strerror(errno); + break; case NETDB_SUCCESS: - return "No problem."; + msg = "No problem."; + break; case HOST_NOT_FOUND: - return "Authoritative answer Host not found."; + msg = "Authoritative answer for host not found."; + break; case TRY_AGAIN: - return "Non-authoritative Host not found, or ServerFail."; + msg = "Non-authoritative for host not found, or ServerFail."; + break; case NO_RECOVERY: - return "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP."; + msg = "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP."; + break; case NO_DATA: - return "Valid name, no data record of resquested type."; + msg = "Valid name, no data record of resquested type."; + break; default: - return "Unknown error."; + msg = "Unknown error."; } + return msg; } @@ -549,10 +557,10 @@ static IPADDR *add_any(int family) return addr; } -static int resolv_host(int family, const char *host, dlist * addr_list, - const char **errstr) +static const char *resolv_host(int family, const char *host, dlist * addr_list) { struct hostent *hp; + const char *errmsg; P(ip_mutex); #ifdef HAVE_GETHOSTBYNAME2 @@ -561,9 +569,9 @@ static int resolv_host(int family, const char *host, dlist * addr_list, if ((hp = gethostbyname(host)) == NULL) { #endif /* may be the strerror give not the right result -:( */ - *errstr = gethost_strerror(); + errmsg = gethost_strerror(); V(ip_mutex); - return 0; + return errmsg; } else { char **p; for (p = hp->h_addr_list; *p != 0; p++) { @@ -581,7 +589,7 @@ static int resolv_host(int family, const char *host, dlist * addr_list, } V(ip_mutex); } - return 1; + return NULL; } /* @@ -591,6 +599,7 @@ dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr) { struct in_addr inaddr; IPADDR *addr = 0; + const char *errmsg; #ifdef HAVE_IPV6 struct in6_addr inaddr6; #endif @@ -621,17 +630,27 @@ dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr) #endif { if (family != 0) { - if (!resolv_host(family, host, addr_list, errstr)) { + errmsg = resolv_host(family, host, addr_list); + if (errmsg) { + *errstr = errmsg; free_addresses(addr_list); return 0; } } else { int done = 0; - done |= resolv_host(AF_INET, host, addr_list, errstr); + errmsg = resolv_host(AF_INET, host, addr_list); #ifdef HAVE_IPV6 - done |= resolv_host(AF_INET6, host, addr_list, errstr); + if (errmsg) { + errmsg = resolv_host(AF_INET6, host, addr_list); + if (!errmsg) { + done = 1; + } + } else { + done = 1; + } #endif if (!done) { + *errstr = errmsg; free_addresses(addr_list); return 0; } @@ -662,9 +681,9 @@ static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service, * the server that we want to connect with. */ if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) { + /* Note errstr is not malloc'ed */ Qmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n", host, errstr); - free((void *)errstr); *fatal = 1; return NULL; } @@ -706,7 +725,7 @@ static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service, } if (!connected) { - free_addresses(addr_list); + free_addresses(addr_list); errno = save_errno; return NULL; } diff --git a/bacula/src/lib/bsys.c b/bacula/src/lib/bsys.c index 5b32e330bd..bc5ae5834b 100644 --- a/bacula/src/lib/bsys.c +++ b/bacula/src/lib/bsys.c @@ -207,7 +207,7 @@ int bstrerror(int errnum, char *buf, size_t bufsiz) static pthread_mutex_t mutex; static int first = 1; int stat = 0; - char *msg; + const char *msg; if (first) { pthread_mutex_init(&mutex, NULL); diff --git a/bacula/src/lib/tree.h b/bacula/src/lib/tree.h index 2d712b406a..4c48f3a423 100644 --- a/bacula/src/lib/tree.h +++ b/bacula/src/lib/tree.h @@ -72,7 +72,7 @@ struct s_tree_root { * do initialization of child */ dlink sibling; dlist child; - char *fname; /* file name */ + const char *fname; /* file name */ int32_t FileIndex; /* file index */ uint32_t JobId; /* JobId */ uint16_t fname_len; /* filename length */ diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index a06460d161..5a59b29152 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -345,7 +345,7 @@ bool write_block_to_device(DCR *dcr, DEV_BLOCK *block) /* Create a jobmedia record for this job */ if (!dir_create_jobmedia_record(dcr)) { dev->dev_errno = EIO; - Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), + Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), jcr->VolCatInfo.VolCatName, jcr->Job); set_new_volume_parameters(dcr); stat = false; @@ -361,7 +361,11 @@ bool write_block_to_device(DCR *dcr, DEV_BLOCK *block) } if (!write_block_to_dev(dcr, block)) { - stat = fixup_device_block_write_error(dcr, block); + if (job_canceled(jcr)) { + stat = 0; + } else { + stat = fixup_device_block_write_error(dcr, block); + } } bail_out: @@ -382,7 +386,7 @@ bool write_block_to_dev(DCR *dcr, DEV_BLOCK *block) ssize_t stat = 0; uint32_t wlen; /* length to write */ int hit_max1, hit_max2; - bool ok; + bool ok = true; DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; @@ -452,7 +456,7 @@ bool write_block_to_dev(DCR *dcr, DEV_BLOCK *block) edit_uint64_with_commas(max_cap, ed1), dev->dev_name); block->write_failed = true; if (weof_dev(dev, 1) != 0) { /* end tape */ - Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); + Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); dev->VolCatInfo.VolCatErrors++; } /* Don't do update after second EOF or file count will be wrong */ @@ -460,6 +464,7 @@ bool write_block_to_dev(DCR *dcr, DEV_BLOCK *block) dev->VolCatInfo.VolCatFiles = dev->file; dir_update_volume_info(dcr, false); if (dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) { /* write eof */ + /* This may not be fatal since we already wrote an EOF */ Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); dev->VolCatInfo.VolCatErrors++; } @@ -474,7 +479,7 @@ bool write_block_to_dev(DCR *dcr, DEV_BLOCK *block) if (dev_state(dev, ST_TAPE) && weof_dev(dev, 1) != 0) { /* write eof */ /* Write EOF */ - Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); + Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); block->write_failed = true; dev->VolCatInfo.VolCatErrors++; dev->state |= (ST_EOF | ST_EOT | ST_WEOT); @@ -543,14 +548,14 @@ bool write_block_to_dev(DCR *dcr, DEV_BLOCK *block) #endif if (stat != (ssize_t)wlen) { - /* We should check for errno == ENOSPC, BUT many - * devices simply report EIO when the volume is full. + /* Some devices simply report EIO when the volume is full. * With a little more thought we may be able to check * capacity and distinguish real errors and EOT * conditions. In any case, we probably want to * simulate an End of Medium. */ if (stat == -1) { + berrno be; /* I have added the ifdefing here because it appears on * FreeBSD where MTIOCERRSTAT is defined, this not only * clears the error but clears the residual unwritten @@ -562,33 +567,37 @@ bool write_block_to_dev(DCR *dcr, DEV_BLOCK *block) if (dev->dev_errno == 0) { dev->dev_errno = ENOSPC; /* out of space */ } - Jmsg4(jcr, M_ERROR, 0, _("Write error at %u:%u on device %s. ERR=%s.\n"), - dev->file, dev->block_num, dev->dev_name, strerror(dev->dev_errno)); + if (dev->dev_errno != ENOSPC) { + Jmsg4(jcr, M_ERROR, 0, _("Write error at %u:%u on device %s. ERR=%s.\n"), + dev->file, dev->block_num, dev->dev_name, be.strerror()); + } } else { dev->dev_errno = ENOSPC; /* out of space */ + } + if (dev->dev_errno == ENOSPC) { Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n"), dev->VolCatInfo.VolCatName, dev->file, dev->block_num, dev->dev_name, wlen, stat); - } - + } Dmsg6(100, "=== Write error. size=%u rtn=%d dev_blk=%d blk_blk=%d errno=%d: ERR=%s\n", wlen, stat, dev->block_num, block->BlockNumber, dev->dev_errno, strerror(dev->dev_errno)); block->write_failed = true; if (weof_dev(dev, 1) != 0) { /* end the tape */ dev->VolCatInfo.VolCatErrors++; - Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); + Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); + ok = false; } Dmsg0(100, "dir_update_volume_info\n"); dev->VolCatInfo.VolCatFiles = dev->file; dir_update_volume_info(dcr, false); - if (dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) { /* end the tape */ + if (ok && dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) { /* end the tape */ dev->VolCatInfo.VolCatErrors++; + /* This may not be fatal since we already wrote an EOF */ Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } dev->state |= (ST_EOF | ST_EOT | ST_WEOT); - ok = true; #define CHECK_LAST_BLOCK #ifdef CHECK_LAST_BLOCK /* @@ -598,8 +607,7 @@ bool write_block_to_dev(DCR *dcr, DEV_BLOCK *block) * then re-read it and verify that the block number is * correct. */ - if ((dev->state & ST_TAPE) && dev_cap(dev, CAP_BSR)) { - + if (ok && (dev->state & ST_TAPE) && dev_cap(dev, CAP_BSR)) { /* Now back up over what we wrote and read the last block */ if (!bsf_dev(dev, 1)) { ok = false; diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 52320bd725..02bb385680 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -516,7 +516,7 @@ eod_dev(DEVICE *dev) Dmsg1(100, "fsf_dev did not advance from file %d\n", file_num); if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) == 0 && mt_stat.mt_fileno >= 0) { - Dmsg2(000, "Adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno); + Dmsg2(100, "Adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno); dev->file = mt_stat.mt_fileno; } stat = 0; diff --git a/bacula/src/stored/status.c b/bacula/src/stored/status.c index 06ffdf991d..d9b4f05028 100644 --- a/bacula/src/stored/status.c +++ b/bacula/src/stored/status.c @@ -425,10 +425,12 @@ static void sendit(const char *msg, int len, void *arg) int qstatus_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; - char time[dir->msglen+1]; + char *time; JCR *njcr; s_last_job* job; - + + time = (char *) alloca(dir->msglen+1); + if (sscanf(dir->msg, qstatus, time) != 1) { pm_strcpy(&jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg); diff --git a/bacula/src/version.h b/bacula/src/version.h index 0f9539d3e4..bdbeb314e8 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION #define VERSION "1.35.2" -#define BDATE "16 August 2004" -#define LSMDATE "16Aug04" +#define BDATE "24 August 2004" +#define LSMDATE "24Aug04" /* Debug flags */ #undef DEBUG -- 2.39.2