From 746e5a31bec217cb5b444d145ab042392ce00cb1 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 12 Mar 2003 21:59:30 +0000 Subject: [PATCH] newvol locking, cleanup Win32, better EOM messages git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@377 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 6 + bacula/src/dird/backup.c | 4 +- bacula/src/dird/fd_cmds.c | 2 +- bacula/src/dird/newvol.c | 4 + bacula/src/filed/win32/bin/CygwinInstall.bat | 2 +- bacula/src/filed/win32/winservice.cpp | 472 ++++++++++++------- bacula/src/findlib/attribs.c | 8 +- bacula/src/lib/tcpd.h | 2 +- bacula/src/stored/block.c | 19 +- 9 files changed, 340 insertions(+), 179 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 04dc7f2e48..931236cdd5 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -10,6 +10,8 @@ Documentation to do: (a little bit at a time) - Document how to use multiple databases. - Document Maximum File Size +***** Write up how to use/manage disk Volume Storage. ****** + Testing to do: (painful) - that ALL console command line options work and are always implemented @@ -17,6 +19,10 @@ Testing to do: (painful) - multiple simultaneous Volumes For 1.30 release: +- Need to return reason for EOF from write_block() e.g. File size + exceeded, ERROR, EOF, ... +- Look at Lutz' every other block checksum error. ***Urgent*** +- Think about adding Modes to the Storage daemon for creating Files. - Fix "access not allowed" for backup of files on WinXP. - Fix Error: bnet.c:408 gethostbyname() for lpmatou failed: ERR=Operation not permited loop. diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 900a8628b1..713a1b138e 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -329,8 +329,8 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since) strcpy(mr.VolumeName, jcr->VolumeName); if (!db_get_media_record(jcr, jcr->db, &mr)) { - Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for stats: %s"), - db_strerror(jcr->db)); + Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for Volume \"%s\": ERR=%s"), + mr.VolumeName, db_strerror(jcr->db)); set_jcr_job_status(jcr, JS_ErrorTerminated); } diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 5af2618dde..93c7dac945 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -195,7 +195,7 @@ int send_include_list(JCR *jcr) pm_strcpy(&fd->msg, "0 "); } pm_strcat(&fd->msg, ie->name_list[j]); - Dmsg1(000, "Include name=%s\n", fd->msg); + Dmsg1(100, "Include name=%s\n", fd->msg); fd->msglen = strlen(fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index d3443dd269..1abab32cae 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -47,6 +47,7 @@ int newVolume(JCR *jcr, MEDIA_DBR *mr) memset(&pr, 0, sizeof(pr)); /* See if we can create a new Volume */ + db_lock(jcr->db); pr.PoolId = jcr->PoolId; if (db_get_pool_record(jcr, jcr->db, &pr) && pr.LabelFormat[0] && pr.LabelFormat[0] != '*') { @@ -56,6 +57,7 @@ int newVolume(JCR *jcr, MEDIA_DBR *mr) strcpy(mr->MediaType, jcr->store->media_type); strcpy(name, pr.LabelFormat); if (strchr(name, (int)'%') != NULL) { + db_unlock(jcr->db); Jmsg(jcr, M_ERROR, 0, _("Illegal character in Label Format\n")); return 0; } @@ -63,6 +65,7 @@ int newVolume(JCR *jcr, MEDIA_DBR *mr) sprintf(mr->VolumeName, name, ++pr.NumVols); if (db_create_media_record(jcr, jcr->db, mr) && db_update_pool_record(jcr, jcr->db, &pr) == 1) { + db_unlock(jcr->db); Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName); return 1; } else { @@ -70,5 +73,6 @@ int newVolume(JCR *jcr, MEDIA_DBR *mr) } } } + db_unlock(jcr->db); return 0; } diff --git a/bacula/src/filed/win32/bin/CygwinInstall.bat b/bacula/src/filed/win32/bin/CygwinInstall.bat index 10c4329d4a..da0787e3b1 100755 --- a/bacula/src/filed/win32/bin/CygwinInstall.bat +++ b/bacula/src/filed/win32/bin/CygwinInstall.bat @@ -1,3 +1,3 @@ -cd \bacula\bin +cd \cygwin\bacula\bin bacula-fd.exe /install diff --git a/bacula/src/filed/win32/winservice.cpp b/bacula/src/filed/win32/winservice.cpp index 8c079cb62b..81b0b17f7b 100755 --- a/bacula/src/filed/win32/winservice.cpp +++ b/bacula/src/filed/win32/winservice.cpp @@ -44,12 +44,17 @@ // Error message logging void LogErrorMsg(char *message); +#ifdef needed +void SetServicePrivileges(); +#endif // OS-SPECIFIC ROUTINES // Create an instance of the bacService class to cause the static fields to be // initialised properly +int NoGetFileAttributesEx = 0; /* set if function no avail -- Win95 */ + bacService init; DWORD g_platform_id; @@ -208,6 +213,7 @@ bacService::PostAddNewClient(unsigned long ipaddress) // List other required serves #define BAC_DEPENDENCIES "" + // Internal service state SERVICE_STATUS g_srvstatus; // current status of the service SERVICE_STATUS_HANDLE g_hstatus; @@ -215,15 +221,13 @@ DWORD g_error = 0; DWORD g_servicethread = 0; char* g_errortext[256]; + // Forward defines of internal service functions void WINAPI ServiceMain(DWORD argc, char **argv); - DWORD WINAPI ServiceWorkThread(LPVOID lpwThreadParam); void ServiceStop(); void WINAPI ServiceCtrl(DWORD ctrlcode); - bool WINAPI CtrlHandler (DWORD ctrltype); - BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint); // ROUTINE TO QUERY WHETHER THIS PROCESS IS RUNNING AS A SERVICE OR NOT @@ -239,8 +243,8 @@ bacService::RunningAsService() BOOL bacService::KillRunningCopy() { - while (PostToBacula(WM_CLOSE, 0, 0)) { - } + while (PostToBacula(WM_CLOSE, 0, 0)) + { } return TRUE; } @@ -332,6 +336,13 @@ bacService::BaculaServiceMain() break; } + /* Test for GetFileAttributesEx which is not in Win95 */ + if (GetProcAddress(kerneldll, "GetFileAttributesEx") == NULL) { + NoGetFileAttributesEx = 1; + /*****FIXME***** remove after testing */ + MessageBox(NULL, "NoGetFileAttributesEx", "Bacula", MB_OK); + } + // And find the RegisterServiceProcess function DWORD (*RegisterService)(DWORD, DWORD); RegisterService = (DWORD (*)(DWORD, DWORD)) @@ -353,12 +364,10 @@ bacService::BaculaServiceMain() // Free the kernel library FreeLibrary(kerneldll); - - // *** If we don't kill the process directly here, then - // for some reason, Bacula crashes... - // ExitProcess(0); break; } + + // Windows NT case VER_PLATFORM_WIN32_NT: { @@ -369,11 +378,12 @@ bacService::BaculaServiceMain() }; // Call the service control dispatcher with our entry table - if (!StartServiceCtrlDispatcher(dispatchTable)) - LogErrorMsg("StartServiceCtrlDispatcher failed."); - break; + if (!StartServiceCtrlDispatcher(dispatchTable)) { + LogErrorMsg("StartServiceCtrlDispatcher failed."); } - } + break; + } /* end case */ + } /* end switch */ return 0; } @@ -383,7 +393,7 @@ void WINAPI ServiceMain(DWORD argc, char **argv) { DWORD dwThreadID; - // Register the service control handler + // Register the service control handler g_hstatus = RegisterServiceCtrlHandler(BAC_SERVICENAME, ServiceCtrl); if (g_hstatus == 0) { @@ -392,22 +402,19 @@ void WINAPI ServiceMain(DWORD argc, char **argv) return; } - // Set up some standard service state values + // Set up some standard service state values g_srvstatus.dwServiceType = SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS; g_srvstatus.dwServiceSpecificExitCode = 0; // Give this status to the SCM if (!ReportStatus( - SERVICE_START_PENDING, // Service state - NO_ERROR, // Exit code type - 15000)) // Hint as to how long Bacula should have hung before you assume error - { - ReportStatus( - SERVICE_STOPPED, - g_error, - 0); - return; - } + SERVICE_START_PENDING, // Service state + NO_ERROR, // Exit code type + 45000)) { // Hint as to how long Bacula should have hung before you assume error + + ReportStatus(SERVICE_STOPPED, g_error, 0); + return; + } // Now start the service for real (void)CreateThread(NULL, 0, ServiceWorkThread, NULL, 0, &dwThreadID); @@ -418,8 +425,6 @@ void WINAPI ServiceMain(DWORD argc, char **argv) // NT ONLY !!!! DWORD WINAPI ServiceWorkThread(LPVOID lpwThreadParam) { - HANDLE hToken; - TOKEN_PRIVILEGES tkp; // Save the current thread identifier g_servicethread = GetCurrentThreadId(); @@ -434,57 +439,83 @@ DWORD WINAPI ServiceWorkThread(LPVOID lpwThreadParam) return 0; } - // Get a token for this process. - - if (!OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { - /* Forge on anyway */ - } + /* Call Bacula main code */ + BaculaAppMain(); + + /* Mark that we're no longer running */ + g_servicethread = 0; - // Get the LUID for the backup privilege. - LookupPrivilegeValue(NULL, SE_BACKUP_NAME, - &tkp.Privileges[0].Luid); + /* Tell the service manager that we've stopped */ + ReportStatus(SERVICE_STOPPED, g_error, 0); + return 0; +} +#ifdef needed +/* + * Setup privileges we think we will need. We probably do not need + * the SE_SECURITY_NAME, but since nothing seems to be working, + * we get it hoping to fix the problems. + */ +void SetServicePrivileges() +{ + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + // Get a token for this process. + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + /* Forge on anyway */ + } + + // Get the LUID for the security privilege. + LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tkp.Privileges[0].Luid); + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get the security privilege for this process. + AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES)NULL, (PDWORD)0); - tkp.PrivilegeCount = 1; // one privilege to set - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + // Cannot test the return value of AdjustTokenPrivileges. + if (GetLastError() != ERROR_SUCCESS) { +// MessageBox(NULL, "Get security priv failed: AdjustTokePrivileges", "backup", MB_OK); + } + + // Get the LUID for the backup privilege. + LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &tkp.Privileges[0].Luid); + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - // Get the backup privilege for this process. - AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, - (PTOKEN_PRIVILEGES)NULL, 0); + // Get the backup privilege for this process. + AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES)NULL, (PDWORD)0); - // Cannot test the return value of AdjustTokenPrivileges. - if (GetLastError() != ERROR_SUCCESS) { -// MessageBox(NULL, "System shutdown failed: AdjustTokePrivileges", "shutdown", MB_OK); - } + // Cannot test the return value of AdjustTokenPrivileges. + if (GetLastError() != ERROR_SUCCESS) { +// MessageBox(NULL, "Get backup priv failed: AdjustTokePrivileges", "backup", MB_OK); + } - // Get the LUID for the restore privilege. - LookupPrivilegeValue(NULL, SE_RESTORE_NAME, - &tkp.Privileges[0].Luid); + // Get the LUID for the restore privilege. + LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tkp.Privileges[0].Luid); - tkp.PrivilegeCount = 1; // one privilege to set - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - // Get the restore privilege for this process. - AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, - (PTOKEN_PRIVILEGES)NULL, 0); + // Get the restore privilege for this process. + AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES)NULL, (PDWORD)0); - // Cannot test the return value of AdjustTokenPrivileges. - if (GetLastError() != ERROR_SUCCESS) { -// MessageBox(NULL, "System shutdown failed: AdjustTokePrivileges", "shutdown", MB_OK); - } - - /* Call Bacula main code */ - BaculaAppMain(); - - /* Mark that we're no longer running */ - g_servicethread = 0; + // Cannot test the return value of AdjustTokenPrivileges. + if (GetLastError() != ERROR_SUCCESS) { +// MessageBox(NULL, "Get restore priv failed: AdjustTokePrivileges", "restore", MB_OK); + } - /* Tell the service manager that we've stopped */ - ReportStatus(SERVICE_STOPPED, g_error, 0); - return 0; + CloseHandle(hToken); } +#endif + // SERVICE STOP ROUTINE - post a quit message to the relevant thread void ServiceStop() { @@ -592,83 +623,191 @@ bacService::InstallService() // Open the default, local Service Control Manager database hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if (hsrvmanager == NULL) { - MessageBox(NULL, - "The Service Control Manager could not be contacted - the Bacula service was not installed", - szAppName, MB_ICONEXCLAMATION | MB_OK); - break; - } - - // Create an entry for the Bacula service - hservice = CreateService( - hsrvmanager, // SCManager database - BAC_SERVICENAME, // name of service - BAC_SERVICEDISPLAYNAME, // name to display - SERVICE_ALL_ACCESS, // desired access - SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, - // service type - SERVICE_AUTO_START, // start type - SERVICE_ERROR_NORMAL, // error control type - servicecmd, // service's binary - NULL, // no load ordering group - NULL, // no tag identifier - BAC_DEPENDENCIES, // dependencies - NULL, // LocalSystem account - NULL); // no password - CloseServiceHandle(hsrvmanager); - if (hservice == NULL) { - MessageBox(NULL, - "The Bacula service could not be installed", - szAppName, MB_ICONEXCLAMATION | MB_OK); - break; - } - CloseServiceHandle(hservice); - - // Now install the servicehelper registry setting... - // Locate the RunService registry entry - HKEY runapps; - if (RegCreateKey(HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\Run", - &runapps) != ERROR_SUCCESS) { - MessageBox(NULL, "WARNING: Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", - szAppName, MB_ICONEXCLAMATION | MB_OK); - } else { - char servicehelpercmd[pathlength]; - - // Append the service-helper-start flag to the end of the path: - if ((int)strlen(path) + 4 + (int)strlen(BaculaRunServiceHelper) < pathlength) - sprintf(servicehelpercmd, "\"%s\" %s", path, BaculaRunServiceHelper); - else - return 0; - - // Add the upsserviceHelper entry - if (RegSetValueEx(runapps, szAppName, 0, REG_SZ, - (unsigned char *)servicehelpercmd, strlen(servicehelpercmd)+1) != ERROR_SUCCESS) - { - MessageBox(NULL, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", szAppName, MB_ICONEXCLAMATION | MB_OK); - } - RegCloseKey(runapps); - } - - // Everything went fine - MessageBox(NULL, - "The Bacula File service was successfully installed.\n" - "The service may be started from the Control Panel and will\n" - "automatically be run the next time this machine is rebooted.", - szAppName, - MB_ICONINFORMATION | MB_OK); - break; + if (hsrvmanager == NULL) { + MessageBox(NULL, + "The Service Control Manager could not be contacted - the Bacula service was not installed", + szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + } + + // Create an entry for the Bacula service + hservice = CreateService( + hsrvmanager, // SCManager database + BAC_SERVICENAME, // name of service + BAC_SERVICEDISPLAYNAME, // name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, + // service type + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + servicecmd, // service's binary + NULL, // no load ordering group + NULL, // no tag identifier + BAC_DEPENDENCIES, // dependencies + NULL, // LocalSystem account + NULL); // no password + if (hservice == NULL) { + CloseServiceHandle(hsrvmanager); + MessageBox(NULL, + "The Bacula service could not be installed", + szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + } + + /*****FIXME***** add code to set Description */ + + CloseServiceHandle(hsrvmanager); + CloseServiceHandle(hservice); + + // Now install the servicehelper registry setting... + // Locate the RunService registry entry + HKEY runapps; + if (RegCreateKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\Run", + &runapps) != ERROR_SUCCESS) { + MessageBox(NULL, "WARNING: Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", + szAppName, MB_ICONEXCLAMATION | MB_OK); + } else { + char servicehelpercmd[pathlength]; + + // Append the service-helper-start flag to the end of the path: + if ((int)strlen(path) + 4 + (int)strlen(BaculaRunServiceHelper) < pathlength) { + sprintf(servicehelpercmd, "\"%s\" %s", path, BaculaRunServiceHelper); + } else { + return 0; + } + + // Add the Bacula Service Helper entry + if (RegSetValueEx(runapps, szAppName, 0, REG_SZ, + (unsigned char *)servicehelpercmd, strlen(servicehelpercmd)+1) != ERROR_SUCCESS) { + MessageBox(NULL, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + RegCloseKey(runapps); + } + + // Everything went fine + MessageBox(NULL, + "The Bacula File service was successfully installed.\n" + "The service may be started from the Control Panel and will\n" + "automatically be run the next time this machine is rebooted.", + szAppName, + MB_ICONINFORMATION | MB_OK); + break; default: - MessageBox(NULL, - "Unknown Windows operating system.\n" - "Cannot install Bacula service.\n", - szAppName, MB_ICONEXCLAMATION | MB_OK); - break; + MessageBox(NULL, + "Unknown Windows operating system.\n" + "Cannot install Bacula service.\n", + szAppName, MB_ICONEXCLAMATION | MB_OK); + break; }; return 0; } +#ifdef implemented +VOID ReconfigureSampleService(BOOL fDisable, LPSTR lpDesc) +{ + SC_LOCK sclLock; + LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf; + SERVICE_DESCRIPTION sdBuf; + DWORD dwBytesNeeded, dwStartType; + + // Need to acquire database lock before reconfiguring. + + sclLock = LockServiceDatabase(schSCManager); + + // If the database cannot be locked, report the details. + + if (sclLock == NULL) + { + // Exit if the database is not locked by another process. + + if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) + MyErrorExit("LockServiceDatabase"); + + // Allocate a buffer to get details about the lock. + + lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc( + LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); + if (lpqslsBuf == NULL) + MyErrorExit("LocalAlloc"); + + // Get and print the lock status information. + + if (!QueryServiceLockStatus( + schSCManager, + lpqslsBuf, + sizeof(QUERY_SERVICE_LOCK_STATUS)+256, + &dwBytesNeeded) ) + MyErrorExit("QueryServiceLockStatus"); + + if (lpqslsBuf->fIsLocked) + printf("Locked by: %s, duration: %d seconds\n", + lpqslsBuf->lpLockOwner, + lpqslsBuf->dwLockDuration); + else + printf("No longer locked\n"); + + LocalFree(lpqslsBuf); + MyErrorExit("Could not lock database"); + } + + // The database is locked, so it is safe to make changes. + + // Open a handle to the service. + + schService = OpenService( + schSCManager, // SCManager database + "Sample_Srv", // name of service + SERVICE_CHANGE_CONFIG); // need CHANGE access + if (schService == NULL) + MyErrorExit("OpenService"); + + dwStartType = (fDisable) ? SERVICE_DISABLED : + SERVICE_DEMAND_START; + + // Make the changes. + + if (! ChangeServiceConfig( + schService, // handle of service + SERVICE_NO_CHANGE, // service type: no change + dwStartType, // change service start type + SERVICE_NO_CHANGE, // error control: no change + NULL, // binary path: no change + NULL, // load order group: no change + NULL, // tag ID: no change + NULL, // dependencies: no change + NULL, // account name: no change + NULL, // password: no change + NULL) ) // display name: no change + { + MyErrorExit("ChangeServiceConfig"); + } + else + printf("ChangeServiceConfig SUCCESS\n"); + + sdBuf.lpDescription = lpDesc; + + if( !ChangeServiceConfig2( + schService, // handle to service + SERVICE_CONFIG_DESCRIPTION // change: description + &sdBuf) ) // value: new description + { + MyErrorExit("ChangeServiceConfig2"); + } + else + printf("ChangeServiceConfig2 SUCCESS\n"); + + // Release the database lock. + + UnlockServiceDatabase(sclLock); + + // Close the handle to the service. + + CloseServiceHandle(schService); +} +#endif + // SERVICE REMOVE ROUTINE int bacService::RemoveService() @@ -676,7 +815,7 @@ bacService::RemoveService() // How to remove the Bacula service depends upon the OS switch (g_platform_id) { - // Windows 95/98 + // Windows 95/98 case VER_PLATFORM_WIN32_WINDOWS: // Locate the RunService registry entry HKEY runservices; @@ -735,18 +874,17 @@ bacService::RemoveService() ); if (hsrvmanager) { hservice = OpenService(hsrvmanager, BAC_SERVICENAME, SERVICE_ALL_ACCESS); - if (hservice != NULL) - { + if (hservice != NULL) { SERVICE_STATUS status; // Try to stop the Bacula service - if (ControlService(hservice, SERVICE_CONTROL_STOP, &status)) - { + if (ControlService(hservice, SERVICE_CONTROL_STOP, &status)) { while(QueryServiceStatus(hservice, &status)) { - if (status.dwCurrentState == SERVICE_STOP_PENDING) - Sleep(1000); - else - break; + if (status.dwCurrentState == SERVICE_STOP_PENDING) { + Sleep(1000); + } else { + break; + } } if (status.dwCurrentState != SERVICE_STOPPED) @@ -754,20 +892,21 @@ bacService::RemoveService() } // Now remove the service from the SCM - if(DeleteService(hservice)) + if(DeleteService(hservice)) { MessageBox(NULL, "The Bacula service has been removed", szAppName, MB_ICONINFORMATION | MB_OK); - else + } else { MessageBox(NULL, "The Bacula service could not be removed", szAppName, MB_ICONEXCLAMATION | MB_OK); + } CloseServiceHandle(hservice); - } - else + } else { MessageBox(NULL, "The Bacula service could not be found", szAppName, MB_ICONEXCLAMATION | MB_OK); + } CloseServiceHandle(hsrvmanager); - } - else + } else { MessageBox(NULL, "The SCM could not be contacted - the Bacula service was not removed", szAppName, MB_ICONEXCLAMATION | MB_OK); + } break; } return 0; @@ -778,27 +917,25 @@ bacService::RemoveService() // Service control routine void WINAPI ServiceCtrl(DWORD ctrlcode) { - // What control code have we been sent? - switch(ctrlcode) - { - - case SERVICE_CONTROL_STOP: - // STOP : The service must stop - g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING; + // What control code have we been sent? + switch(ctrlcode) { + case SERVICE_CONTROL_STOP: + // STOP : The service must stop + g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING; ServiceStop(); break; case SERVICE_CONTROL_INTERROGATE: - // QUERY : Service control manager just wants to know our state - break; + // QUERY : Service control manager just wants to know our state + break; - default: - // Control code not recognised - break; + default: + // Control code not recognised + break; } - // Tell the control manager what we're up to. + // Tell the control manager what we're up to. ReportStatus(g_srvstatus.dwCurrentState, NO_ERROR, 0); } @@ -812,10 +949,11 @@ BOOL ReportStatus(DWORD state, // If we're in the start state then we don't want the control manager // sending us control messages because they'll confuse us. - if (state == SERVICE_START_PENDING) + if (state == SERVICE_START_PENDING) { g_srvstatus.dwControlsAccepted = 0; - else + } else { g_srvstatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + } // Save the new status we've been given g_srvstatus.dwCurrentState = state; diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index 488ed47fdb..35e8c032f0 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -212,7 +212,7 @@ int set_attributes(void *jcr, char *fname, char *ofile, char *lname, } /* - * Update file times. + * Reset file times. */ if (utime(ofile, &ut) < 0) { Jmsg2(jcr, M_ERROR, 0, "Unable to set file times %s: ERR=%s\n", @@ -253,6 +253,8 @@ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) #ifdef HAVE_CYGWIN +extern int NoGetFileAttributesEx; + int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) { char *p = attribsEx; @@ -261,6 +263,10 @@ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) attribsEx[0] = 0; /* no extended attributes */ + if (NoGetFileAttributesEx) { + return STREAM_UNIX_ATTRIBUTES; + } + unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname); if (!GetFileAttributesEx(ff_pkt->sys_fname, GetFileExInfoStandard, (LPVOID)&atts)) { diff --git a/bacula/src/lib/tcpd.h b/bacula/src/lib/tcpd.h index f281b9cb67..d9f49ec36e 100644 --- a/bacula/src/lib/tcpd.h +++ b/bacula/src/lib/tcpd.h @@ -133,7 +133,7 @@ extern char *eval_user(); /* client user */ extern char *eval_hostname(); /* printable hostname */ extern char *eval_hostaddr(); /* printable host address */ extern char *eval_hostinfo(); /* host name or address */ -extern char *eval_client(); /* whatever is available */ +extern char *eval_client(struct request_info *); /* whatever is available */ extern char *eval_server(); /* whatever is available */ #define eval_daemon(r) ((r)->daemon) /* daemon process name */ #define eval_pid(r) ((r)->pid) /* process id */ diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 3faa66eb0c..7de8be29c7 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -256,8 +256,8 @@ static int unser_block_header(DEVICE *dev, DEV_BLOCK *block) if (BlockCheckSum != CheckSum) { Dmsg2(00, "Block checksum mismatch: calc=%x blk=%x\n", BlockCheckSum, CheckSum); - Mmsg2(&dev->errmsg, _("Block checksum mismatch: calc=%x blk=%x\n"), BlockCheckSum, - CheckSum); + Mmsg3(&dev->errmsg, _("Block checksum mismatch in block %u: calc=%x blk=%x\n"), + (unsigned)BlockNumber, BlockCheckSum, CheckSum); return 0; } } @@ -276,6 +276,7 @@ int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) int stat = 1; lock_device(dev); if (!write_block_to_dev(jcr, dev, block)) { + Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); stat = fixup_device_block_write_error(jcr, dev, block); } unlock_device(dev); @@ -304,6 +305,7 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) /* dump_block(block, "before write"); */ if (dev->state & ST_WEOT) { Dmsg0(100, "return write_block_to_dev with ST_WEOT\n"); + Mmsg0(&dev->errmsg, _("Cannot write block. Device at EOF.\n")); return 0; } wlen = block->binbuf; @@ -348,10 +350,10 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) dev->state |= ST_WEOT; Dmsg0(10, "==== Output bytes Triggered medium max capacity.\n"); if (hit_max1) { - Mmsg2(&dev->errmsg, _("Max. Volume capacity %s exceeded on device %s.\n"), + Mmsg(&dev->errmsg, _("Max. Volume capacity %s exceeded on device %s.\n"), edit_uint64(dev->max_volume_size, ed1), dev->dev_name); } else { - Mmsg2(&dev->errmsg, _("Max. Volume capacity %s exceeded on device %s.\n"), + Mmsg(&dev->errmsg, _("Max. Volume capacity %s exceeded on device %s.\n"), edit_uint64(dev->VolCatInfo.VolCatMaxBytes, ed1), dev->dev_name); } block->failed_write = TRUE; @@ -393,8 +395,13 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Dmsg4(10, "=== Write error. size=%u rtn=%d errno=%d: ERR=%s\n", wlen, stat, dev->dev_errno, strerror(dev->dev_errno)); - Mmsg4(&dev->errmsg, _("Write error on device %s. Write of %u bytes got %d. ERR=%s.\n"), - dev->dev_name, wlen, stat, strerror(dev->dev_errno)); + if (stat == -1) { + Mmsg2(&dev->errmsg, _("Write error on device %s. ERR=%s.\n"), + dev->dev_name, strerror(dev->dev_errno)); + } else { + Mmsg3(&dev->errmsg, _("End of media on device %s. Write of %u bytes got %d.\n"), + dev->dev_name, wlen, stat); + } block->failed_write = TRUE; dev->EndBlock = dev->block_num; dev->EndFile = dev->file; -- 2.39.5