mirror of
https://git.openafs.org/openafs.git
synced 2025-01-20 16:00:12 +00:00
win-power-mgmt-flush-test-20041003
The windows power management code responds to a request to suspend or hibernate by performing a "fs flushvol" as the logged in user on each of the SMB/CIFS mounted shares. This can be very time consuming if the cell servers cannot be reached. This patch adds a test to ensure that there is at least one network adapter in the machine which is not a loopback adapter. While developing this patch other areas of concern have been raised. The power management code waits a fixed period of time based upon the hard dead timeout before allowing the suspend/hibernate to continue. This allows the machine to shutdown even if there are active flush operations being performed. This defeats the benefit of performing the flush at all. A better mechanism could be developed if the functions called via cm_IoctlFlushVolume returned and checked error codes. Then it might be possible to abandon the flush operation if a Server Not Reachable state was obtained. The power management flush operations will also not work on Terminal Server. This would be important in the case where a terminal server is shutting down due to a switch over to a UPS. The reason it does not work on Terminal Server is that there is that it is not possible for afsd_service.exe to enumerate the SMB/CIFS shares and impersonate the individual logged in users. It would be preferred for there to be a new cm_FlushAll() function implemented which was not dependent on the use of the ioctl mechanism for the purpose of identifying a volume ID or a user ID.
This commit is contained in:
parent
3f2e943d43
commit
2469663d0d
@ -27,6 +27,9 @@
|
||||
|
||||
#include "afsd_flushvol.h"
|
||||
#include "afsd_eventlog.h"
|
||||
#include "lanahelper.h"
|
||||
|
||||
extern void afsi_log(char *pattern, ...);
|
||||
|
||||
static FLUSHVOLTHREADINFO gThreadInfo = {0};
|
||||
static HANDLE gThreadHandle = NULL;
|
||||
@ -48,6 +51,7 @@ afsd_ServicePerformFlushVolumeCmd(char *data)
|
||||
register afs_int32 code;
|
||||
struct ViceIoctl blob;
|
||||
|
||||
afsi_log("Flushing Volume \"%s\"",data);
|
||||
memset(&blob, '\0', sizeof(blob));
|
||||
code = pioctl(data, VIOC_FLUSHVOLUME, &blob, 0);
|
||||
|
||||
@ -74,6 +78,11 @@ afsd_ServicePerformFlushVolumes()
|
||||
PCHAR pszShareName, pc;
|
||||
afs_int32 afsRet = 0;
|
||||
|
||||
if ( lana_OnlyLoopback() ) {
|
||||
// Nothing to do if we only have a loopback interface
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Determine the root share name (\\AFS\ALL or \\<machine>-AFS\ALL),
|
||||
// and the length of the server name prefix.
|
||||
pszShareName = smb_GetSharename();
|
||||
@ -143,8 +152,7 @@ afsd_ServicePerformFlushVolumes()
|
||||
{
|
||||
// got one!
|
||||
// but we don't want to flush '\\[...]afs\all'
|
||||
if (_stricmp(lpnr->lpRemoteName,
|
||||
pszShareName) == 0)
|
||||
if (_stricmp(lpnr->lpRemoteName, pszShareName) == 0)
|
||||
continue;
|
||||
++dwTotalVols;
|
||||
|
||||
|
@ -32,7 +32,8 @@
|
||||
// The following is defined if you want to receive Power notifications,
|
||||
// including Hibernation, and also subsequent flushing of AFS volumes
|
||||
//
|
||||
#define REGISTER_POWER_NOTIFICATIONS
|
||||
#define REGISTER_POWER_NOTIFICATIONS 1
|
||||
#define FLUSH_VOLUME 1
|
||||
//
|
||||
// Check
|
||||
*/
|
||||
@ -130,7 +131,6 @@ afsd_ServiceFlushVolume(DWORD dwlpEventData)
|
||||
{
|
||||
dwRet = NO_ERROR;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* flush was unsuccessful, or timeout - deny shutdown */
|
||||
@ -276,7 +276,7 @@ afsd_ServiceControlHandlerEx(
|
||||
case PBT_APMQUERYSUSPEND:
|
||||
case PBT_APMQUERYSTANDBY:
|
||||
|
||||
#ifdef REGISTER_POWER_NOTIFICATIONS
|
||||
#ifdef FLUSH_VOLUME
|
||||
/* handle event */
|
||||
dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData);
|
||||
#else
|
||||
|
@ -394,6 +394,35 @@ extern "C" lana_number_t lana_FindLoopback(void)
|
||||
return LANA_INVALID;
|
||||
}
|
||||
|
||||
/* Returns TRUE if all adapters are loopback adapters */
|
||||
extern "C" BOOL lana_OnlyLoopback(void)
|
||||
{
|
||||
NCB ncb;
|
||||
LANA_ENUM lana_list;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
memset(&ncb, 0, sizeof(ncb));
|
||||
ncb.ncb_command = NCBENUM;
|
||||
ncb.ncb_buffer = (UCHAR *) &lana_list;
|
||||
ncb.ncb_length = sizeof(lana_list);
|
||||
status = Netbios(&ncb);
|
||||
if (status != 0) {
|
||||
#ifndef NOLOGGING
|
||||
afsi_log("Netbios NCBENUM failed: status %ld", status);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
for (i = 0; i < lana_list.length; i++) {
|
||||
if (!lana_IsLoopback(lana_list.lana[i])) {
|
||||
// Found one non-Loopback adapter
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// All adapters are loopback
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Is the given lana a Windows Loopback Adapter?
|
||||
// TODO: implement a better check for loopback
|
||||
// TODO: also check for proper bindings (IPv4)
|
||||
|
@ -59,6 +59,8 @@ extern "C" {
|
||||
|
||||
lana_number_t lana_FindLoopback(void);
|
||||
|
||||
BOOL lana_OnlyLoopback(void);
|
||||
|
||||
BOOL lana_IsLoopback(lana_number_t lana);
|
||||
|
||||
long lana_GetUncServerNameEx(char *buffer, lana_number_t * pLana, int * pIsGateway, int flags);
|
||||
|
Loading…
Reference in New Issue
Block a user