int test_create_and_write_file(char *name, int size, int chunk_size) { int res; spiffs_file fd; printf(" create and write %s", name); res = test_create_file(name); if (res < 0) { printf(" failed creation, %i\n",res); } CHECK(res >= 0); fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0); if (res < 0) { printf(" failed open, %i\n",res); } CHECK(fd >= 0); int pfd = open(make_test_fname(name), O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); int offset = 0; int mark = 0; while (offset < size) { int len = MIN(size-offset, chunk_size); if (offset > mark) { mark += size/16; printf("."); fflush(stdout); } uint8_t *buf = malloc(len); memrand(buf, len); res = SPIFFS_write(FS, fd, buf, len); write(pfd, buf, len); free(buf); if (res < 0) { printf("\n error @ offset %i, res %i\n", offset, res); } offset += len; CHECK(res >= 0); } printf("\n"); close(pfd); spiffs_stat stat; res = SPIFFS_fstat(FS, fd, &stat); if (res < 0) { printf(" failed fstat, %i\n",res); } CHECK(res >= 0); if (stat.size != size) { printf(" failed size, %i != %i\n", stat.size, size); } CHECK(stat.size == size); SPIFFS_close(FS, fd); return 0; }
/* The protection is specified by t1 and t2, referring to test_prots. * The value 0 means a null pointer so there is no memory to protect. */ void test_prot(int signum, int t1, int t2, size_t sigsetsize) { unsigned char sim_new[SIGACTSZ + 2 * MARGIN]; unsigned char sim_old[SIGACTSZ + 2 * MARGIN]; const size_t sim_array_size = sizeof(sim_new); int prot1 = test_prots[t1]; int prot2 = test_prots[t2]; int ret_sys, ret_sim; memrand(sim_new, sim_array_size); memcpy(test_prot_mem1, sim_new, sim_array_size); memrand(sim_old, sim_array_size); memcpy(test_prot_mem2, sim_old, sim_array_size); if (t1 != 0) mprotect_nofail(test_prot_mem1, sim_array_size, prot1); if (t2 != 0) mprotect_nofail(test_prot_mem2, sim_array_size, prot2); ret_sys = sys_sigaction(signum, t1 == 0 ? NULL : test_prot_mem1 + MARGIN, t2 == 0 ? NULL : test_prot_mem2 + MARGIN, sigsetsize); if (t1 != 0) mprotect_nofail(test_prot_mem1, sim_array_size, PROT_READ | PROT_WRITE); if (t2 != 0) mprotect_nofail(test_prot_mem2, sim_array_size, PROT_READ | PROT_WRITE); ret_sim = sim_sigaction(signum, t1 == 0 ? NULL : sim_new + MARGIN, t2 == 0 ? NULL : sim_old + MARGIN, sigsetsize, prot1, prot2); assert(ret_sys == ret_sim || /* 32-bit on a 64-bit kernel returns -ENXIO for invalid oact (i#1984) */ (ret_sys == -ENXIO && ret_sim == -EFAULT)); assert(memcmp(test_prot_mem1, sim_new, sim_array_size) == 0 && memcmp(test_prot_mem2, sim_old, sim_array_size) == 0); }
void test_rw(int signum, unsigned char *act, unsigned char *oldact, size_t sigsetsize) { int prot_rw = PROT_READ | PROT_WRITE; int ret_sys, ret_sim; memrand(test_rw_sys, sizeof(test_rw_sys)); memcpy(test_rw_sim, test_rw_sys, sizeof(test_rw_sys)); ret_sys = sys_sigaction(signum, act, oldact, sigsetsize); ret_sim = sim_sigaction(signum, act == NULL ? NULL : test_rw_sim + (act - test_rw_sys), oldact == NULL ? NULL : test_rw_sim + (oldact - test_rw_sys), sigsetsize, prot_rw, prot_rw); assert(ret_sys == ret_sim); assert(memcmp(test_rw_sys, test_rw_sim, sizeof(test_rw_sys)) == 0); }
u8_t *niffs_emul_write_rand_data(char *name, u32_t offs, u32_t seed, u32_t len) { fdata *cur_e = dhead; fdata *e = 0; while (cur_e) { if (strcmp(name, cur_e->name) == 0) { e = cur_e; break; } } NIFFS_ASSERT(e); if (e->len < offs+len) { (void)niffs_emul_extend_data(name, offs+len-e->len, 0); } memrand(&e->data[offs], len, seed); return e->data; }
int run_file_config(int cfg_count, tfile_conf* cfgs, int max_runs, int max_concurrent_files, int dbg) { int res; tfile *tfiles = malloc(sizeof(tfile) * max_concurrent_files); memset(tfiles, 0, sizeof(tfile) * max_concurrent_files); int run = 0; int cur_config_ix = 0; char name[32]; while (run < max_runs) { if (dbg) printf(" run %i/%i\n", run, max_runs); int i; for (i = 0; i < max_concurrent_files; i++) { sprintf(name, "file%i_%i", (1+run), i); tfile *tf = &tfiles[i]; if (tf->state == 0 && cur_config_ix < cfg_count) { // create a new file strcpy(tf->name, name); tf->state = 1; tf->cfg = cfgs[cur_config_ix]; int size = tfile_get_size(tf->cfg.tsize); if (dbg) printf(" create new %s with cfg %i/%i, size %i\n", name, (1+cur_config_ix), cfg_count, size); if (tf->cfg.tsize == EMPTY) { res = SPIFFS_creat(FS, name, 0); CHECK_RES(res); int pfd = open(make_test_fname(name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); close(pfd); int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0; spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_RDWR, 0); CHECK(fd > 0); tf->fd = fd; } else { int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0; spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); CHECK(fd > 0); extra_flags = tf->cfg.ttype == APPENDED ? O_APPEND : 0; int pfd = open(make_test_fname(name), extra_flags | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); tf->fd = fd; uint8_t *buf = malloc(size); memrand(buf, size); res = SPIFFS_write(FS, fd, buf, size); CHECK_RES(res); write(pfd, buf, size); close(pfd); free(buf); res = read_and_verify(name); CHECK_RES(res); } cur_config_ix++; } else if (tf->state > 0) { // hande file lifecycle switch (tf->cfg.ttype) { case UNTAMPERED: { break; } case APPENDED: { if (dbg) printf(" appending %s\n", tf->name); int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; uint8_t *buf = malloc(size); memrand(buf, size); res = SPIFFS_write(FS, tf->fd, buf, size); CHECK_RES(res); int pfd = open(make_test_fname(tf->name), O_APPEND | O_RDWR); write(pfd, buf, size); close(pfd); free(buf); res = read_and_verify(tf->name); CHECK_RES(res); break; } case MODIFIED: { if (dbg) printf(" modify %s\n", tf->name); spiffs_stat stat; res = SPIFFS_fstat(FS, tf->fd, &stat); CHECK_RES(res); int size = stat.size / tf->cfg.tlife + SPIFFS_DATA_PAGE_SIZE(FS)/3; int offs = (stat.size / tf->cfg.tlife) * tf->state; res = SPIFFS_lseek(FS, tf->fd, offs, SPIFFS_SEEK_SET); CHECK_RES(res); uint8_t *buf = malloc(size); memrand(buf, size); res = SPIFFS_write(FS, tf->fd, buf, size); CHECK_RES(res); int pfd = open(make_test_fname(tf->name), O_RDWR); lseek(pfd, offs, SEEK_SET); write(pfd, buf, size); close(pfd); free(buf); res = read_and_verify(tf->name); CHECK_RES(res); break; } case REWRITTEN: { if (tf->fd > 0) { SPIFFS_close(FS, tf->fd); } if (dbg) printf(" rewriting %s\n", tf->name); spiffs_file fd = SPIFFS_open(FS, tf->name, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); CHECK(fd > 0); int pfd = open(make_test_fname(tf->name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); tf->fd = fd; int size = tfile_get_size(tf->cfg.tsize); uint8_t *buf = malloc(size); memrand(buf, size); res = SPIFFS_write(FS, fd, buf, size); CHECK_RES(res); write(pfd, buf, size); close(pfd); free(buf); res = read_and_verify(tf->name); CHECK_RES(res); break; } } tf->state++; if (tf->state > tf->cfg.tlife) { // file outlived its time, kill it if (tf->fd > 0) { SPIFFS_close(FS, tf->fd); } if (dbg) printf(" removing %s\n", tf->name); res = read_and_verify(tf->name); CHECK_RES(res); res = SPIFFS_remove(FS, tf->name); CHECK_RES(res); remove(make_test_fname(tf->name)); memset(tf, 0, sizeof(tf)); } } } run++; } free(tfiles); return 0; }