Utility to test atomic writes

This commit is contained in:
Vitaliy Filippov
2025-12-02 01:52:12 +03:00
parent 5607222921
commit 993f40de37
2 changed files with 112 additions and 0 deletions
+4
View File
@@ -78,3 +78,7 @@ add_test(NAME test_blockstore COMMAND test_blockstore)
## test_shit
#add_executable(test_shit test_shit.cpp osd_peering_pg.cpp)
#target_link_libraries(test_shit ${LIBURING_LIBRARIES} m)
# test_atomic
add_executable(test_atomic test_atomic.cpp ../util/ringloop.cpp)
target_link_libraries(test_atomic ${LIBURING_LIBRARIES})
+108
View File
@@ -0,0 +1,108 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <stdexcept>
#include "addr_util.h"
#include "ringloop.h"
#include "epoll_manager.h"
#include "messenger.h"
int main(int narg, char *args[])
{
if (narg < 2)
{
fprintf(stderr, "USAGE: ./test_atomic <device> [--verify]\n");
return 1;
}
uint64_t write_size = 128*1024;
ring_consumer_t looper;
ring_loop_t *ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE);
uint8_t *buf = (uint8_t*)memalign_or_die(4096, write_size);
memset(buf, 0xA7, write_size);
int fd = open(args[1], O_DIRECT|O_RDWR|O_EXCL);
if (fd < 0)
{
perror("open");
return 1;
}
bool verify = narg >= 3 && !strcmp(args[2], "--verify");
fprintf(stderr, "%s %s\n", verify ? "Verifying" : "Writing", args[1]);
int inflight = 0;
uint64_t offset = 0;
uint64_t prev_offset = 0;
looper.loop = [&]()
{
while (inflight < 16 && offset < (uint64_t)50*1000*1024*1024-write_size)
{
io_uring_sqe *sqe = ringloop->get_sqe();
ring_data_t *data = (ring_data_t*)sqe->user_data;
if (!verify)
{
data->iov = { buf, write_size };
io_uring_prep_writev(sqe, fd, &data->iov, 1, offset);
data->callback = [&, offset](ring_data_t *data)
{
if (data->res != write_size)
{
fprintf(stderr, "Error writing at offset %lu: %s (code %d)\n", offset, strerror(-data->res), -data->res);
exit(1);
}
inflight--;
};
}
else
{
uint8_t *buf2 = (uint8_t*)memalign_or_die(4096, write_size);
memset(buf2, 0, write_size);
data->iov = { buf2, write_size };
io_uring_prep_readv(sqe, fd, &data->iov, 1, offset);
data->callback = [&, buf2, offset](ring_data_t *data)
{
if (data->res != write_size)
{
fprintf(stderr, "Error reading at offset %ju: %s (code %d)\n", offset, strerror(-data->res), -data->res);
exit(1);
}
for (uint64_t i = 0; i < write_size; i++)
{
if (buf2[i] != buf2[0])
{
fprintf(stderr, "Atomicity broken at offset %ju+%ju: byte is %02x\n", offset, i, buf2[i]);
exit(1);
}
}
free(buf2);
inflight--;
if (offset >= prev_offset+1024*1024*1024)
{
fprintf(stderr, "Verified at %ju\n", offset);
prev_offset = offset;
}
};
}
offset += write_size + 4096;
inflight++;
}
ringloop->submit();
};
ringloop->register_consumer(&looper);
while (true)
{
ringloop->loop();
ringloop->wait();
}
close(fd);
free(buf);
delete ringloop;
return 0;
}