From 14b82a889f1ab2f3139aa7ac91bc79a6399ad8ec Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 23 Jul 2005 21:59:10 +0000 Subject: [PATCH] - Complete (almost) documentation of 1.38. - Add error messages for error conditions with VSS. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2239 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 143 +++---------------- bacula/kes-1.37 | 2 + bacula/src/filed/job.c | 11 +- bacula/src/findlib/attribs.c | 21 ++- bacula/src/win32/baculafd/baculafd.mak | 83 ++++++++++- bacula/src/win32/compat/compat.cpp | 176 ++++++++++++------------ bacula/src/win32/compat/vss.cpp | 7 +- bacula/src/win32/compat/vss.h | 7 + bacula/src/win32/compat/vss_generic.cpp | 119 ++++++++++------ 9 files changed, 293 insertions(+), 276 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 64c5a3105f..1aa2f5ea54 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -1,5 +1,5 @@ Kern's ToDo List - 20 July 2005 + 23 July 2005 Major development: Project Developer @@ -11,113 +11,33 @@ Final items for 1.37 before release: 1. Fix bugs - --without-openssl breaks at least on Solaris. 3. Document all the new features (about half done). - - VSS. Shall I write "Include Writer 'WMI Writer", "MSDEWriter" - Let me explain this: An windows application can (no must) - register as VSS writer. This means that the applications opts to - be notified if a backup (or restore) occurs. If it then gets - this message, it will immediately store a consistent state to - disk. Examples for these writers are "MSDE" (Microsoft database - engine), "Event Log Writer", "Registry Writer" plus 3rd - party-writers. If you have a non-vss aware application (e.g. - SQL Anywhere or probably MySQL), a shadow copy is still generated - and the open files can be backed up, but there is no guarantee - that the file is consistent. - - At least the Microsoft example makes a significant effort to - determine which writers may be involved when a drive or file is - to be shadow copied. Of course, every single writer may fail.... - So they offer a user interface to explicitly include or exclude a - writer when creating a VSS shadow copy. I personally would not - like to bother the user with this - at least not right now - (efforts for exchanging lists between fd and director + efforts - for selecting, etc.). - - But I personally would like to have an information message about - the individual writers involved in the backup-process ("vssadmin - list writers" produced 4 entries on my xp-client and 7 on my w2k3 - server, please try this on your machine to understand the system - a little bit better). - - - Multiple drive autochanger support - - Support for ANSI/IBM labels. - - Seven new options keywords in a FileSet resource: - ignorecase, fstype, hfsplussupport, wilddir, wildfile, regexdir, - and regexfile thanks to Pruben Guldberg). See below for details. - Restore of all files for a Job or set of jobs even if the file records have been removed from the catalog. - Restore of a directory (non-recursive, i.e. only one level). - Support for TLS (ssl) between all the daemon connections thanks - to Landon Fuller. - - Any Volume in the Pool named Scratch may be reassigned to any - other Pool when a new Volume is needed. - Unicode filename support for Win32 (thanks to Thorsten Engel) - - Volume Shadow Copy support for Win32 thus the capability to - backup exclusively opened files (thanks to Thorsten Engel). - A VSS enabled Win32 FD is available. You must explicitly - turn on VSS with "Enable VSS = yes" in your FileSet resource. - SQLite3 support, but it seems to run at 1/2 to 1/4 the speed of SQLite2. - - New Job directive "Prefer Mounted Volumes = yes|no" causes the - SD to select either an Autochanger or a drive with a valid - Volume already mounted in preference. If none is available, - it will select the first available drive. - - New Run directive in Job resource of DIR. It permits - cloning of jobs. To clone a copy of the current job, use - Run = "job-name level=%l since=\"%s\"" - Note, job-name is normally the same name as the job that - is running but there is no restriction on what you put. If you - want to start the job by hand and use job overrides such as - storage=xxx, realize that the job will be started with the - default storage values not the overrides. The level=%l guarantees - that the chosen level of the job is the same, and the since=... - ensures that the job uses *exactly* the same time/date for incremental - and differential jobs. The since=... is ignored when level=Full. - A cloned job will not start additional clones, so it is not possible - to recurse. - - New Options keywords in a FileSet directive: - - WildDir xxx - Will do a wild card match against directories (files will not - be matched). - - WildFile xxx - Will do a wild card match against files (directories will not - be matched). - - RegexDir xxx - Will do a regular expression match against directories (files - will not be matched). - - RegexFile xxx - Will do a regular expression match against files( directories - will not be matched). - - IgnoreCase = yes | no - Will ignore case in wild card and regular expression matches. - This is handy for Windows where filename case is not significant. - - FsType = string - where string is a filesystem type: ext2, jfs, ntfs, proc, - reiserfs, xfs, usbdevfs, sysfs, smbfs, iso9660. For ext3 - systems, use ext2. You may have multiple fstype directives - and thus permit multiple filesystem types. If the type - specified on the fstype directive does not match the - filesystem for a particular directive, that directory will - not be backed up. This directive can be used to prevent - backing up non-local filesystems. - - HFS Plus Support = yes | no - If set, Mac OS X resource forks will be saved and restored. - - Label Type = ANSI | IBM | Bacula - Implemented in Director Pool resource and in SD Device resource. - If it is specified in the SD Device resource, it will take - precedence over the value passed from the Director to the SD. - - Check Labels = yes | no - Implemented in the SD Device resource. If you intend to read - ANSI or IBM labels, this *must* be set. Even if the volume - is not ANSI labeled, you can set this to yes, and Bacula will - check the label type. - - Scripts Directory = name. Defines the directory from - which Bacula scripts will be called for events. In fact, Bacula - appends this name to the standard Python list of search directories, - so the script could also be in any of the Python system directories. - - In FileSet, you can exclude backing up of hardlinks (if you have - a lot, it can be very expensive), by using: - HardLinks = no - in the Options section. Patch supplied by David R Bosso. Thanks. + - A pile of new Directives to support TLS. Please see the TLS chapter + of the manual. + + - "python restart" restarts the Python interpreter. Rather brutal, make + sure no Python scripts are running. This permits you to change + a Python script and ge + - With Python 2.3, there are a few compiler warnings. + - You must add --with-openssl to the configure command line if + you want TLS communications encryption support. +7. Write a bacula-web document +9. Run the regression scripts on Solaris and FreeBSD +- Figure out how to package gui, and rescue programs. +- Test TLS. + +Document: +- Document cleaning up the spool files: + db, pid, state, bsr, mail, conmsg, spool +- Document the multiple-drive-changer.txt script. +- Pruning with Admin job. +========= probably not in 1.38 ============= - MaximumPartSize = bytes (SD, Device resource) Defines the maximum part size. - Requires Mount = Yes/No (SD, Device resource) @@ -147,26 +67,7 @@ Final items for 1.37 before release: - Write Part After Job = Yes/No (DIR, Job Resource, and Schedule Resource) If this directive is set to yes (default no), a new part file will be created after the job is finished. - - A pile of new Directives to support TLS. Please see the TLS chapter - of the manual. - - - "python restart" restarts the Python interpreter. Rather brutal, make - sure no Python scripts are running. This permits you to change - a Python script and ge - - With Python 2.3, there are a few compiler warnings. - - You must add --with-openssl to the configure command line if - you want TLS communications encryption support. -7. Write a bacula-web document -9. Run the regression scripts on Solaris and FreeBSD -- Figure out how to package gui, and rescue programs. -- Test TLS. - -Document: -- Document cleaning up the spool files: - db, pid, state, bsr, mail, conmsg, spool -- Document the multiple-drive-changer.txt script. -- Pruning with Admin job. - +======= For 1.39: - Fix bpipe.c so that it does not modify results pointer. diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index 690a3262e7..4da52fd059 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -5,6 +5,8 @@ General: Changes to 1.37.32: 23Jul05 +- Complete (almost) documentation of 1.38. +- Add error messages for error conditions with VSS. - Fix additional problems with VSS backup that I introduced. Changes to 1.37.31: 22Jul05 diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index c7683b1020..39518d1f43 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -23,7 +23,6 @@ #include "bacula.h" #include "filed.h" - #ifdef WIN32_VSS #include "vss.h" #endif @@ -1219,19 +1218,23 @@ static int backup_cmd(JCR *jcr) if (get_win32_driveletters(jcr->ff, szWinDriveLetters)) { Jmsg(jcr, M_INFO, 0, _("Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n"), g_pVSSClient->GetDriverName(), szWinDriveLetters); if (!g_pVSSClient->CreateSnapshots(szWinDriveLetters)) { - Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshots failed\n")); + berrno be; + Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshots failed. ERR=%s\n"), + be.strerror()); } else { /* tell user if snapshot creation of a specific drive failed */ size_t i; for (i=0; iGetWriterCount(); i++) { int msg_type = M_INFO; - if (g_pVSSClient->GetWriterState(i) < 0) + if (g_pVSSClient->GetWriterState(i) < 0) { msg_type = M_WARNING; + } Jmsg(jcr, msg_type, 0, _("VSS Writer: %s\n"), g_pVSSClient->GetWriterInfo(i)); } } diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index 79e910e32e..38c0b1920e 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -604,17 +604,17 @@ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) if (!(atts.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (p_SetFileAttributesW) { - POOLMEM* pwszBuf = get_pool_memory (PM_FNAME); - UTF8_2_wchar(&pwszBuf, win32_ofile); + POOLMEM* pwszBuf = get_pool_memory (PM_FNAME); + UTF8_2_wchar(&pwszBuf, win32_ofile); - BOOL b=SetFileAttributesW((LPCWSTR)pwszBuf, atts.dwFileAttributes & SET_ATTRS); - free_pool_memory(pwszBuf); + BOOL b=SetFileAttributesW((LPCWSTR)pwszBuf, atts.dwFileAttributes & SET_ATTRS); + free_pool_memory(pwszBuf); - if (!b) - win_error(jcr, "SetFileAttributesW:", win32_ofile); + if (!b) + win_error(jcr, "SetFileAttributesW:", win32_ofile); } else { - if (!SetFileAttributes(win32_ofile, atts.dwFileAttributes & SET_ATTRS)) { + if (!SetFileAttributes(win32_ofile, atts.dwFileAttributes & SET_ATTRS)) { win_error(jcr, "SetFileAttributesA:", win32_ofile); } } @@ -662,16 +662,15 @@ void win_error(JCR *jcr, char *prefix, DWORD lerror) } -/* Cygwin API definition */ -extern "C" void cygwin_conv_to_win32_path(const char *path, char *win32_path, DWORD dwSize); - +/* Conversion of a Unix filename to a Win32 filename */ +extern void conv_unix_to_win32_path(const char *path, char *win32_path, DWORD dwSize); void unix_name_to_win32(POOLMEM **win32_name, char *name) { /* One extra byte should suffice, but we double it */ /* add MAX_PATH bytes for VSS shadow copy name */ DWORD dwSize = 2*strlen(name)+MAX_PATH; *win32_name = check_pool_memory_size(*win32_name, dwSize); - cygwin_conv_to_win32_path(name, *win32_name, dwSize); + conv_unix_to_win32_path(name, *win32_name, dwSize); } #endif /* HAVE_CYGWIN */ diff --git a/bacula/src/win32/baculafd/baculafd.mak b/bacula/src/win32/baculafd/baculafd.mak index fb8df37ccb..7afb9dca66 100644 --- a/bacula/src/win32/baculafd/baculafd.mak +++ b/bacula/src/win32/baculafd/baculafd.mak @@ -110,6 +110,9 @@ CLEAN : -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\verify.obj" -@erase "$(INTDIR)\verify_vol.obj" + -@erase "$(INTDIR)\vss.obj" + -@erase "$(INTDIR)\vss_xp.obj" + -@erase "$(INTDIR)\vss_w2k3.obj" -@erase "$(INTDIR)\watchdog.obj" -@erase "$(INTDIR)\winabout.obj" -@erase "$(INTDIR)\winapi.obj" @@ -125,14 +128,14 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "../compat" /I "../.." /I "../../../../depkgs-win32/pthreads" /I "../../../../depkgs-win32/zlib" /I "." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_WIN32" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "../compat" /I "../.." /I "../../../../depkgs-win32/pthreads" /I "../../../../depkgs-win32/zlib" /I "." /D "_WINDOWS" /D "_WIN32_WINNT=0x500" /D "WIN32_VSS" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_WIN32" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c RSC_PROJ=/l 0x409 /fo"$(INTDIR)\winres.res" /d "NDEBUG" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\baculafd.bsc" BSC32_SBRS= \ LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib gdi32.lib wsock32.lib shell32.lib pthreadVCE.lib zlib.lib /nologo /subsystem:windows /pdb:none /machine:I386 /nodefaultlib:"MSVCRT" /out:"$(OUTDIR)\bacula-fd.exe" /libpath:"../../../../depkgs-win32/pthreads" /libpath:"../../../../depkgs-win32/zlib" +LINK32_FLAGS=ole32.lib oleaut32.lib user32.lib advapi32.lib gdi32.lib wsock32.lib shell32.lib pthreadVCE.lib zlib.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"MSVCRT.lib" /out:"$(OUTDIR)\bacula-fd.exe" /libpath:"../../../../depkgs-win32/pthreads" /libpath:"../../../../depkgs-win32/zlib" LINK32_OBJS= \ "$(INTDIR)\address_conf.obj" \ "$(INTDIR)\alist.obj" \ @@ -203,6 +206,9 @@ LINK32_OBJS= \ "$(INTDIR)\var.obj" \ "$(INTDIR)\verify.obj" \ "$(INTDIR)\verify_vol.obj" \ + "$(INTDIR)\vss.obj" \ + "$(INTDIR)\vss_xp.obj" \ + "$(INTDIR)\vss_w2k3.obj" \ "$(INTDIR)\watchdog.obj" \ "$(INTDIR)\winabout.obj" \ "$(INTDIR)\winapi.obj" \ @@ -371,6 +377,12 @@ CLEAN : -@erase "$(INTDIR)\verify.sbr" -@erase "$(INTDIR)\verify_vol.obj" -@erase "$(INTDIR)\verify_vol.sbr" + -@erase "$(INTDIR)\vss.obj" + -@erase "$(INTDIR)\vss.sbr" + -@erase "$(INTDIR)\vss_xp.obj" + -@erase "$(INTDIR)\vss_xp.sbr" + -@erase "$(INTDIR)\vss_w2k3.obj" + -@erase "$(INTDIR)\vss_w2k3.sbr" -@erase "$(INTDIR)\watchdog.obj" -@erase "$(INTDIR)\watchdog.sbr" -@erase "$(INTDIR)\winabout.obj" @@ -396,7 +408,7 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /I "../compat" /I "../.." /I "../../../../depkgs-win32/pthreads" /I "../../../../depkgs-win32/zlib" /I "." /D "_DEBUG" /D "_WINMAIN_" /D "PTW32_BUILD" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_WIN32" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /I "../compat" /I "../.." /I "../../../../depkgs-win32/pthreads" /I "../../../../depkgs-win32/zlib" /I "." /D "_WINDOWS" /D "_WIN32_WINNT=0x500" /D "WIN32_VSS" /D "_DEBUG" /D "_WINMAIN_" /D "PTW32_BUILD" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_WIN32" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c RSC_PROJ=/l 0x409 /fo"$(INTDIR)\winres.res" /d "_DEBUG" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\baculafd.bsc" @@ -470,6 +482,9 @@ BSC32_SBRS= \ "$(INTDIR)\var.sbr" \ "$(INTDIR)\verify.sbr" \ "$(INTDIR)\verify_vol.sbr" \ + "$(INTDIR)\vss.sbr" \ + "$(INTDIR)\vss_xp.sbr" \ + "$(INTDIR)\vss_w2k3.sbr" \ "$(INTDIR)\watchdog.sbr" \ "$(INTDIR)\winabout.sbr" \ "$(INTDIR)\winapi.sbr" \ @@ -486,7 +501,7 @@ BSC32_SBRS= \ << LINK32=link.exe -LINK32_FLAGS=user32.lib advapi32.lib gdi32.lib shell32.lib wsock32.lib pthreadVCE.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"MSVCRT" /out:"$(OUTDIR)\bacula-fd.exe" /libpath:"../../../../depkgs-win32/pthreads" /libpath:"../../../../depkgs-win32/zlib" +LINK32_FLAGS=ole32.lib oleaut32.lib user32.lib advapi32.lib gdi32.lib shell32.lib wsock32.lib pthreadVCE.lib zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"MSVCRT.lib" /out:"$(OUTDIR)\bacula-fd.exe" /libpath:"../../../../depkgs-win32/pthreads" /libpath:"../../../../depkgs-win32/zlib" LINK32_OBJS= \ "$(INTDIR)\address_conf.obj" \ "$(INTDIR)\alist.obj" \ @@ -557,6 +572,9 @@ LINK32_OBJS= \ "$(INTDIR)\var.obj" \ "$(INTDIR)\verify.obj" \ "$(INTDIR)\verify_vol.obj" \ + "$(INTDIR)\vss.obj" \ + "$(INTDIR)\vss_xp.obj" \ + "$(INTDIR)\vss_w2k3.obj" \ "$(INTDIR)\watchdog.obj" \ "$(INTDIR)\winabout.obj" \ "$(INTDIR)\winapi.obj" \ @@ -1869,6 +1887,63 @@ SOURCE=..\filed\verify_vol.cpp !ENDIF +SOURCE=..\compat\vss.cpp + +!IF "$(CFG)" == "baculafd - Win32 Release" + + +"$(INTDIR)\vss.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "baculafd - Win32 Debug" + + +"$(INTDIR)\vss.obj" "$(INTDIR)\vss.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\compat\vss_xp.cpp + +!IF "$(CFG)" == "baculafd - Win32 Release" + + +"$(INTDIR)\vss_xp.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "baculafd - Win32 Debug" + + +"$(INTDIR)\vss_xp.obj" "$(INTDIR)\vss_xp.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\compat\vss_w2k3.cpp + +!IF "$(CFG)" == "baculafd - Win32 Release" + + +"$(INTDIR)\vss_w2k3.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "baculafd - Win32 Debug" + + +"$(INTDIR)\vss_w2k3.obj" "$(INTDIR)\vss_w2k3.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + + + + SOURCE=..\lib\watchdog.cpp !IF "$(CFG)" == "baculafd - Win32 Release" diff --git a/bacula/src/win32/compat/compat.cpp b/bacula/src/win32/compat/compat.cpp index 285786826a..edd04b528b 100644 --- a/bacula/src/win32/compat/compat.cpp +++ b/bacula/src/win32/compat/compat.cpp @@ -22,10 +22,9 @@ // $Id$ #include "bacula.h" +#define b_errno_win32 (1<<29) -#ifdef WIN32_VSS #include "vss.h" -#endif #include "../../lib/winapi.h" @@ -33,7 +32,6 @@ /* to allow the usage of the original version in this file here */ #undef fputs -#define b_errno_win32 (1<<29) #define USE_WIN32_COMPAT_IO 1 @@ -50,8 +48,7 @@ extern int enable_vss; #define WIN32_FILETIME_SCALE 10000000 // 100ns/second -extern "C" void -cygwin_conv_to_win32_path(const char *name, char *win32_name, DWORD dwSize) +void conv_unix_to_win32_path(const char *name, char *win32_name, DWORD dwSize) { const char *fname = name; char *tname = win32_name; @@ -84,7 +81,7 @@ cygwin_conv_to_win32_path(const char *name, char *win32_name, DWORD dwSize) \\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy1\\bacula\\uninstall.exe from c:\bacula\uninstall.exe */ - if (g_pVSSClient && enable_vss == 1) { + if (g_pVSSClient && enable_vss && g_pVSSClient->IsInitialized()) { POOLMEM *pszBuf = get_pool_memory (PM_FNAME); pszBuf = check_pool_memory_size(pszBuf, dwSize); bstrncpy(pszBuf, tname, strlen(tname)+1); @@ -334,7 +331,7 @@ stat2(const char *file, struct stat *sb) HANDLE h; int rval = 0; char tmpbuf[1024]; - cygwin_conv_to_win32_path(file, tmpbuf, 1024); + conv_unix_to_win32_path(file, tmpbuf, 1024); DWORD attr = -1; @@ -344,8 +341,7 @@ stat2(const char *file, struct stat *sb) attr = p_GetFileAttributesW((LPCWSTR) pwszBuf); free_pool_memory(pwszBuf); - } - else if (p_GetFileAttributesA) { + } else if (p_GetFileAttributesA) { attr = p_GetFileAttributesA(tmpbuf); } @@ -419,30 +415,32 @@ error: int stat(const char *file, struct stat *sb) { - WIN32_FILE_ATTRIBUTE_DATA data; - errno = 0; + WIN32_FILE_ATTRIBUTE_DATA data; + errno = 0; - memset(sb, 0, sizeof(*sb)); + memset(sb, 0, sizeof(*sb)); - if (g_platform_id == VER_PLATFORM_WIN32_WINDOWS) - return stat2(file, sb); + if (g_platform_id == VER_PLATFORM_WIN32_WINDOWS) { + return stat2(file, sb); + } - // otherwise we're on NT + // otherwise we're on NT #if 0 - WCHAR buf[32767]; - buf[0] = '\\'; - buf[1] = '\\'; - buf[2] = '?'; - buf[3] = '\\'; + WCHAR buf[32767]; + buf[0] = '\\'; + buf[1] = '\\'; + buf[2] = '?'; + buf[3] = '\\'; - wchar_win32_path(file, buf+4); + wchar_win32_path(file, buf+4); - if (!GetFileAttributesExW((WCHAR *)buf, GetFileExInfoStandard, &data)) - return stat2(file, sb); + if (!GetFileAttributesExW((WCHAR *)buf, GetFileExInfoStandard, &data)) { + return stat2(file, sb); + } #else - if (p_GetFileAttributesExW) { + if (p_GetFileAttributesExW) { /* dynamically allocate enough space for UCS2 filename */ POOLMEM* pwszBuf = get_pool_memory (PM_FNAME); UTF8_2_wchar(&pwszBuf, file); @@ -450,41 +448,45 @@ stat(const char *file, struct stat *sb) BOOL b = p_GetFileAttributesExW((LPCWSTR) pwszBuf, GetFileExInfoStandard, &data); free_pool_memory(pwszBuf); - if (!b) + if (!b) { return stat2(file, sb); - - } else if (p_GetFileAttributesExA) { - if (!p_GetFileAttributesExA(file, GetFileExInfoStandard, &data)) - return stat2(file, sb); - } - else - return stat2(file, sb); + } + } else if (p_GetFileAttributesExA) { + if (!p_GetFileAttributesExA(file, GetFileExInfoStandard, &data)) { + return stat2(file, sb); + } + } else { + return stat2(file, sb); + } #endif - sb->st_mode = 0777; /* start with everything */ - if (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) - sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH); - if (data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) - sb->st_mode &= ~S_IRWXO; /* remove everything for other */ - if (data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */ - - if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - sb->st_mode |= S_IFDIR; - else - sb->st_mode |= S_IFREG; + sb->st_mode = 0777; /* start with everything */ + if (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH); + } + if (data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) { + sb->st_mode &= ~S_IRWXO; /* remove everything for other */ + } + if (data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */ + } + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + sb->st_mode |= S_IFDIR; + } else { + sb->st_mode |= S_IFREG; + } - sb->st_nlink = 1; - sb->st_size = data.nFileSizeHigh; - sb->st_size <<= 32; - sb->st_size |= data.nFileSizeLow; - sb->st_blksize = 4096; - sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096; - sb->st_atime = cvt_ftime_to_utime(data.ftLastAccessTime); - sb->st_mtime = cvt_ftime_to_utime(data.ftLastWriteTime); - sb->st_ctime = cvt_ftime_to_utime(data.ftCreationTime); - return 0; + sb->st_nlink = 1; + sb->st_size = data.nFileSizeHigh; + sb->st_size <<= 32; + sb->st_size |= data.nFileSizeLow; + sb->st_blksize = 4096; + sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096; + sb->st_atime = cvt_ftime_to_utime(data.ftLastAccessTime); + sb->st_mtime = cvt_ftime_to_utime(data.ftLastWriteTime); + sb->st_ctime = cvt_ftime_to_utime(data.ftCreationTime); + return 0; } #endif //HAVE_MINGW @@ -492,54 +494,54 @@ stat(const char *file, struct stat *sb) int lstat(const char *file, struct stat *sb) { - return stat(file, sb); + return stat(file, sb); } void sleep(int sec) { - Sleep(sec * 1000); + Sleep(sec * 1000); } int geteuid(void) { - return 0; + return 0; } int execvp(const char *, char *[]) { - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; } int fork(void) { - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; } int pipe(int[]) { - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; } int waitpid(int, int*, int) { - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; } int readlink(const char *, char *, int) { - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; } @@ -547,23 +549,22 @@ readlink(const char *, char *, int) int strcasecmp(const char *s1, const char *s2) { - register int ch1, ch2; + register int ch1, ch2; - if (s1==s2) - return 0; /* strings are equal if same object. */ - else if (!s1) - return -1; - else if (!s2) - return 1; - do - { - ch1 = *s1; - ch2 = *s2; - s1++; - s2++; - } while (ch1 != 0 && tolower(ch1) == tolower(ch2)); + if (s1==s2) + return 0; /* strings are equal if same object. */ + else if (!s1) + return -1; + else if (!s2) + return 1; + do { + ch1 = *s1; + ch2 = *s2; + s1++; + s2++; + } while (ch1 != 0 && tolower(ch1) == tolower(ch2)); - return(ch1 - ch2); + return(ch1 - ch2); } #endif //HAVE_MINGW @@ -578,8 +579,7 @@ strncasecmp(const char *s1, const char *s2, int len) return -1; else if (!s2) return 1; - while (len--) - { + while (len--) { ch1 = *s1; ch2 = *s2; s1++; @@ -671,7 +671,7 @@ opendir(const char *path) if (g_platform_id != VER_PLATFORM_WIN32_WINDOWS) { #ifdef WIN32_VSS /* will append \\?\ at front itself */ - cygwin_conv_to_win32_path(path, tspec, max_len-4); + conv_unix_to_win32_path(path, tspec, max_len-4); #else /* allow path to be 32767 bytes */ tspec[0] = '\\'; @@ -679,10 +679,10 @@ opendir(const char *path) tspec[2] = '?'; tspec[3] = '\\'; tspec[4] = 0; - cygwin_conv_to_win32_path(path, tspec+4, max_len-4); + conv_unix_to_win32_path(path, tspec+4, max_len-4); #endif } else { - cygwin_conv_to_win32_path(path, tspec, max_len); + conv_unix_to_win32_path(path, tspec, max_len); } bstrncat(tspec, "\\*", max_len); @@ -1501,7 +1501,7 @@ utime(const char *fname, struct utimbuf *times) FILETIME acc, mod; char tmpbuf[1024]; - cygwin_conv_to_win32_path(fname, tmpbuf, 1024); + conv_unix_to_win32_path(fname, tmpbuf, 1024); cvt_utime_to_ftime(times->actime, acc); cvt_utime_to_ftime(times->modtime, mod); diff --git a/bacula/src/win32/compat/vss.cpp b/bacula/src/win32/compat/vss.cpp index 5fc878adf7..d08409eddc 100644 --- a/bacula/src/win32/compat/vss.cpp +++ b/bacula/src/win32/compat/vss.cpp @@ -79,8 +79,8 @@ VSSClient::VSSClient() m_pVectorWriterStates = new vector; m_pVectorWriterInfo = new vector; m_uidCurrentSnapshotSet = GUID_NULL; - memset (m_wszUniqueVolumeName,0,sizeof (m_wszUniqueVolumeName)); - memset (m_szShadowCopyName,0,sizeof (m_szShadowCopyName)); + memset(m_wszUniqueVolumeName,0, sizeof(m_wszUniqueVolumeName)); + memset(m_szShadowCopyName,0, sizeof(m_szShadowCopyName)); } // Destructor @@ -107,7 +107,7 @@ VSSClient::~VSSClient() BOOL VSSClient::InitializeForBackup() { //return Initialize (VSS_CTX_BACKUP); - return Initialize (0); + return Initialize(0); } @@ -138,6 +138,7 @@ BOOL VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nB } strncpy(szShadowPath, szFilePath, nBuflen); + errno = EINVAL; return FALSE; } diff --git a/bacula/src/win32/compat/vss.h b/bacula/src/win32/compat/vss.h index 9f8a4c0ebf..f3726ada87 100644 --- a/bacula/src/win32/compat/vss.h +++ b/bacula/src/win32/compat/vss.h @@ -27,6 +27,12 @@ #ifndef __VSS_H_ #define __VSS_H_ +#ifndef b_errno_win32 +#define b_errno_win32 (1<<29) +#endif + +#ifdef WIN32_VSS + // some forward declarations struct IVssAsync; @@ -103,5 +109,6 @@ private: BOOL CheckWriterStatus(); }; +#endif /* WIN32_VSS */ #endif /* __VSS_H_ */ diff --git a/bacula/src/win32/compat/vss_generic.cpp b/bacula/src/win32/compat/vss_generic.cpp index f412f1c7ad..ccb981fbc0 100644 --- a/bacula/src/win32/compat/vss_generic.cpp +++ b/bacula/src/win32/compat/vss_generic.cpp @@ -156,8 +156,7 @@ inline wstring GetUniqueVolumeNameForPath(wstring path) // Convert a writer status into a string inline wstring GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus) { - switch (eWriterStatus) - { + switch (eWriterStatus) { CHECK_CASE_FOR_CONSTANT(VSS_WS_STABLE); CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_FREEZE); CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_THAW); @@ -174,7 +173,7 @@ inline wstring GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus) CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_POST_RESTORE); default: - return wstring(L"Undefined"); + return wstring(L"Error or Undefined"); } } @@ -204,14 +203,18 @@ VSSClientGeneric::~VSSClientGeneric() // Initialize the COM infrastructure and the internal pointers BOOL VSSClientGeneric::Initialize(DWORD dwContext, BOOL bDuringRestore) { - if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) + if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) { + errno = ENOSYS; return FALSE; + } HRESULT hr; // Initialize COM if (!m_bCoInitializeCalled) { - if (FAILED(CoInitialize(NULL))) + if (FAILED(CoInitialize(NULL))) { + errno = b_errno_win32; return FALSE; + } m_bCoInitializeCalled = true; @@ -229,8 +232,10 @@ BOOL VSSClientGeneric::Initialize(DWORD dwContext, BOOL bDuringRestore) NULL // Reserved parameter ); - if (FAILED(hr)) + if (FAILED(hr)) { + errno = b_errno_win32; return FALSE; + } } // Release the IVssBackupComponents interface @@ -241,14 +246,18 @@ BOOL VSSClientGeneric::Initialize(DWORD dwContext, BOOL bDuringRestore) // Create the internal backup components object hr = p_CreateVssBackupComponents((IVssBackupComponents**) &m_pVssObject); - if (FAILED(hr)) + if (FAILED(hr)) { + errno = b_errno_win32; return FALSE; + } #ifdef B_VSS_W2K3 if (dwContext != VSS_CTX_BACKUP) { hr = ((IVssBackupComponents*) m_pVssObject)->SetContext(dwContext); - if (FAILED(hr)) + if (FAILED(hr)) { + errno = b_errno_win32; return FALSE; + } } #endif @@ -295,8 +304,10 @@ BOOL VSSClientGeneric::CreateSnapshots(char* szDriveLetters) /* if a drive can not being added, it's converted to lowercase in szDriveLetters */ /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vss/base/ivssbackupcomponents_startsnapshotset.asp */ - if (!m_pVssObject || m_bBackupIsInitialized) + if (!m_pVssObject || m_bBackupIsInitialized) { + errno = ENOSYS; return FALSE; + } m_uidCurrentSnapshotSet = GUID_NULL; @@ -304,13 +315,17 @@ BOOL VSSClientGeneric::CreateSnapshots(char* szDriveLetters) // 1. InitializeForBackup HRESULT hr = pVss->InitializeForBackup(); - if (FAILED(hr)) + if (FAILED(hr)) { + errno = b_errno_win32; return FALSE; + } // 2. SetBackupState hr = pVss->SetBackupState(true, true, VSS_BT_FULL, false); - if (FAILED(hr)) + if (FAILED(hr)) { + errno = b_errno_win32; return FALSE; + } CComPtr pAsync1; CComPtr pAsync2; @@ -319,8 +334,10 @@ BOOL VSSClientGeneric::CreateSnapshots(char* szDriveLetters) // 3. GatherWriterMetaData hr = pVss->GatherWriterMetadata(&pAsync3); - if (FAILED(hr)) + if (FAILED(hr)) { + errno = b_errno_win32; return FALSE; + } // Waits for the async operation to finish and checks the result WaitAndCheckForAsyncOperation(pAsync3); @@ -371,8 +388,10 @@ BOOL VSSClientGeneric::CreateSnapshots(char* szDriveLetters) BOOL VSSClientGeneric::CloseBackup() { - if (!m_pVssObject) + if (!m_pVssObject) { + errno = ENOSYS; return FALSE; + } BOOL bRet = FALSE; IVssBackupComponents* pVss = (IVssBackupComponents*) m_pVssObject; @@ -384,8 +403,8 @@ BOOL VSSClientGeneric::CloseBackup() // Waits for the async operation to finish and checks the result WaitAndCheckForAsyncOperation(pAsync); bRet = TRUE; - } - else { + } else { + errno = b_errno_win32; pVss->AbortBackup(); } @@ -413,13 +432,17 @@ BOOL VSSClientGeneric::CloseBackup() // Query all the shadow copies in the given set void VSSClientGeneric::QuerySnapshotSet(GUID snapshotSetID) { - if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) + if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) { + errno = ENOSYS; return; + } memset (m_szShadowCopyName,0,sizeof (m_szShadowCopyName)); - if (snapshotSetID == GUID_NULL || m_pVssObject == NULL) + if (snapshotSetID == GUID_NULL || m_pVssObject == NULL) { + errno = ENOSYS; return; + } IVssBackupComponents* pVss = (IVssBackupComponents*) m_pVssObject; @@ -431,15 +454,16 @@ void VSSClientGeneric::QuerySnapshotSet(GUID snapshotSetID) &pIEnumSnapshots ); // If there are no shadow copies, just return - if (FAILED(hr)) + if (FAILED(hr)) { + errno = b_errno_win32; return; + } // Enumerate all shadow copies. VSS_OBJECT_PROP Prop; VSS_SNAPSHOT_PROP& Snap = Prop.Obj.Snap; - while(true) - { + while (true) { // Get the next element ULONG ulFetched; hr = pIEnumSnapshots->Next( 1, &Prop, &ulFetched ); @@ -459,6 +483,7 @@ void VSSClientGeneric::QuerySnapshotSet(GUID snapshotSetID) } p_VssFreeSnapshotProperties(&Snap); } + errno = 0; } // Check the status for all selected writers @@ -475,8 +500,10 @@ BOOL VSSClientGeneric::CheckWriterStatus() CComPtr pAsync; HRESULT hr = pVss->GatherWriterStatus(&pAsync); - if (FAILED(hr)) - return FALSE; + if (FAILED(hr)) { + errno = b_errno_win32; + return FALSE; + } // Waits for the async operation to finish and checks the result WaitAndCheckForAsyncOperation(pAsync); @@ -484,12 +511,13 @@ BOOL VSSClientGeneric::CheckWriterStatus() unsigned cWriters = 0; hr = pVss->GetWriterStatusCount(&cWriters); - if (FAILED(hr)) - return FALSE; + if (FAILED(hr)) { + errno = b_errno_win32; + return FALSE; + } // Enumerate each writer - for(unsigned iWriter = 0; iWriter < cWriters; iWriter++) - { + for (unsigned iWriter = 0; iWriter < cWriters; iWriter++) { VSS_ID idInstance = GUID_NULL; VSS_ID idWriter= GUID_NULL; VSS_WRITER_STATE eWriterStatus = VSS_WS_UNKNOWN; @@ -503,31 +531,31 @@ BOOL VSSClientGeneric::CheckWriterStatus() &bstrWriterName, &eWriterStatus, &hrWriterFailure); - if (FAILED(hr)) + if (FAILED(hr)) { continue; + } // If the writer is in non-stable state, break - switch(eWriterStatus) - { - case VSS_WS_FAILED_AT_IDENTIFY: - case VSS_WS_FAILED_AT_PREPARE_BACKUP: - case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: - case VSS_WS_FAILED_AT_FREEZE: - case VSS_WS_FAILED_AT_THAW: - case VSS_WS_FAILED_AT_POST_SNAPSHOT: - case VSS_WS_FAILED_AT_BACKUP_COMPLETE: - case VSS_WS_FAILED_AT_PRE_RESTORE: - case VSS_WS_FAILED_AT_POST_RESTORE: + switch(eWriterStatus) { + case VSS_WS_FAILED_AT_IDENTIFY: + case VSS_WS_FAILED_AT_PREPARE_BACKUP: + case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: + case VSS_WS_FAILED_AT_FREEZE: + case VSS_WS_FAILED_AT_THAW: + case VSS_WS_FAILED_AT_POST_SNAPSHOT: + case VSS_WS_FAILED_AT_BACKUP_COMPLETE: + case VSS_WS_FAILED_AT_PRE_RESTORE: + case VSS_WS_FAILED_AT_POST_RESTORE: #ifdef B_VSS_W2K3 - case VSS_WS_FAILED_AT_BACKUPSHUTDOWN: + case VSS_WS_FAILED_AT_BACKUPSHUTDOWN: #endif - /* failed */ - pVWriterStates->push_back(-1); - break; + /* failed */ + pVWriterStates->push_back(-1); + break; - default: - /* okay */ - pVWriterStates->push_back(1); + default: + /* okay */ + pVWriterStates->push_back(1); } @@ -536,5 +564,6 @@ BOOL VSSClientGeneric::CheckWriterStatus() pVWriterInfo->push_back(osf.str()); } + errno = 0; return TRUE; } -- 2.39.5