120 lines
2.0 KiB
C
120 lines
2.0 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
|
|
*/
|
|
|
|
/*
|
|
* Runs several threads that fills up the filesystem repeatedly.
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include "tst_safe_pthread.h"
|
|
#include "tst_test.h"
|
|
|
|
#define MNTPOINT "mntpoint"
|
|
|
|
static volatile int run;
|
|
static unsigned int nthreads;
|
|
static int enospc_cnt;
|
|
static struct worker *workers;
|
|
|
|
struct worker {
|
|
char dir[PATH_MAX];
|
|
};
|
|
|
|
static void *worker(void *p)
|
|
{
|
|
struct worker *w = p;
|
|
DIR *d;
|
|
struct dirent *ent;
|
|
char file[PATH_MAX];
|
|
|
|
while (run) {
|
|
tst_fill_fs(w->dir, 0);
|
|
|
|
tst_atomic_inc(&enospc_cnt);
|
|
|
|
d = SAFE_OPENDIR(w->dir);
|
|
while ((ent = SAFE_READDIR(d))) {
|
|
|
|
if (!strcmp(ent->d_name, ".") ||
|
|
!strcmp(ent->d_name, ".."))
|
|
continue;
|
|
|
|
snprintf(file, sizeof(file), "%s/%s",
|
|
w->dir, ent->d_name);
|
|
|
|
tst_res(TINFO, "Unlinking %s", file);
|
|
|
|
SAFE_UNLINK(file);
|
|
break;
|
|
}
|
|
SAFE_CLOSEDIR(d);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void testrun(void)
|
|
{
|
|
pthread_t threads[nthreads];
|
|
unsigned int i, ms;
|
|
|
|
run = 1;
|
|
for (i = 0; i < nthreads; i++)
|
|
SAFE_PTHREAD_CREATE(&threads[i], NULL, worker, &workers[i]);
|
|
|
|
for (ms = 0; ; ms++) {
|
|
usleep(1000);
|
|
|
|
if (ms >= 1000 && enospc_cnt)
|
|
break;
|
|
|
|
if (enospc_cnt > 100)
|
|
break;
|
|
}
|
|
|
|
run = 0;
|
|
for (i = 0; i < nthreads; i++)
|
|
SAFE_PTHREAD_JOIN(threads[i], NULL);
|
|
|
|
tst_res(TPASS, "Got %i ENOSPC runtime %ims", enospc_cnt, ms);
|
|
}
|
|
|
|
static void setup(void)
|
|
{
|
|
unsigned int i;
|
|
|
|
nthreads = tst_ncpus_conf() + 2;
|
|
workers = SAFE_MALLOC(sizeof(struct worker) * nthreads);
|
|
|
|
for (i = 0; i < nthreads; i++) {
|
|
snprintf(workers[i].dir, sizeof(workers[i].dir),
|
|
MNTPOINT "/thread%i", i + 1);
|
|
SAFE_MKDIR(workers[i].dir, 0700);
|
|
}
|
|
|
|
tst_res(TINFO, "Running %i writer threads", nthreads);
|
|
}
|
|
|
|
static void cleanup(void)
|
|
{
|
|
free(workers);
|
|
}
|
|
|
|
static struct tst_test test = {
|
|
.needs_root = 1,
|
|
.mount_device = 1,
|
|
.mntpoint = MNTPOINT,
|
|
.all_filesystems = 1,
|
|
.setup = setup,
|
|
.cleanup = cleanup,
|
|
.test_all = testrun,
|
|
};
|