Intel® MPI Library
Get help with building, analyzing, optimizing, and scaling high-performance computing (HPC) applications.

Update: no Windows privileges when running MPI

Greg_G_
Beginner
1,483 Views

I am creating a MPI transfer application to move data between two programs working together on a local area network, but initial testing I am running the tests on a single computer with 2 processes. I still feel new to MPI, but experienced programmer in other fields. 

If running from the console with the flag -localonly it works on a single machine. But when using a command like "mpiexec -n 2 -ppn 1 -hosts PC1,PC2 code.exe" I get Error Access is denied for the action OpenFileMappingA. I am running in an Administrator cmd window.

Windows code below:

HANDLE sMemHandle = OpenFileMappingA(PAGE_READWRITE, FALSE, "Global\\ComputeSharedMem");
LPVOID baseAddress = MapViewOfFile(sMemHandle , FILE_MAP_READ, 0, 0, sharedMemSize);

It states SeCreateGlobalPrivilege is needed which the cmd says is enabled only when running as "-localonly" I added code to check the privileges at run time and it shows when running mpiexec it does not have privileges. 

C:\Folder>mpiexec -n 2 -localonly MPICode.exe
Rank1: Hello world: rank 1 of 2 running on PC1.local
Rank1: Location count: 0
Rank0: Starting
LsaOpenPolicy: The operation completed successfully.

LsaEnumerateAccountRights: The operation completed successfully.

LsaEnumerateAccountRights Called Printing Below:
Name: SeSecurityPrivilege
Name: SeBackupPrivilege
Name: SeRestorePrivilege
Name: SeSystemtimePrivilege
Name: SeShutdownPrivilege
Name: SeRemoteShutdownPrivilege
Name: SeTakeOwnershipPrivilege
Name: SeDebugPrivilege
Name: SeSystemEnvironmentPrivilege
Name: SeSystemProfilePrivilege
Name: SeProfileSingleProcessPrivilege
Name: SeIncreaseBasePriorityPrivilege
Name: SeLoadDriverPrivilege
Name: SeCreatePagefilePrivilege
Name: SeIncreaseQuotaPrivilege
Name: SeUndockPrivilege
Name: SeManageVolumePrivilege
Name: SeImpersonatePrivilege
Name: SeCreateGlobalPrivilege
Name: SeTimeZonePrivilege
Name: SeCreateSymbolicLinkPrivilege
Name: SeChangeNotifyPrivilege
Name: SeInteractiveLogonRight
Name: SeNetworkLogonRight
Name: SeBatchLogonRight
Name: SeRemoteInteractiveLogonRight

Rank0: sMemHand_MPIBool: The operation completed successfully.


C:\Folder>mpiexec -n 2 -ppn 1 -hosts PC1,PC2 MPICode.exe
Rank1: Hello world: rank 1 of 2 running on PC2.local
Rank1: Location count: 0
Rank0: Starting
LsaOpenPolicy: The operation completed successfully.

LsaEnumerateAccountRights: Error: Access is denied.

LsaEnumerateAccountRights Called Printing Below:
No rights D: uh oh
Rank0: sMemHand_MPIBool: Error: Access is denied.


C:\Folder>

Posted here because I intend to use Intel MPI for the final code, and the error only occurs when using MPI. However, I am starting to think it might be more windows permissions related. So I have recently (two days after posting here with no response) posted on Microsoft's parallel computing forms. https://social.msdn.microsoft.com/Forums/windowsapps/en-US/7fd45ecf-2f23-41b1-8477-0a274c2ea7b9/error-with-openfilemapping-from-an-mpi-program?forum=parallelcppnative

Thank you in advance

 

0 Kudos
8 Replies
Artem_R_Intel1
Employee
1,483 Views

Hi Greg,

Have you launched 'mpiexec -register' before the MPI run?

Could you please also check the firewall status? If it's enabled try the same MPI scenario with disabled firewall (or add the appropriate permissions for MPI executables).

0 Kudos
Greg_G_
Beginner
1,483 Views

Yes I have run -register. 

The firewall has exceptions for the program too. 

If I comment out all of the privilege checking and Named shared memory operations the code runs with no errors.

I don't think it is truly an MPI error, just a problem with having windows administrators privileges when using mpiexec. It reports being an admin though. 

0 Kudos
Artem_R_Intel1
Employee
1,483 Views

Hi Greg,

Could you please provide your program (if possible) to reproduce the problem?

0 Kudos
Greg_G_
Beginner
1,483 Views
//This code is a proof of concept, not yet functional for the intended purpose 
#include "mpi.h"
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <conio.h>
#include <tchar.h>
#include <WinBase.h>
#include <atlstr.h>
#include <Strsafe.h>
#include <Ntsecapi.h>

