Skip to content

Commit 526f96c

Browse files
committed
Add test if FSDAX is mapped with the MAP_SYNC flag
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent fe80d68 commit 526f96c

File tree

5 files changed

+115
-43
lines changed

5 files changed

+115
-43
lines changed

.github/workflows/dax.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ permissions:
2222

2323
env:
2424
UMF_TESTS_DEVDAX_NAMESPACE : "0.0"
25+
UMF_TESTS_FSDAX_NAMESPACE : "1.0"
26+
UMF_TESTS_FSDAX_PATH: "/mnt/pmem1/file"
2527
BUILD_DIR : "${{github.workspace}}/build"
2628
INSTL_DIR : "${{github.workspace}}/../install-dir"
2729

@@ -39,11 +41,21 @@ jobs:
3941
steps:
4042
- name: Check if the devdax exists, print out UMF_TESTS_DEVDAX_PATH and UMF_TESTS_DEVDAX_SIZE
4143
run: |
42-
ndctl list -N --device-dax
44+
echo UMF_TESTS_DEVDAX_NAMESPACE="${UMF_TESTS_DEVDAX_NAMESPACE}"
45+
ndctl list --namespace=namespace${UMF_TESTS_DEVDAX_NAMESPACE} --device-dax
4346
ls -al /dev/dax${UMF_TESTS_DEVDAX_NAMESPACE}
4447
echo UMF_TESTS_DEVDAX_PATH="/dev/dax${UMF_TESTS_DEVDAX_NAMESPACE}"
4548
echo UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${UMF_TESTS_DEVDAX_NAMESPACE} | grep size | cut -d':' -f2 | cut -d',' -f1)"
4649
50+
- name: Check if the FSDAX exists
51+
run: |
52+
echo UMF_TESTS_FSDAX_NAMESPACE="${UMF_TESTS_FSDAX_NAMESPACE}"
53+
echo UMF_TESTS_FSDAX_PATH="${UMF_TESTS_FSDAX_PATH}"
54+
ndctl list --namespace=namespace${UMF_TESTS_FSDAX_NAMESPACE}
55+
ls -al /dev/$(echo $UMF_TESTS_FSDAX_PATH | cut -d'/' -f3)
56+
ls -al /mnt/$(echo $UMF_TESTS_FSDAX_PATH | cut -d'/' -f3)
57+
mount | grep -e "/dev/$(echo $UMF_TESTS_FSDAX_PATH | cut -d'/' -f3)"
58+
4759
- name: Checkout
4860
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
4961
with:
@@ -78,3 +90,7 @@ jobs:
7890
UMF_TESTS_DEVDAX_PATH="/dev/dax${UMF_TESTS_DEVDAX_NAMESPACE}"
7991
UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${UMF_TESTS_DEVDAX_NAMESPACE} | grep size | cut -d':' -f2 | cut -d',' -f1)"
8092
ctest -C ${{matrix.build_type}} -R devdax -V
93+
94+
- name: Run only tests of the file memory provider with FSDAX
95+
working-directory: ${{env.BUILD_DIR}}
96+
run: ctest -C ${{matrix.build_type}} -R umf-provider_file_memory -V

test/common/test_helpers.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44
// This file contains tests for UMF pool API
55

66
#include <assert.h>
7+
#include <fcntl.h>
78
#include <stdio.h>
89
#include <stdlib.h>
910
#include <string.h>
11+
#include <sys/stat.h>
12+
#include <sys/types.h>
13+
#include <unistd.h>
1014

1115
#include "pool_null.h"
1216
#include "pool_trace.h"
@@ -76,3 +80,53 @@ tracePoolCreate(umf_memory_pool_handle_t hUpstreamPool,
7680
assert(ret == UMF_RESULT_SUCCESS);
7781
return hPool;
7882
}
83+
84+
bool is_mapped_with_MAP_SYNC(char *path, char *buf, size_t size_buf) {
85+
memset(buf, 0, size_buf);
86+
87+
int fd = open("/proc/self/smaps", O_RDONLY);
88+
if (fd == -1) {
89+
return false;
90+
}
91+
92+
// number of bytes read from the file
93+
ssize_t nbytes = 1;
94+
// string starting from the path of the smaps
95+
char *smaps = NULL;
96+
97+
// Read the "/proc/self/smaps" file
98+
// until the path of the smaps is found
99+
// or EOF is reached.
100+
while (nbytes > 0 && smaps == NULL) {
101+
memset(buf, 0, nbytes); // erase previous data
102+
nbytes = read(fd, buf, size_buf);
103+
// look for the path of the smaps
104+
smaps = strstr(buf, path);
105+
}
106+
107+
// String starting from the "sf" flag
108+
// marking that memory was mapped with the MAP_SYNC flag.
109+
char *sf_flag = NULL;
110+
111+
if (smaps) {
112+
// look for the "VmFlags:" string
113+
char *VmFlags = strstr(smaps, "VmFlags:");
114+
if (VmFlags) {
115+
// look for the EOL
116+
char *eol = strstr(VmFlags, "\n");
117+
if (eol) {
118+
// End the VmFlags string at EOL.
119+
*eol = 0;
120+
// Now the VmFlags string contains only one line with all VmFlags.
121+
122+
// Look for the "sf" flag in VmFlags
123+
// marking that memory was mapped
124+
// with the MAP_SYNC flag.
125+
sf_flag = strstr(VmFlags, "sf");
126+
}
127+
}
128+
}
129+
130+
// fail if the "sf" flag was not found
131+
return (sf_flag != NULL);
132+
}

