mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-03 15:24:22 +01:00
testing: Add unreliable libc
This commit is contained in:
25
testing/unreliable-libc/Makefile
Normal file
25
testing/unreliable-libc/Makefile
Normal file
@@ -0,0 +1,25 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -fPIC
|
||||
LDFLAGS = -shared
|
||||
TARGET = unreliable-libc.so
|
||||
SRCS = file.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ -ldl
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET)
|
||||
|
||||
install: $(TARGET)
|
||||
install -m 755 $(TARGET) /usr/local/lib
|
||||
|
||||
uninstall:
|
||||
rm -f /usr/local/lib/$(TARGET)
|
||||
91
testing/unreliable-libc/file.c
Normal file
91
testing/unreliable-libc/file.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/uio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
static double probabilities[] = {
|
||||
[ENOSPC] = 0.01,
|
||||
[EIO] = 0.01,
|
||||
};
|
||||
|
||||
static bool chance(double probability)
|
||||
{
|
||||
double event = drand48();
|
||||
return event < probability;
|
||||
}
|
||||
|
||||
static bool inject_fault(int error)
|
||||
{
|
||||
double probability = probabilities[error];
|
||||
if (chance(probability)) {
|
||||
errno = error;
|
||||
return true;
|
||||
}
|
||||
errno = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssize_t (*libc_pwrite) (int, const void *, size_t, off_t);
|
||||
|
||||
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset)
|
||||
{
|
||||
if (libc_pwrite == NULL) {
|
||||
libc_pwrite = dlsym(RTLD_NEXT, "pwrite");
|
||||
}
|
||||
if (inject_fault(ENOSPC)) {
|
||||
printf("%s: injecting fault NOSPC\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (inject_fault(EIO)) {
|
||||
printf("%s: injecting fault EIO\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return libc_pwrite(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
static ssize_t (*libc_pwritev) (int, const struct iovec *, int, off_t);
|
||||
|
||||
ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
|
||||
{
|
||||
if (libc_pwritev == NULL) {
|
||||
libc_pwritev = dlsym(RTLD_NEXT, "pwritev");
|
||||
}
|
||||
if (inject_fault(ENOSPC)) {
|
||||
printf("%s: injecting fault NOSPC\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (inject_fault(EIO)) {
|
||||
printf("%s: injecting fault EIO\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return libc_pwritev(fd, iov, iovcnt, offset);
|
||||
}
|
||||
|
||||
static int (*libc_fsync) (int);
|
||||
|
||||
int fsync(int fd)
|
||||
{
|
||||
if (libc_fsync == NULL) {
|
||||
libc_fsync = dlsym(RTLD_NEXT, "fsync");
|
||||
}
|
||||
if (inject_fault(ENOSPC)) {
|
||||
printf("%s: injecting fault NOSPC\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (inject_fault(EIO)) {
|
||||
printf("%s: injecting fault EIO\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return libc_fsync(fd);
|
||||
}
|
||||
|
||||
__attribute__((constructor))
|
||||
static void init(void)
|
||||
{
|
||||
srand48(time(NULL));
|
||||
}
|
||||
Reference in New Issue
Block a user