From 26dea62aec147d0e9dfb688ce1a971c43ff53be0 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 24 Jun 2007 17:27:12 +0000 Subject: [PATCH] kes Implement Windows reparse points -- similar to directories, but we do not descend into it. This is a first cut. They seem to be backed up, but restore is not yet tested. kes Remove restore_blocking in tls code when shutting a socket to leave it in blocking mode. Hopefully this will fix the encryption bug reported by Frank Sweetser. kes When opening a file for backup, tell the OS that we are going to read it sequentially -- optimization. kes Change variable names in authenticate_director() to not conflict with member names in bat. Caused great confusion with compiler, but no warnings. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5077 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/baconfig.h | 3 ++- bacula/src/filed/backup.c | 5 ++++- bacula/src/filed/estimate.c | 21 ++++++++++---------- bacula/src/filed/status.c | 5 +++-- bacula/src/filed/verify.c | 3 ++- bacula/src/findlib/bfile.c | 34 ++++++++++++++++++-------------- bacula/src/findlib/bfile.h | 2 ++ bacula/src/findlib/create_file.c | 4 ++++ bacula/src/findlib/find.c | 1 + bacula/src/findlib/find_one.c | 6 +++++- bacula/src/lib/bsock.c | 2 +- bacula/src/lib/tls.c | 5 +---- bacula/src/version.h | 2 +- bacula/technotes-2.1 | 13 ++++++++++-- 14 files changed, 67 insertions(+), 39 deletions(-) diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index 6fa3fd6b2f..ae5bddbf9f 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -267,12 +267,13 @@ void InitWinAPIWrapper(); #define FT_NOOPEN 15 /* Could not open directory */ #define FT_RAW 16 /* Raw block device */ #define FT_FIFO 17 /* Raw fifo device */ -/* This directory packet is sent to the FD file processing routine so +/* The DIRBEGIN packet is sent to the FD file processing routine so * that it can filter packets, but otherwise, it is not used * or saved */ #define FT_DIRBEGIN 18 /* Directory at beginning (not saved) */ #define FT_INVALIDFS 19 /* File system not allowed for */ #define FT_INVALIDDT 20 /* Drive type not allowed for */ +#define FT_REPARSE 21 /* Win NTFS reparse point */ /* Definitions for upper part of type word (see above). */ #define AR_DATA_STREAM (1<<16) /* Data stream id present */ diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index e4651c7c19..db9193e716 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -273,6 +273,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"), ff_pkt->fname); break; + case FT_REPARSE: case FT_DIREND: Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link); break; @@ -441,6 +442,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) do_read = ff_pkt->statp.st_size > 0; #endif } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO || + ff_pkt->type == FT_REPARSE || (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) { do_read = true; } @@ -453,6 +455,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) tid = NULL; } int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0; + ff_pkt->bfd.reparse_point = ff_pkt->type == FT_REPARSE; if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) { ff_pkt->ff_errno = errno; berrno be; @@ -1068,7 +1071,7 @@ static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_strea stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles, ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0, attribsEx, 0); - } else if (ff_pkt->type == FT_DIREND) { + } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) { /* Here link is the canonical filename (i.e. with trailing slash) */ stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles, ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0); diff --git a/bacula/src/filed/estimate.c b/bacula/src/filed/estimate.c index 26f9bd8866..70d0154fb4 100644 --- a/bacula/src/filed/estimate.c +++ b/bacula/src/filed/estimate.c @@ -1,16 +1,7 @@ -/* - * Bacula File Daemon estimate.c - * Make and estimate of the number of files and size to be saved. - * - * Kern Sibbald, September MMI - * - * Version $Id$ - * - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2006 Free Software Foundation Europe e.V. + Copyright (C) 2001-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -34,6 +25,15 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Bacula File Daemon estimate.c + * Make and estimate of the number of files and size to be saved. + * + * Kern Sibbald, September MMI + * + * Version $Id$ + * + */ #include "bacula.h" #include "filed.h" @@ -76,6 +76,7 @@ static int tally_file(FF_PKT *ff_pkt, void *ijcr, bool top_level) case FT_NOFSCHG: case FT_INVALIDFS: case FT_INVALIDDT: + case FT_REPARSE: case FT_DIREND: case FT_SPEC: case FT_RAW: diff --git a/bacula/src/filed/status.c b/bacula/src/filed/status.c index 07e0f6b2e1..866cc18dd6 100644 --- a/bacula/src/filed/status.c +++ b/bacula/src/filed/status.c @@ -174,8 +174,9 @@ void output_status(void sendit(const char *msg, int len, void *sarg), void *arg) edit_uint64_with_commas(njcr->JobBytes, b2), edit_uint64_with_commas(bps, b3)); sendit(msg.c_str(), len, arg); - len = Mmsg(msg, _(" Files Examined=%s\n"), - edit_uint64_with_commas(njcr->num_files_examined, b1)); + len = Mmsg(msg, _(" Files Examined=%s Errors=%d\n"), + edit_uint64_with_commas(njcr->num_files_examined, b1), + njcr->JobErrors); sendit(msg.c_str(), len, arg); if (njcr->JobFiles > 0) { njcr->lock(); diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index 18ebe09d7f..e42dcf5f6b 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -104,6 +104,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level) case FT_DIRBEGIN: jcr->num_files_examined--; /* correct file count */ return 1; /* ignored */ + case FT_REPARSE: case FT_DIREND: Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname); break; @@ -190,7 +191,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level) stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0); - } else if (ff_pkt->type == FT_DIREND) { + } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) { /* Here link is the canonical filename (i.e. with trailing slash) */ stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link, diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index d98ba1afae..03b51431b5 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -1,13 +1,3 @@ -/* - * Bacula low level File I/O routines. This routine simulates - * open(), read(), write(), and close(), but using native routines. - * I.e. on Windows, we use Windows APIs. - * - * Kern Sibbald, April MMIII - * - * Version $Id$ - * - */ /* Bacula® - The Network Backup Solution @@ -35,6 +25,16 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Bacula low level File I/O routines. This routine simulates + * open(), read(), write(), and close(), but using native routines. + * I.e. on Windows, we use Windows APIs. + * + * Kern Sibbald, April MMIII + * + * Version $Id$ + * + */ #include "bacula.h" #include "find.h" @@ -417,8 +417,8 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) dwflags = 0; } - // unicode or ascii open for create write if (p_CreateFileW && p_MultiByteToWideChar) { + // unicode open for create write bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar, dwaccess, /* Requested access */ 0, /* Shared mode */ @@ -427,6 +427,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } else { + // ascii open bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */ 0, /* Shared mode */ @@ -441,14 +442,14 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) } else if (flags & O_WRONLY) { /* Open existing for write */ if (bfd->use_backup_api) { dwaccess = GENERIC_WRITE|WRITE_OWNER|WRITE_DAC; - dwflags = FILE_FLAG_BACKUP_SEMANTICS; + dwflags = FILE_FLAG_BACKUP_SEMANTICS; } else { dwaccess = GENERIC_WRITE; dwflags = 0; } - // unicode or ascii open for open existing write if (p_CreateFileW && p_MultiByteToWideChar) { + // unicode open for open existing write bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar, dwaccess, /* Requested access */ 0, /* Shared mode */ @@ -457,6 +458,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } else { + // ascii open bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */ 0, /* Shared mode */ @@ -472,7 +474,8 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) } else { /* Read */ if (bfd->use_backup_api) { dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY; - dwflags = FILE_FLAG_BACKUP_SEMANTICS; + dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN | + FILE_FLAG_OPEN_REPARSE_POINT; dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE; } else { dwaccess = GENERIC_READ; @@ -480,8 +483,8 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE; } - // unicode or ascii open for open existing read if (p_CreateFileW && p_MultiByteToWideChar) { + // unicode open for open existing read bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar, dwaccess, /* Requested access */ dwshare, /* Share modes */ @@ -490,6 +493,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } else { + // ascii open bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */ dwshare, /* Share modes */ diff --git a/bacula/src/findlib/bfile.h b/bacula/src/findlib/bfile.h index ffbb08270f..ed3f6c6d28 100644 --- a/bacula/src/findlib/bfile.h +++ b/bacula/src/findlib/bfile.h @@ -103,6 +103,7 @@ struct BFILE { Python_IO pio; /* Python I/O routines */ PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */ int use_backup_decomp; /* set if using BackupRead Stream Decomposition */ + bool reparse_point; /* set if reparse point */ }; HANDLE bget_handle(BFILE *bfd); @@ -126,6 +127,7 @@ struct BFILE { Python_IO pio; /* Python I/O routines */ PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */ int use_backup_decomp; /* set if using BackupRead Stream Decomposition */ + bool reparse_point; /* not used in Unix */ }; #endif diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index 05416ced82..12f7c487ba 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -78,6 +78,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) bool exists = false; struct stat mstatp; + bfd->reparse_point = false; if (is_win32_stream(attr->data_stream)) { set_win32_backup(bfd); } else { @@ -350,6 +351,9 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) #endif } /* End inner switch */ + case FT_REPARSE: + bfd->reparse_point = true; + /* Fall through wanted */ case FT_DIRBEGIN: case FT_DIREND: Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname); diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index dd1bbdabf4..0bffa6abe4 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -376,6 +376,7 @@ static int our_callback(FF_PKT *ff, void *hpkt, bool top_level) case FT_INVALIDFS: case FT_INVALIDDT: case FT_NOOPEN: + case FT_REPARSE: // return ff->callback(ff, hpkt, top_level); /* These items can be filtered */ diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index 81c892651e..723d45ccf7 100644 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -511,6 +511,10 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, } else { ff_pkt->type = FT_DIRBEGIN; } + /* We have set st_rdev to 1 if it is a reparse point, otherwise 0 */ + if (have_win32_api() && ff_pkt->statp.st_rdev) { + ff_pkt->type = FT_REPARSE; + } /* * Note, we return the directory to the calling program (handle_file) * when we first see the directory (FT_DIRBEGIN. @@ -520,7 +524,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, * in the directory is seen (i.e. the FT_DIREND). */ rtn_stat = handle_file(ff_pkt, pkt, top_level); - if (rtn_stat < 1) { /* ignore or error status */ + if (rtn_stat < 1 || ff_pkt->type == FT_REPARSE) { /* ignore or error status */ free(link); return rtn_stat; } diff --git a/bacula/src/lib/bsock.c b/bacula/src/lib/bsock.c index 88841f322f..32a163acc8 100644 --- a/bacula/src/lib/bsock.c +++ b/bacula/src/lib/bsock.c @@ -802,7 +802,7 @@ void BSOCK::close() free_tls_connection(bsock->tls); bsock->tls = NULL; } - if (bsock->is_timed_out() || bsock->is_terminated()) { + if (bsock->is_timed_out()) { shutdown(bsock->m_fd, SHUT_RDWR); /* discard any pending I/O */ } socketClose(bsock->m_fd); /* normal close */ diff --git a/bacula/src/lib/tls.c b/bacula/src/lib/tls.c index dd3aba8438..1acb404e56 100644 --- a/bacula/src/lib/tls.c +++ b/bacula/src/lib/tls.c @@ -569,7 +569,7 @@ void tls_bsock_shutdown(BSOCK *bsock) int flags; /* Set socket blocking for shutdown */ - flags = bsock->set_blocking(); + bsock->set_blocking(); err = SSL_shutdown(bsock->tls->openssl); @@ -585,9 +585,6 @@ void tls_bsock_shutdown(BSOCK *bsock) openssl_post_errors(M_ERROR, _("TLS shutdown failure.")); break; } - - /* Restore saved flags */ - bsock->restore_blocking(flags); } /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */ diff --git a/bacula/src/version.h b/bacula/src/version.h index 9467de874d..6315fe8404 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -3,7 +3,7 @@ */ #undef VERSION -#define VERSION "2.1.21" +#define VERSION "2.1.22" #define BDATE "24 June 2007" #define LSMDATE "24Jun07" diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index 808fe337db..6beafd1fd5 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,7 +1,16 @@ Technical notes on version 2.1 General: +Release 2.1.22 beta Win32 binaries only: 24Jun07 +kes Implement Windows reparse points -- similar to directories, but + we do not descend into it. This is a first cut. They seem to + be backed up, but restore is not yet tested. +kes Remove restore_blocking in tls code when shutting a socket to leave + it in blocking mode. Hopefully this will fix the encryption bug + reported by Frank Sweetser. +kes When opening a file for backup, tell the OS that we are going to + read it sequentially -- optimization. kes Change variable names in authenticate_director() to not conflict with member names in bat. Caused great confusion with compiler, but no warnings. @@ -17,9 +26,9 @@ kes Add Swedish sv.po file 21Jun07 kes Don't print clock skew message in FD if less than 3 seconds diff. kes Add a bit of VSS info to status client. -kes Make a gross first cut of Vista VSS, using Win2003 code. +kes Implement a first cut of Vista VSS, using Win2003 code. -Release: 2.1.18 beta +Release: 2.1.20 beta 20Jun07 kes Fixed bug #886 (multidrive autochanger: SD doesn't use drive with loaded tape but uses first drive). -- 2.39.5