|
2 | 2 | // Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
|
3 | 3 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
4 | 4 |
|
| 5 | +#include <fcntl.h> |
| 6 | +#include <sys/stat.h> |
| 7 | +#include <sys/types.h> |
| 8 | + |
5 | 9 | #include "base.hpp"
|
6 | 10 |
|
7 | 11 | #include "cpp_helpers.hpp"
|
@@ -121,6 +125,85 @@ static void test_alloc_failure(umf_memory_provider_handle_t provider,
|
121 | 125 |
|
122 | 126 | // TESTS
|
123 | 127 |
|
| 128 | +// Test checking if FSDAX was mapped with the MAP_SYNC flag: |
| 129 | +// 1) Open and read the /proc/self/smaps file. |
| 130 | +// 2) Look for the section of the FSDAX file (for example /mnt/pmem1/file path). |
| 131 | +// 3) Check if the VmFlags of the /mnt/pmem1/file contains the "sf" flag |
| 132 | +// marking that the FSDAX file was mapped with the MAP_SYNC flag. |
| 133 | +TEST_F(test, test_if_mapped_with_MAP_SYNC) { |
| 134 | + umf_memory_provider_handle_t hProvider = nullptr; |
| 135 | + umf_result_t umf_result; |
| 136 | + |
| 137 | + char *path = getenv("UMF_TESTS_FSDAX_PATH"); |
| 138 | + if (path == nullptr || path[0] == 0) { |
| 139 | + GTEST_SKIP() << "Test skipped, UMF_TESTS_FSDAX_PATH is not set"; |
| 140 | + } |
| 141 | + |
| 142 | + auto params = umfFileMemoryProviderParamsDefault(path); |
| 143 | + params.visibility = UMF_MEM_MAP_SYNC; |
| 144 | + |
| 145 | + umf_result = umfMemoryProviderCreate(umfFileMemoryProviderOps(), ¶ms, |
| 146 | + &hProvider); |
| 147 | + ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); |
| 148 | + ASSERT_NE(hProvider, nullptr); |
| 149 | + |
| 150 | + char *buf; |
| 151 | + size_t size = 2 * 1024 * 1024; // 2MB |
| 152 | + umf_result = umfMemoryProviderAlloc(hProvider, size, 0, (void **)&buf); |
| 153 | + ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); |
| 154 | + ASSERT_NE(buf, nullptr); |
| 155 | + memset(buf, 0, size); |
| 156 | + |
| 157 | + int fd = open("/proc/self/smaps", O_RDONLY); |
| 158 | + ASSERT_NE(fd, -1); |
| 159 | + |
| 160 | + // number of bytes read from the file |
| 161 | + ssize_t nbytes = 1; |
| 162 | + // string starting from the path of the devdax |
| 163 | + char *devdax = nullptr; |
| 164 | + |
| 165 | + // Read the "/proc/self/smaps" file |
| 166 | + // until the path of the devdax is found |
| 167 | + // or EOF is reached. |
| 168 | + while (nbytes > 0 && devdax == nullptr) { |
| 169 | + memset(buf, 0, nbytes); // erase previous data |
| 170 | + nbytes = read(fd, buf, size); |
| 171 | + // look for the path of the devdax |
| 172 | + devdax = strstr(buf, path); |
| 173 | + } |
| 174 | + |
| 175 | + // String starting from the "sf" flag |
| 176 | + // marking that memory was mapped with the MAP_SYNC flag. |
| 177 | + char *sf_flag = nullptr; |
| 178 | + |
| 179 | + if (devdax) { |
| 180 | + // look for the "VmFlags:" string |
| 181 | + char *VmFlags = strstr(devdax, "VmFlags:"); |
| 182 | + if (VmFlags) { |
| 183 | + // look for the EOL |
| 184 | + char *eol = strstr(VmFlags, "\n"); |
| 185 | + if (eol) { |
| 186 | + // End the VmFlags string at EOL. |
| 187 | + *eol = 0; |
| 188 | + // Now the VmFlags string contains only one line with all VmFlags. |
| 189 | + |
| 190 | + // Look for the "sf" flag in VmFlags |
| 191 | + // marking that memory was mapped |
| 192 | + // with the MAP_SYNC flag. |
| 193 | + sf_flag = strstr(VmFlags, "sf"); |
| 194 | + } |
| 195 | + } |
| 196 | + } |
| 197 | + |
| 198 | + umf_result = umfMemoryProviderFree(hProvider, buf, size); |
| 199 | + ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED); |
| 200 | + |
| 201 | + umfMemoryProviderDestroy(hProvider); |
| 202 | + |
| 203 | + // fail test if the "sf" flag was not found |
| 204 | + ASSERT_NE(sf_flag, nullptr); |
| 205 | +} |
| 206 | + |
124 | 207 | // positive tests using test_alloc_free_success
|
125 | 208 |
|
126 | 209 | umf_file_memory_provider_params_t get_file_params_shared(char *path) {
|
|
0 commit comments