test/common/test_helpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ tracePoolCreate(umf_memory_pool_handle_t hUpstreamPool,
9797
umf_memory_provider_handle_t providerDesc, void *trace_context,
9898
trace_handler_t trace_handler);
9999

100+
bool is_mapped_with_MAP_SYNC(char *path, char *buf, size_t size_buf);
101+
100102
#ifdef __cplusplus
101103
}
102104
#endif

test/provider_devdax_memory.cpp

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "base.hpp"
1212

1313
#include "cpp_helpers.hpp"
14+
#include "test_helpers.h"
1415

1516
#include <umf/memory_provider.h>
1617
#include <umf/providers/provider_devdax_memory.h>
@@ -167,56 +168,16 @@ TEST_F(test, test_if_mapped_with_MAP_SYNC) {
167168
umf_result = umfMemoryProviderAlloc(hProvider, size, 0, (void **)&buf);
168169
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
169170
ASSERT_NE(buf, nullptr);
170-
memset(buf, 0, size);
171-
172-
int fd = open("/proc/self/smaps", O_RDONLY);
173-
ASSERT_NE(fd, -1);
174-
175-
// number of bytes read from the file
176-
ssize_t nbytes = 1;
177-
// string starting from the path of the devdax
178-
char *devdax = nullptr;
179-
180-
// Read the "/proc/self/smaps" file
181-
// until the path of the devdax is found
182-
// or EOF is reached.
183-
while (nbytes > 0 && devdax == nullptr) {
184-
memset(buf, 0, nbytes); // erase previous data
185-
nbytes = read(fd, buf, size);
186-
// look for the path of the devdax
187-
devdax = strstr(buf, path);
188-
}
189171

190-
// String starting from the "sf" flag
191-
// marking that memory was mapped with the MAP_SYNC flag.
192-
char *sf_flag = nullptr;
193-
194-
if (devdax) {
195-
// look for the "VmFlags:" string
196-
char *VmFlags = strstr(devdax, "VmFlags:");
197-
if (VmFlags) {
198-
// look for the EOL
199-
char *eol = strstr(VmFlags, "\n");
200-
if (eol) {
201-
// End the VmFlags string at EOL.
202-
*eol = 0;
203-
// Now the VmFlags string contains only one line with all VmFlags.
204-
205-
// Look for the "sf" flag in VmFlags
206-
// marking that memory was mapped
207-
// with the MAP_SYNC flag.
208-
sf_flag = strstr(VmFlags, "sf");
209-
}
210-
}
211-
}
172+
bool flag_found = is_mapped_with_MAP_SYNC(path, buf, size);
212173

213174
umf_result = umfMemoryProviderFree(hProvider, buf, size);
214175
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
215176

216177
umfMemoryProviderDestroy(hProvider);
217178

218179
// fail test if the "sf" flag was not found
219-
ASSERT_NE(sf_flag, nullptr);
180+
ASSERT_EQ(flag_found, true);
220181
}
221182

222183
// positive tests using test_alloc_free_success

test/provider_file_memory.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,45 @@ static void test_alloc_failure(umf_memory_provider_handle_t provider,
121121

122122
// TESTS
123123

124+
// Test checking if FSDAX was mapped with the MAP_SYNC flag:
125+
// 1) Open and read the /proc/self/smaps file.
126+
// 2) Look for the section of the FSDAX file (for example /mnt/pmem1/file path).
127+
// 3) Check if the VmFlags of the /mnt/pmem1/file contains the "sf" flag
128+
// marking that the FSDAX file was mapped with the MAP_SYNC flag.
129+
TEST_F(test, test_if_mapped_with_MAP_SYNC) {
130+
umf_memory_provider_handle_t hProvider = nullptr;
131+
umf_result_t umf_result;
132+
133+
char *path = getenv("UMF_TESTS_FSDAX_PATH");
134+
if (path == nullptr || path[0] == 0) {
135+
GTEST_SKIP() << "Test skipped, UMF_TESTS_FSDAX_PATH is not set";
136+
}
137+
138+
auto params = umfFileMemoryProviderParamsDefault(path);
139+
params.visibility = UMF_MEM_MAP_SYNC;
140+
141+
umf_result = umfMemoryProviderCreate(umfFileMemoryProviderOps(), &params,
142+
&hProvider);
143+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
144+
ASSERT_NE(hProvider, nullptr);
145+
146+
char *buf;
147+
size_t size = 2 * 1024 * 1024; // 2MB
148+
umf_result = umfMemoryProviderAlloc(hProvider, size, 0, (void **)&buf);
149+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
150+
ASSERT_NE(buf, nullptr);
151+
152+
bool flag_found = is_mapped_with_MAP_SYNC(path, buf, size);
153+
154+
umf_result = umfMemoryProviderFree(hProvider, buf, size);
155+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED);
156+
157+
umfMemoryProviderDestroy(hProvider);
158+
159+
// fail test if the "sf" flag was not found
160+
ASSERT_EQ(flag_found, true);
161+
}
162+
124163
// positive tests using test_alloc_free_success
125164

126165
umf_file_memory_provider_params_t get_file_params_shared(char *path) {

0 commit comments

Comments
 (0)