void ErrorExit(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPTSTR lpMsgBuf = NULL;
	CString error;
    DWORD dw = GetLastError(); 

    int length = FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf,
        0, NULL );

	if(dw == 0)
		printf("%s: %s\n", lpszFunction, lpMsgBuf);
	else
		printf("%s: Error: %s\n", lpszFunction, lpMsgBuf);
	
    LocalFree(lpMsgBuf);
    //ExitProcess(dw); 
}
void ErrorExit(ULONG dd) 
{ 
    // Retrieve the system error message for the last-error code

    LPTSTR lpMsgBuf = NULL;
	CString error;
    DWORD dw = dd; 

    int length = FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf,
        0, NULL );

	
	if(dw == 0)
		printf("%s\n", lpMsgBuf);
	else
		printf("Error: %s\n", lpMsgBuf);

    LocalFree(lpMsgBuf);
    //ExitProcess(dw); 
}
BOOL ConvertNameToSid(LPWSTR lpszName, PSID *ppSid)
{
	WCHAR        szDomainName[256];
	DWORD        dwSizeDomain = sizeof(szDomainName) / sizeof(WCHAR);
	DWORD        dwSizeSid = 0;
	SID_NAME_USE sidName;

	LookupAccountNameW(NULL, lpszName, NULL, &dwSizeSid, szDomainName, &dwSizeDomain, &sidName);
	
	*ppSid = (PSID)LocalAlloc(LPTR, dwSizeSid);

	return LookupAccountNameW(NULL, lpszName, *ppSid, &dwSizeSid, szDomainName, &dwSizeDomain, &sidName);
}
BOOL IsAdmin(void)
{
	HANDLE hAccessToken;
	UCHAR InfoBuffer[1024];
	PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer;
	DWORD dwInfoBufferSize;
	PSID psidAdministrators;
	SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
	UINT x;
	BOOL bSuccess;

	if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,
		&hAccessToken )) {
			if(GetLastError() != ERROR_NO_TOKEN)
				return FALSE;
			//
			// retry against process token if no thread token exists
			//
			if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
				&hAccessToken))
				return FALSE;
	}

	bSuccess = GetTokenInformation(hAccessToken,TokenGroups,InfoBuffer,
		1024, &dwInfoBufferSize);

	CloseHandle(hAccessToken);

	if(!bSuccess )
		return FALSE;

	if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
		SECURITY_BUILTIN_DOMAIN_RID,
		DOMAIN_ALIAS_RID_ADMINS,
		0, 0, 0, 0, 0, 0,
		&psidAdministrators))
		return FALSE;

	// assume that we don't find the admin SID.
	bSuccess = FALSE;

	for(x=0;x<ptgGroups->GroupCount;x++)
	{
		if( EqualSid(psidAdministrators, ptgGroups->Groups.Sid) )
		{
			bSuccess = TRUE;
			break;
		}

	}
	FreeSid(psidAdministrators);
	return bSuccess;
}
void InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
{
    DWORD StringLength;

    if (String == NULL) {
        LsaString->Buffer = NULL;
        LsaString->Length = 0;
        LsaString->MaximumLength = 0;
        return;
    }

    StringLength = wcslen(String);
    LsaString->Buffer = String;
    LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
    LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
}
BOOL EnumerateAccountRights(LSA_HANDLE hPolicy, LPWSTR lpszAccount)
{
	ULONG               i;
	ULONG               uCount;
	PSID                pSid;
	WCHAR               szBuf[256];
	NTSTATUS            ns;
	PLSA_UNICODE_STRING plsaString;

	ConvertNameToSid(lpszAccount, &pSid);

	ns = LsaEnumerateAccountRights(hPolicy, pSid, &plsaString, &uCount);
	printf("LsaEnumerateAccountRights: "); ErrorExit(LsaNtStatusToWinError(ns));
	
	printf("LsaEnumerateAccountRights Called Printing Below:\n");
	for (i = 0; i < uCount; i++) {
		//lstrcpynW(szBuf, plsaString.Buffer, (plsaString.Length / sizeof(WCHAR)) + 1);
		wprintf(L"Name: %s\n", plsaString.Buffer);
		//SendMessageW(hwndListBox, LB_ADDSTRING, 0, (LPARAM)szBuf);
	}
	if(uCount == 0){
		printf("No rights D: uh oh");
	}
	printf ("\n");
	LsaFreeMemory(plsaString);
	LocalFree(pSid);

	return TRUE;
}
int main (int argc, char *argv[])
{
    int rank, size, namelen;
    char name[MPI_MAX_PROCESSOR_NAME];
    MPI::Status stat;

    MPI::Init (argc, argv);

    size = MPI::COMM_WORLD.Get_size ();
    rank = MPI::COMM_WORLD.Get_rank ();
    MPI::Get_processor_name (name, namelen);

	if (rank == 1) {
		printf ("Rank1: Hello world: rank %d of %d running on %s\n", rank, size, name);
		
		//   Currently rank 1 is empty, but later both ranks will use windows shared memory
		int segCount = 0; int rankRecv = 0;
		MPI::COMM_WORLD.Recv (&rank, 1, MPI_INT, rankRecv, 1, stat);
	    MPI::COMM_WORLD.Recv (&size, 1, MPI_INT, rankRecv, 1, stat);
	    MPI::COMM_WORLD.Recv (&namelen, 1, MPI_INT, rankRecv, 1, stat);
	    MPI::COMM_WORLD.Recv (name, namelen + 1, MPI_CHAR, rankRecv, 1, stat);
		MPI::COMM_WORLD.Recv (&segCount, 1, MPI_INT, rankRecv, 1, stat);
		//==============================================================================
		printf ("Rank1: Location count: %d \n", segCount);


	} else {
		printf ("Rank0: Starting\n");
		
		//  Checking Windows Privileges
		NTSTATUS              ns;
		LSA_HANDLE            hPolicy;
		LSA_OBJECT_ATTRIBUTES objectAttributes;
		BOOL                  bEnumPrivilege = TRUE;
		ZeroMemory(&objectAttributes, sizeof(LSA_OBJECT_ATTRIBUTES));
		objectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
		ns = LsaOpenPolicy(NULL, &objectAttributes, POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES, &hPolicy);
		printf("LsaOpenPolicy: ");ErrorExit(LsaNtStatusToWinError(ns));
		EnumerateAccountRights(hPolicy, L"Administrators");
		LsaClose(hPolicy);
		
		//   Checking if it is running as an Administrator
		bool isAdminKa = IsAdmin();
		printf("Is a admin: %d\n",  isAdminKa);
		
		//   To be functional code 
		const int boolCount = 17;
		size_t sharedMemSize_MPIBool = boolCount*sizeof(int);
		int MPIBool[boolCount] = {0};
		
		// When using mpiexec Access is denied
		HANDLE sMemHand_MPIBool = OpenFileMappingA(PAGE_READWRITE, FALSE, "Global\\ComputeShared_MPIBool");
		ErrorExit(TEXT("Rank0: sMemHand_MPIBool"));
		
		// If uncommented the code below creates strange mpi errors because the above failed
		/*LPVOID baseAddress_MPIBool = MapViewOfFile(sMemHand_MPIBool, FILE_MAP_READ, 0, 0, sharedMemSize_MPIBool); //(LPVOID)0x0000000000190000; 
		ErrorExit(TEXT("Rank0: baseAddress_MPIBool"));
		CopyMemory(MPIBool, baseAddress_MPIBool, sharedMemSize_MPIBool);
		printf ("Rank0: Some MPIBool(int): (%d, %d, %d) \n", MPIBool[0],MPIBool[1],MPIBool[2]);
		UnmapViewOfFile(baseAddress_MPIBool);*/
		CloseHandle(sMemHand_MPIBool);
		
		//  Other to be shared data, that one host will update and send for the other to use
		/*float * host_segLocations = new float[MPIBool[0]*3]; // Delete
		size_t sharedMemSize_Loc = MPIBool[0]*3*sizeof(float);
		HANDLE sMemHand_Loc = OpenFileMapping(PAGE_READWRITE, FALSE, "Global\\ComputeShared_Loc");
		ErrorExit(TEXT("Rank0: sharedMemSize_Loc"));
		LPVOID baseAddress_Loc = MapViewOfFile(sMemHand_Loc, FILE_MAP_READ, 0, 0, sharedMemSize_Loc);
		ErrorExit(TEXT("Rank0: baseAddress_Loc"));
		CopyMemory(host_segLocations, baseAddress_Loc, sharedMemSize_Loc);
		printf ("Rank0: Some Locations: (%3.2f, %3.2f, %3.2f) sharedMemSize_Loc: %d\n", host_segLocations[0],host_segLocations[1],host_segLocations[2], sharedMemSize_Loc);
		UnmapViewOfFile(baseAddress_Loc);
		CloseHandle(sMemHand_Loc);
		
		*/
		
		//Code mostly from Intel Example
		int rankSend = 1;
		MPI::COMM_WORLD.Send (&rank, 1, MPI_INT, rankSend, 1);
		MPI::COMM_WORLD.Send (&size, 1, MPI_INT, rankSend, 1);
		MPI::COMM_WORLD.Send (&namelen, 1, MPI_INT, rankSend, 1);
		MPI::COMM_WORLD.Send (name, namelen + 1, MPI_CHAR, rankSend, 1);
		MPI::COMM_WORLD.Send (&MPIBool[0], 1, MPI_INT, rankSend, 1);
		
	}

	MPI::Finalize ();

	return (0);
}
0 Kudos
Sergey_O_Intel
Employee
1,483 Views

