/*
* rump server for advanced quota tests
* this one includes functions to run against the filesystem before
* starting to handle rump requests from clients.
*/
static int
quota_test0(const char *testopts)
{
static char buf[512];
int fd;
int error;
unsigned int i;
int chowner = 1;
for (i =0; testopts && i < strlen(testopts); i++) {
switch(testopts[i]) {
case 'C':
chowner = 0;
break;
default:
errx(1, "test4: unknown option %c", testopts[i]);
}
}
if (chowner)
rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
rump_sys_chmod(".", 0777);
if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_setegid");
return error;
}
if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_seteuid");
return error;
}
fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
if (fd < 0) {
error = errno;
warn("rump_sys_open");
} else {
while (rump_sys_write(fd, buf, sizeof(buf)) == sizeof(buf))
error = 0;
error = errno;
}
rump_sys_close(fd);
rump_sys_seteuid(0);
rump_sys_setegid(0);
return error;
}
static int
quota_test1(const char *testopts)
{
static char buf[512];
int fd;
int error;
rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
rump_sys_chmod(".", 0777);
if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_setegid");
return error;
}
if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_seteuid");
return error;
}
fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
if (fd < 0) {
error = errno;
warn("rump_sys_open");
} else {
/*
* write up to the soft limit, wait a bit, and try to
* keep on writing
*/
int i;
/* write 2k: with the directory this makes 2.5K */
for (i = 0; i < 4; i++) {
error = rump_sys_write(fd, buf, sizeof(buf));
if (error != sizeof(buf))
err(1, "write failed early");
}
sleep(2);
/* now try to write an extra .5k */
if (rump_sys_write(fd, buf, sizeof(buf)) != sizeof(buf))
error = errno;
else
error = 0;
}
rump_sys_close(fd);
rump_sys_seteuid(0);
rump_sys_setegid(0);
return error;
}
static int
quota_test2(const char *testopts)
{
static char buf[512];
int fd;
int error;
int i;
rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
rump_sys_chmod(".", 0777);
if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_setegid");
return error;
}
if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_seteuid");
return error;
}
for (i = 0; ; i++) {
sprintf(buf, "file%d", i);
fd = rump_sys_open(buf, O_CREAT | O_RDWR, 0644);
if (fd < 0)
break;
sprintf(buf, "test file no %d", i);
rump_sys_write(fd, buf, strlen(buf));
rump_sys_close(fd);
}
error = errno;
static int
quota_test3(const char *testopts)
{
static char buf[512];
int fd;
int error;
int i;
rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
rump_sys_chmod(".", 0777);
if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_setegid");
return error;
}
if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
error = errno;
warn("rump_sys_seteuid");
return error;
}
/*
* create files one past the soft limit: one less as we already own the
* root directory
*/
for (i = 0; i < 4; i++) {
sprintf(buf, "file%d", i);
fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
if (fd < 0)
err(1, "file create failed early");
sprintf(buf, "test file no %d", i);
rump_sys_write(fd, buf, strlen(buf));
rump_sys_close(fd);
}
/* now create an extra file after grace time: this should fail */
sleep(2);
sprintf(buf, "file%d", i);
fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
if (fd < 0)
error = errno;
else
error = 0;
struct quota_test quota_tests[] = {
{ quota_test0, "write up to hard limit"},
{ quota_test1, "write beyond the soft limit after grace time"},
{ quota_test2, "create file up to hard limit"},
{ quota_test3, "create file beyond the soft limit after grace time"},
{ quota_test4, "take a snapshot and add some data"},
{ quota_test5, "open and unlink a file"},
};