qga: vss-win32: Fix interference with snapshot creation by other VSS requesters
When a VSS requester such as vshadow.exe or diskshadow.exe requests to create disk snapshots, Windows may choose qemu-ga VSS provider if it is only provider registered on the system. However, because it provides only a function to freeze the filesystem, the snapshotting fails. This patch adds a check into CQGAVssProvider::IsVolumeSupported() to reject the request from other VSS requesters, so that the other provider is chosen. The check of requester is done by confirming event channels between qemu-ga's requester and provider established. To ensure that the events are initialized when CQGAVssProvider::IsVolumeSupported() is called, it moves the initialization earlier. Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@hds.com> Reviewed-by: Gal Hammer <ghammer@redhat.com> Reviewed-by: Yan Vugenfirer <yvugenfi@redhat.com> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
		
							parent
							
								
									4c1b8f1e83
								
							
						
					
					
						commit
						ff8adbcfdb
					
				@ -291,8 +291,17 @@ STDMETHODIMP CQGAVssProvider::BeginPrepareSnapshot(
 | 
				
			|||||||
STDMETHODIMP CQGAVssProvider::IsVolumeSupported(
 | 
					STDMETHODIMP CQGAVssProvider::IsVolumeSupported(
 | 
				
			||||||
    VSS_PWSZ pwszVolumeName, BOOL *pbSupportedByThisProvider)
 | 
					    VSS_PWSZ pwszVolumeName, BOOL *pbSupportedByThisProvider)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *pbSupportedByThisProvider = TRUE;
 | 
					    HANDLE hEventFrozen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Check if a requester is qemu-ga by whether an event is created */
 | 
				
			||||||
 | 
					    hEventFrozen = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_FROZEN);
 | 
				
			||||||
 | 
					    if (!hEventFrozen) {
 | 
				
			||||||
 | 
					        *pbSupportedByThisProvider = FALSE;
 | 
				
			||||||
 | 
					        return S_OK;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    CloseHandle(hEventFrozen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *pbSupportedByThisProvider = TRUE;
 | 
				
			||||||
    return S_OK;
 | 
					    return S_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -252,6 +252,32 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    CoInitialize(NULL);
 | 
					    CoInitialize(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Allow unrestricted access to events */
 | 
				
			||||||
 | 
					    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
 | 
				
			||||||
 | 
					    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
 | 
				
			||||||
 | 
					    sa.nLength = sizeof(sa);
 | 
				
			||||||
 | 
					    sa.lpSecurityDescriptor = &sd;
 | 
				
			||||||
 | 
					    sa.bInheritHandle = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vss_ctx.hEventFrozen = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_FROZEN);
 | 
				
			||||||
 | 
					    if (!vss_ctx.hEventFrozen) {
 | 
				
			||||||
 | 
					        err_set(errset, GetLastError(), "failed to create event %s",
 | 
				
			||||||
 | 
					                EVENT_NAME_FROZEN);
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    vss_ctx.hEventThaw = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_THAW);
 | 
				
			||||||
 | 
					    if (!vss_ctx.hEventThaw) {
 | 
				
			||||||
 | 
					        err_set(errset, GetLastError(), "failed to create event %s",
 | 
				
			||||||
 | 
					                EVENT_NAME_THAW);
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    vss_ctx.hEventTimeout = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_TIMEOUT);
 | 
				
			||||||
 | 
					    if (!vss_ctx.hEventTimeout) {
 | 
				
			||||||
 | 
					        err_set(errset, GetLastError(), "failed to create event %s",
 | 
				
			||||||
 | 
					                EVENT_NAME_TIMEOUT);
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(pCreateVssBackupComponents != NULL);
 | 
					    assert(pCreateVssBackupComponents != NULL);
 | 
				
			||||||
    hr = pCreateVssBackupComponents(&vss_ctx.pVssbc);
 | 
					    hr = pCreateVssBackupComponents(&vss_ctx.pVssbc);
 | 
				
			||||||
    if (FAILED(hr)) {
 | 
					    if (FAILED(hr)) {
 | 
				
			||||||
@ -362,32 +388,6 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
 | 
				
			|||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Allow unrestricted access to events */
 | 
					 | 
				
			||||||
    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
 | 
					 | 
				
			||||||
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
 | 
					 | 
				
			||||||
    sa.nLength = sizeof(sa);
 | 
					 | 
				
			||||||
    sa.lpSecurityDescriptor = &sd;
 | 
					 | 
				
			||||||
    sa.bInheritHandle = FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    vss_ctx.hEventFrozen = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_FROZEN);
 | 
					 | 
				
			||||||
    if (!vss_ctx.hEventFrozen) {
 | 
					 | 
				
			||||||
        err_set(errset, GetLastError(), "failed to create event %s",
 | 
					 | 
				
			||||||
                EVENT_NAME_FROZEN);
 | 
					 | 
				
			||||||
        goto out;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    vss_ctx.hEventThaw = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_THAW);
 | 
					 | 
				
			||||||
    if (!vss_ctx.hEventThaw) {
 | 
					 | 
				
			||||||
        err_set(errset, GetLastError(), "failed to create event %s",
 | 
					 | 
				
			||||||
                EVENT_NAME_THAW);
 | 
					 | 
				
			||||||
        goto out;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    vss_ctx.hEventTimeout = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_TIMEOUT);
 | 
					 | 
				
			||||||
    if (!vss_ctx.hEventTimeout) {
 | 
					 | 
				
			||||||
        err_set(errset, GetLastError(), "failed to create event %s",
 | 
					 | 
				
			||||||
                EVENT_NAME_TIMEOUT);
 | 
					 | 
				
			||||||
        goto out;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Start VSS quiescing operations.
 | 
					     * Start VSS quiescing operations.
 | 
				
			||||||
     * CQGAVssProvider::CommitSnapshots will kick vss_ctx.hEventFrozen
 | 
					     * CQGAVssProvider::CommitSnapshots will kick vss_ctx.hEventFrozen
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user