]> git.ipfire.org Git - thirdparty/git.git/blob - t/helper/test-drop-caches.c
commit.c: allow lookup_commit_reference to handle arbitrary repositories
[thirdparty/git.git] / t / helper / test-drop-caches.c
1 #include "test-tool.h"
2 #include "git-compat-util.h"
3
4 #if defined(GIT_WINDOWS_NATIVE)
5 #include "lazyload.h"
6
7 static int cmd_sync(void)
8 {
9 char Buffer[MAX_PATH];
10 DWORD dwRet;
11 char szVolumeAccessPath[] = "\\\\.\\X:";
12 HANDLE hVolWrite;
13 int success = 0;
14
15 dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
16 if ((0 == dwRet) || (dwRet > MAX_PATH))
17 return error("Error getting current directory");
18
19 if ((Buffer[0] < 'A') || (Buffer[0] > 'Z'))
20 return error("Invalid drive letter '%c'", Buffer[0]);
21
22 szVolumeAccessPath[4] = Buffer[0];
23 hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
24 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
25 if (INVALID_HANDLE_VALUE == hVolWrite)
26 return error("Unable to open volume for writing, need admin access");
27
28 success = FlushFileBuffers(hVolWrite);
29 if (!success)
30 error("Unable to flush volume");
31
32 CloseHandle(hVolWrite);
33
34 return !success;
35 }
36
37 #define STATUS_SUCCESS (0x00000000L)
38 #define STATUS_PRIVILEGE_NOT_HELD (0xC0000061L)
39
40 typedef enum _SYSTEM_INFORMATION_CLASS {
41 SystemMemoryListInformation = 80,
42 } SYSTEM_INFORMATION_CLASS;
43
44 typedef enum _SYSTEM_MEMORY_LIST_COMMAND {
45 MemoryCaptureAccessedBits,
46 MemoryCaptureAndResetAccessedBits,
47 MemoryEmptyWorkingSets,
48 MemoryFlushModifiedList,
49 MemoryPurgeStandbyList,
50 MemoryPurgeLowPriorityStandbyList,
51 MemoryCommandMax
52 } SYSTEM_MEMORY_LIST_COMMAND;
53
54 static BOOL GetPrivilege(HANDLE TokenHandle, LPCSTR lpName, int flags)
55 {
56 BOOL bResult;
57 DWORD dwBufferLength;
58 LUID luid;
59 TOKEN_PRIVILEGES tpPreviousState;
60 TOKEN_PRIVILEGES tpNewState;
61
62 dwBufferLength = 16;
63 bResult = LookupPrivilegeValueA(0, lpName, &luid);
64 if (bResult) {
65 tpNewState.PrivilegeCount = 1;
66 tpNewState.Privileges[0].Luid = luid;
67 tpNewState.Privileges[0].Attributes = 0;
68 bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpNewState,
69 (DWORD)((LPBYTE)&(tpNewState.Privileges[1]) - (LPBYTE)&tpNewState),
70 &tpPreviousState, &dwBufferLength);
71 if (bResult) {
72 tpPreviousState.PrivilegeCount = 1;
73 tpPreviousState.Privileges[0].Luid = luid;
74 tpPreviousState.Privileges[0].Attributes = flags != 0 ? 2 : 0;
75 bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpPreviousState,
76 dwBufferLength, 0, 0);
77 }
78 }
79 return bResult;
80 }
81
82 static int cmd_dropcaches(void)
83 {
84 HANDLE hProcess = GetCurrentProcess();
85 HANDLE hToken;
86 DECLARE_PROC_ADDR(ntdll.dll, DWORD, NtSetSystemInformation, INT, PVOID, ULONG);
87 SYSTEM_MEMORY_LIST_COMMAND command;
88 int status;
89
90 if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
91 return error("Can't open current process token");
92
93 if (!GetPrivilege(hToken, "SeProfileSingleProcessPrivilege", 1))
94 return error("Can't get SeProfileSingleProcessPrivilege");
95
96 CloseHandle(hToken);
97
98 if (!INIT_PROC_ADDR(NtSetSystemInformation))
99 return error("Could not find NtSetSystemInformation() function");
100
101 command = MemoryPurgeStandbyList;
102 status = NtSetSystemInformation(
103 SystemMemoryListInformation,
104 &command,
105 sizeof(SYSTEM_MEMORY_LIST_COMMAND)
106 );
107 if (status == STATUS_PRIVILEGE_NOT_HELD)
108 error("Insufficient privileges to purge the standby list, need admin access");
109 else if (status != STATUS_SUCCESS)
110 error("Unable to execute the memory list command %d", status);
111
112 return status;
113 }
114
115 #elif defined(__linux__)
116
117 static int cmd_sync(void)
118 {
119 return system("sync");
120 }
121
122 static int cmd_dropcaches(void)
123 {
124 return system("echo 3 | sudo tee /proc/sys/vm/drop_caches");
125 }
126
127 #elif defined(__APPLE__)
128
129 static int cmd_sync(void)
130 {
131 return system("sync");
132 }
133
134 static int cmd_dropcaches(void)
135 {
136 return system("sudo purge");
137 }
138
139 #else
140
141 static int cmd_sync(void)
142 {
143 return 0;
144 }
145
146 static int cmd_dropcaches(void)
147 {
148 return error("drop caches not implemented on this platform");
149 }
150
151 #endif
152
153 int cmd__drop_caches(int argc, const char **argv)
154 {
155 cmd_sync();
156 return cmd_dropcaches();
157 }