hi Greg

as I can see you are using OpenFileMapping function which just opens existing file mapping, but your program doesn't create new one. as you noticed in original post you launched your application on different PC's. is it possible that on some PC's there is no created file mapping? note that CreateFileMapping function creates file mapping on current PC only (not cluster or domain wide). could it be reason of program failure?

thank you for your post

--Sergey

0 Kudos
Greg_G_
Beginner
1,483 Views

Hello Sergey, 

You're welcome. Also, a lot of the code above is hard to find there are lots of forms trying to figure out how to check privileges. I found parts of that code on Microsofts Japanese pages. 

 

When I forget to start the other program it reports "Rank0: sMemHand_MPIBool: Error: The system cannot find the file specified." insted of "Rank0: sMemHand_MPIBool: Error: Access is denied." when running localonly. 

So if it was failing due to not finding the mapped file that would be the error. 

C:\Folder>mpiexec -n 2 -localonly MPICode.exe
Rank1: Hello world: rank 1 of 2 running on PC1.local
Rank1: Location count: 0
Rank0: Starting
LsaOpenPolicy: The operation completed successfully.

LsaEnumerateAccountRights: The operation completed successfully.

LsaEnumerateAccountRights Called Printing Below:
Name: SeSecurityPrivilege
Name: SeBackupPrivilege
Name: SeRestorePrivilege
Name: SeSystemtimePrivilege
Name: SeShutdownPrivilege
Name: SeRemoteShutdownPrivilege
Name: SeTakeOwnershipPrivilege
Name: SeDebugPrivilege
Name: SeSystemEnvironmentPrivilege
Name: SeSystemProfilePrivilege
Name: SeProfileSingleProcessPrivilege
Name: SeIncreaseBasePriorityPrivilege
Name: SeLoadDriverPrivilege
Name: SeCreatePagefilePrivilege
Name: SeIncreaseQuotaPrivilege
Name: SeUndockPrivilege
Name: SeManageVolumePrivilege
Name: SeImpersonatePrivilege
Name: SeCreateGlobalPrivilege
Name: SeTimeZonePrivilege
Name: SeCreateSymbolicLinkPrivilege
Name: SeChangeNotifyPrivilege
Name: SeInteractiveLogonRight
Name: SeNetworkLogonRight
Name: SeBatchLogonRight
Name: SeRemoteInteractiveLogonRight

