Home | History | Annotate | Line # | Download | only in ffs
h_quota2_tests.c revision 1.1.2.3
      1 /*	$NetBSD: h_quota2_tests.c,v 1.1.2.3 2011/02/07 16:22:50 bouyer Exp $	*/
      2 
      3 /*
      4  * rump server for advanced quota tests
      5  * this one includes functions to run against the filesystem before
      6  * starting to handle rump requests from clients.
      7  */
      8 
      9 #include "../common/h_fsmacros.h"
     10 
     11 #include <err.h>
     12 #include <semaphore.h>
     13 #include <sys/types.h>
     14 #include <sys/mount.h>
     15 
     16 #include <stdlib.h>
     17 #include <unistd.h>
     18 
     19 #include <ufs/ufs/ufsmount.h>
     20 
     21 #include <rump/rump.h>
     22 #include <rump/rump_syscalls.h>
     23 
     24 #include "../../h_macros.h"
     25 
     26 int background = 0;
     27 
     28 #define TEST_NONROOT_ID 1
     29 
     30 static int
     31 quota_test0(void)
     32 {
     33 	static char buf[512];
     34 	int fd;
     35 	int error;
     36 	rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
     37 	if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
     38 		error = errno;
     39 		perror("rump_sys_setegid");
     40 		return error;
     41 	}
     42 	if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
     43 		error = errno;
     44 		perror("rump_sys_seteuid");
     45 		return error;
     46 	}
     47 	fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
     48 	if (fd < 0) {
     49 		error = errno;
     50 		perror("rump_sys_open");
     51 	} else {
     52 		while (rump_sys_write(fd, buf, sizeof(buf)) == sizeof(buf))
     53 			error = 0;
     54 		error = errno;
     55 	}
     56 	rump_sys_close(fd);
     57 	rump_sys_seteuid(0);
     58 	rump_sys_setegid(0);
     59 	return error;
     60 }
     61 
     62 static int
     63 quota_test1(void)
     64 {
     65 	static char buf[512];
     66 	int fd;
     67 	int error;
     68 	rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
     69 	if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
     70 		error = errno;
     71 		perror("rump_sys_setegid");
     72 		return error;
     73 	}
     74 	if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
     75 		error = errno;
     76 		perror("rump_sys_seteuid");
     77 		return error;
     78 	}
     79 	fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
     80 	if (fd < 0) {
     81 		error = errno;
     82 		perror("rump_sys_open");
     83 	} else {
     84 		/*
     85 		 * write up to the soft limit, wait a bit, an try to
     86 		 * keep on writing
     87 		 */
     88 		int i;
     89 
     90 		/* write 2k: with the directory this makes 2.5K */
     91 		for (i = 0; i < 4; i++) {
     92 			error = rump_sys_write(fd, buf, sizeof(buf));
     93 			if (error != sizeof(buf))
     94 				err(1, "write failed early");
     95 		}
     96 		sleep(2);
     97 		/* now try to write an extra .5k */
     98 		if (rump_sys_write(fd, buf, sizeof(buf)) != sizeof(buf))
     99 			error = errno;
    100 		else
    101 			error = 0;
    102 	}
    103 	rump_sys_close(fd);
    104 	rump_sys_seteuid(0);
    105 	rump_sys_setegid(0);
    106 	return error;
    107 }
    108 
    109 static int
    110 quota_test2(void)
    111 {
    112 	static char buf[512];
    113 	int fd;
    114 	int error;
    115 	int i;
    116 	rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
    117 	if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
    118 		error = errno;
    119 		perror("rump_sys_setegid");
    120 		return error;
    121 	}
    122 	if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
    123 		error = errno;
    124 		perror("rump_sys_seteuid");
    125 		return error;
    126 	}
    127 
    128 	for (i = 0; ; i++) {
    129 		sprintf(buf, "file%d", i);
    130 		fd = rump_sys_open(buf, O_CREAT | O_RDWR, 0644);
    131 		if (fd < 0)
    132 			break;
    133 		sprintf(buf, "test file no %d", i);
    134 		rump_sys_write(fd, buf, strlen(buf));
    135 		rump_sys_close(fd);
    136 	}
    137 	error = errno;
    138 
    139 	rump_sys_close(fd);
    140 	rump_sys_seteuid(0);
    141 	rump_sys_setegid(0);
    142 	return error;
    143 }
    144 
    145 static int
    146 quota_test3(void)
    147 {
    148 	static char buf[512];
    149 	int fd;
    150 	int error;
    151 	int i;
    152 	rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
    153 	if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
    154 		error = errno;
    155 		perror("rump_sys_setegid");
    156 		return error;
    157 	}
    158 	if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
    159 		error = errno;
    160 		perror("rump_sys_seteuid");
    161 		return error;
    162 	}
    163 
    164 	/*
    165 	 * create files one past the soft limit: one less as we already own the
    166 	 * root directory
    167 	 */
    168 	for (i = 0; i < 4; i++) {
    169 		sprintf(buf, "file%d", i);
    170 		fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
    171 		if (fd < 0)
    172 			err(1, "file create failed early");
    173 		sprintf(buf, "test file no %d", i);
    174 		rump_sys_write(fd, buf, strlen(buf));
    175 		rump_sys_close(fd);
    176 	}
    177 	/* now create an extra file after grace time: this should fail */
    178 	sleep(2);
    179 	sprintf(buf, "file%d", i);
    180 	fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
    181 	if (fd < 0)
    182 		error = errno;
    183 	else
    184 		error = 0;
    185 
    186 	rump_sys_close(fd);
    187 	rump_sys_seteuid(0);
    188 	rump_sys_setegid(0);
    189 	return error;
    190 }
    191 
    192 struct quota_test {
    193 	int (*func)(void);
    194 	const char *desc;
    195 };
    196 
    197 struct quota_test quota_tests[] = {
    198 	{ quota_test0, "write up to hard limit"},
    199 	{ quota_test1, "write beyond the soft limit after grace time"},
    200 	{ quota_test2, "create file up to hard limit"},
    201 	{ quota_test3, "create file beyond the soft limit after grace time"},
    202 };
    203 
    204 static void
    205 usage(void)
    206 {
    207 	fprintf(stderr, "usage: %s [-b] [-l] test# diskimage bindurl\n",
    208 	    getprogname());
    209 	exit(1);
    210 }
    211 
    212 static void
    213 die(const char *reason, int error)
    214 {
    215 
    216 	warnx("%s: %s", reason, strerror(error));
    217 	if (background)
    218 		rump_daemonize_done(error);
    219 	exit(1);
    220 }
    221 
    222 static sem_t sigsem;
    223 static void
    224 sigreboot(int sig)
    225 {
    226 
    227 	sem_post(&sigsem);
    228 }
    229 
    230 int
    231 main(int argc, char **argv)
    232 {
    233 	int error;
    234 	u_long test;
    235 	char *end;
    236 	struct ufs_args uargs;
    237 	const char *filename;
    238 	const char *serverurl;
    239 	int log = 0;
    240 	int ch;
    241 
    242 	while ((ch = getopt(argc, argv, "bl")) != -1) {
    243 		switch(ch) {
    244 		case 'b':
    245 			background = 1;
    246 			break;
    247 		case 'l':
    248 			log = 1;
    249 			break;
    250 		default:
    251 			usage();
    252 		}
    253 	}
    254 	argc -= optind;
    255 	argv += optind;
    256 
    257 	if (argc != 3)
    258 		usage();
    259 
    260 	filename = argv[1];
    261 	serverurl = argv[2];
    262 
    263 	test = strtoul(argv[0], &end, 10);
    264 	if (*end != '\0') {
    265 		usage();
    266 	}
    267 	if (test > sizeof(quota_tests) / sizeof(quota_tests[0])) {
    268 		fprintf(stderr, "test number %lu too big\n", test);
    269 		exit(1);
    270 	}
    271 
    272 	if (background) {
    273 		error = rump_daemonize_begin();
    274 		if (error)
    275 			errx(1, "rump daemonize: %s", strerror(error));
    276 	}
    277 
    278 	error = rump_init();
    279 	if (error)
    280 		die("rump init failed", error);
    281 
    282 	if (rump_sys_mkdir(FSTEST_MNTNAME, 0777) == -1)
    283 		err(1, "mount point create");
    284 	rump_pub_etfs_register("/diskdev", filename, RUMP_ETFS_BLK);
    285 	uargs.fspec = __UNCONST("/diskdev");
    286 	if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, (log) ? MNT_LOG : 0,
    287 	    &uargs, sizeof(uargs)) == -1)
    288 		die("mount ffs", errno);
    289 
    290 	if (rump_sys_chdir(FSTEST_MNTNAME) == -1)
    291 		err(1, "cd %s", FSTEST_MNTNAME);
    292 	rump_sys_chown(".", 0, 0);
    293 	rump_sys_chmod(".", 0777);
    294 	error = quota_tests[test].func();
    295 	if (error) {
    296 		fprintf(stderr, " test %lu: %s returned %d: %s\n",
    297 		    test, quota_tests[test].desc, error, strerror(error));
    298 	}
    299 	if (rump_sys_chdir("/") == -1)
    300 		err(1, "cd /");
    301 
    302 	error = rump_init_server(serverurl);
    303 	if (error)
    304 		die("rump server init failed", error);
    305 	if (background)
    306 		rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS);
    307 
    308 	sem_init(&sigsem, 0, 0);
    309 	signal(SIGTERM, sigreboot);
    310 	signal(SIGINT, sigreboot);
    311 	sem_wait(&sigsem);
    312 
    313 	rump_sys_reboot(0, NULL);
    314 	/*NOTREACHED*/
    315 	return 0;
    316 }
    317