The operation completed successfully.

Accounts with SeCreateGlobalPrivilege enabled
Name: SERVICE
Name: Administrators
Name: NETWORK SERVICE
Name: LOCAL SERVICE

Is admin: 1
Rank0: sMemHand_MPIBool: Error: The system cannot find the file specified.

Then when running on two hosts it reports the lines below, same error pattern. The privilege errors are problems, but the key line is the one with sMemHand_MPIBool

First section is when not running the program to create the shared memory. Second section is when the program to create the shared memory is started first. (PC1 is the computer that Im currently using to test shared memory)

C:\Folder>mpiexec -n 2 -ppn 1 -hosts PC1,PC2 MPICode.exe
Rank0: Starting
LsaOpenPolicy: The operation completed successfully.

LsaEnumerateAccountRights: Error: Access is denied.

LsaEnumerateAccountRights Called Printing Below:
No rights D: uh oh

Error: Access is denied.

Accounts with SeCreateGlobalPrivilege enabled
No Accounts with rights...

Is admin: 1
Rank0: sMemHand_MPIBool: Error: The system cannot find the file specified.

Rank1: Hello world: rank 1 of 2 running on PC2.local
Rank1: Location count: 0

###########################################################################

C:\Folder>mpiexec -n 2 -ppn 1 -hosts PC1,PC2 MPICode.exe
Rank1: Hello world: rank 1 of 2 running on PC2.local
Rank1: Location count: 0
Rank0: Starting
LsaOpenPolicy: The operation completed successfully.

LsaEnumerateAccountRights: Error: Access is denied.

LsaEnumerateAccountRights Called Printing Below:
No rights D: uh oh

Error: Access is denied.

Accounts with SeCreateGlobalPrivilege enabled
No Accounts with rights...

Is admin: 1
Rank0: sMemHand_MPIBool: Error: Access is denied.

 

0 Kudos
Greg_G_
Beginner
1,483 Views

Is this an intended functionality of of MPI to remove windows privileges or is this an error? 

0 Kudos
Greg_G_
Beginner
1,483 Views

I've come to the conclusion that maybe MPI is not a viable solution for my problem. I have decided to use socket programming. 

 

Thanks for the help though,

Greg

0 Kudos
Reply