1 1.8 maya /* $NetBSD: snapshot.c,v 1.8 2019/07/09 16:24:01 maya Exp $ */ 2 1.1 pooka 3 1.1 pooka #include <sys/types.h> 4 1.1 pooka #include <sys/ioctl.h> 5 1.1 pooka #include <sys/mount.h> 6 1.1 pooka 7 1.1 pooka #include <dev/fssvar.h> 8 1.1 pooka 9 1.1 pooka #include <atf-c.h> 10 1.1 pooka #include <fcntl.h> 11 1.7 hannken #include <pthread.h> 12 1.1 pooka #include <stdio.h> 13 1.1 pooka #include <stdlib.h> 14 1.1 pooka #include <string.h> 15 1.1 pooka #include <unistd.h> 16 1.1 pooka 17 1.1 pooka ATF_TC_WITH_CLEANUP(snapshot); 18 1.1 pooka ATF_TC_HEAD(snapshot, tc) 19 1.1 pooka { 20 1.1 pooka 21 1.1 pooka atf_tc_set_md_var(tc, "descr", "basic snapshot features"); 22 1.1 pooka } 23 1.1 pooka 24 1.1 pooka static void 25 1.1 pooka makefile(const char *path) 26 1.1 pooka { 27 1.1 pooka int fd; 28 1.1 pooka 29 1.1 pooka fd = rump_sys_open(path, O_CREAT | O_RDWR, 0777); 30 1.1 pooka if (fd == -1) 31 1.1 pooka atf_tc_fail_errno("create %s", path); 32 1.1 pooka rump_sys_close(fd); 33 1.1 pooka } 34 1.1 pooka 35 1.1 pooka ATF_TC_BODY(snapshot, tc) 36 1.1 pooka { 37 1.1 pooka char buf[1024]; 38 1.1 pooka struct fss_set fss; 39 1.1 pooka int fssfd; 40 1.1 pooka int fd, fd2, i; 41 1.1 pooka 42 1.1 pooka if (system(NEWFS) == -1) 43 1.1 pooka atf_tc_fail_errno("cannot create file system"); 44 1.1 pooka 45 1.1 pooka rump_init(); 46 1.1 pooka begin(); 47 1.1 pooka 48 1.1 pooka if (rump_sys_mkdir("/mnt", 0777) == -1) 49 1.1 pooka atf_tc_fail_errno("mount point create"); 50 1.1 pooka if (rump_sys_mkdir("/snap", 0777) == -1) 51 1.1 pooka atf_tc_fail_errno("mount point 2 create"); 52 1.1 pooka 53 1.1 pooka rump_pub_etfs_register("/diskdev", IMGNAME, RUMP_ETFS_BLK); 54 1.1 pooka 55 1.1 pooka mount_diskfs("/diskdev", "/mnt"); 56 1.1 pooka 57 1.1 pooka #define TESTSTR1 "huihai\n" 58 1.1 pooka #define TESTSZ1 (sizeof(TESTSTR1)-1) 59 1.1 pooka #define TESTSTR2 "baana liten\n" 60 1.1 pooka #define TESTSZ2 (sizeof(TESTSTR2)-1) 61 1.1 pooka 62 1.1 pooka fd = rump_sys_open("/mnt/myfile", O_RDWR | O_CREAT, 0777); 63 1.1 pooka if (fd == -1) 64 1.1 pooka atf_tc_fail_errno("create file"); 65 1.1 pooka if (rump_sys_write(fd, TESTSTR1, TESTSZ1) != TESTSZ1) 66 1.1 pooka atf_tc_fail_errno("write fail"); 67 1.1 pooka 68 1.1 pooka fssfd = rump_sys_open("/dev/rfss0", O_RDWR); 69 1.6 bouyer if (fssfd == -1) 70 1.1 pooka atf_tc_fail_errno("cannot open fss"); 71 1.1 pooka makefile(BAKNAME); 72 1.1 pooka memset(&fss, 0, sizeof(fss)); 73 1.1 pooka fss.fss_mount = __UNCONST("/mnt"); 74 1.1 pooka fss.fss_bstore = __UNCONST(BAKNAME); 75 1.1 pooka fss.fss_csize = 0; 76 1.1 pooka if (rump_sys_ioctl(fssfd, FSSIOCSET, &fss) == -1) 77 1.1 pooka atf_tc_fail_errno("create snapshot"); 78 1.1 pooka 79 1.1 pooka for (i = 0; i < 10000; i++) { 80 1.1 pooka if (rump_sys_write(fd, TESTSTR2, TESTSZ2) != TESTSZ2) 81 1.1 pooka atf_tc_fail_errno("write fail"); 82 1.1 pooka } 83 1.1 pooka rump_sys_sync(); 84 1.1 pooka 85 1.1 pooka /* technically we should fsck it first? */ 86 1.1 pooka mount_diskfs("/dev/fss0", "/snap"); 87 1.1 pooka 88 1.1 pooka /* check for old contents */ 89 1.1 pooka fd2 = rump_sys_open("/snap/myfile", O_RDONLY); 90 1.1 pooka if (fd2 == -1) 91 1.1 pooka atf_tc_fail_errno("fail"); 92 1.1 pooka memset(buf, 0, sizeof(buf)); 93 1.1 pooka if (rump_sys_read(fd2, buf, sizeof(buf)) == -1) 94 1.1 pooka atf_tc_fail_errno("read snap"); 95 1.1 pooka ATF_CHECK(strcmp(buf, TESTSTR1) == 0); 96 1.1 pooka 97 1.1 pooka /* check that new files are invisible in the snapshot */ 98 1.1 pooka makefile("/mnt/newfile"); 99 1.1 pooka if (rump_sys_open("/snap/newfile", O_RDONLY) != -1) 100 1.1 pooka atf_tc_fail("newfile exists in snapshot"); 101 1.1 pooka if (errno != ENOENT) 102 1.1 pooka atf_tc_fail_errno("newfile open should fail with ENOENT"); 103 1.1 pooka 104 1.1 pooka /* check that removed files are still visible in the snapshot */ 105 1.1 pooka rump_sys_unlink("/mnt/myfile"); 106 1.1 pooka if (rump_sys_open("/snap/myfile", O_RDONLY) == -1) 107 1.1 pooka atf_tc_fail_errno("unlinked file no longer in snapshot"); 108 1.1 pooka 109 1.1 pooka /* done for now */ 110 1.1 pooka } 111 1.1 pooka 112 1.1 pooka ATF_TC_CLEANUP(snapshot, tc) 113 1.1 pooka { 114 1.1 pooka 115 1.1 pooka unlink(IMGNAME); 116 1.1 pooka } 117 1.1 pooka 118 1.7 hannken ATF_TC_WITH_CLEANUP(snapshotstress); 119 1.7 hannken ATF_TC_HEAD(snapshotstress, tc) 120 1.7 hannken { 121 1.7 hannken 122 1.7 hannken atf_tc_set_md_var(tc, "descr", "snapshot on active file system"); 123 1.7 hannken } 124 1.7 hannken 125 1.7 hannken #define NACTIVITY 4 126 1.7 hannken 127 1.7 hannken static bool activity_stop = false; 128 1.7 hannken static pid_t wrkpid; 129 1.7 hannken 130 1.7 hannken static void * 131 1.7 hannken fs_activity(void *arg) 132 1.7 hannken { 133 1.7 hannken int di, fi; 134 1.7 hannken char *prefix = arg, path[128]; 135 1.7 hannken 136 1.7 hannken rump_pub_lwproc_newlwp(wrkpid); 137 1.7 hannken 138 1.7 hannken RL(rump_sys_mkdir(prefix, 0777)); 139 1.7 hannken while (! activity_stop) { 140 1.7 hannken for (di = 0; di < 5; di++) { 141 1.7 hannken snprintf(path, sizeof(path), "%s/d%d", prefix, di); 142 1.7 hannken RL(rump_sys_mkdir(path, 0777)); 143 1.7 hannken for (fi = 0; fi < 5; fi++) { 144 1.7 hannken snprintf(path, sizeof(path), "%s/d%d/f%d", 145 1.7 hannken prefix, di, fi); 146 1.7 hannken makefile(path); 147 1.7 hannken } 148 1.7 hannken } 149 1.7 hannken for (di = 0; di < 5; di++) { 150 1.7 hannken for (fi = 0; fi < 5; fi++) { 151 1.7 hannken snprintf(path, sizeof(path), "%s/d%d/f%d", 152 1.7 hannken prefix, di, fi); 153 1.7 hannken RL(rump_sys_unlink(path)); 154 1.7 hannken } 155 1.7 hannken snprintf(path, sizeof(path), "%s/d%d", prefix, di); 156 1.7 hannken RL(rump_sys_rmdir(path)); 157 1.7 hannken } 158 1.7 hannken } 159 1.7 hannken RL(rump_sys_rmdir(prefix)); 160 1.7 hannken 161 1.7 hannken rump_pub_lwproc_releaselwp(); 162 1.7 hannken 163 1.7 hannken return NULL; 164 1.7 hannken } 165 1.7 hannken 166 1.7 hannken ATF_TC_BODY(snapshotstress, tc) 167 1.7 hannken { 168 1.7 hannken pthread_t at[NACTIVITY]; 169 1.7 hannken struct fss_set fss; 170 1.7 hannken char prefix[NACTIVITY][128]; 171 1.7 hannken int i, fssfd; 172 1.7 hannken 173 1.7 hannken if (system(NEWFS) == -1) 174 1.7 hannken atf_tc_fail_errno("cannot create file system"); 175 1.7 hannken /* Force SMP so the stress makes sense. */ 176 1.7 hannken RL(setenv("RUMP_NCPU", "4", 1)); 177 1.7 hannken RZ(rump_init()); 178 1.7 hannken /* Prepare for fsck to use the RUMP /dev/fss0. */ 179 1.7 hannken RL(rump_init_server("unix://commsock")); 180 1.7 hannken RL(setenv("LD_PRELOAD", "/usr/lib/librumphijack.so", 1)); 181 1.7 hannken RL(setenv("RUMP_SERVER", "unix://commsock", 1)); 182 1.7 hannken RL(setenv("RUMPHIJACK", "blanket=/dev/rfss0", 1)); 183 1.7 hannken begin(); 184 1.7 hannken 185 1.7 hannken RL(rump_sys_mkdir("/mnt", 0777)); 186 1.7 hannken 187 1.7 hannken rump_pub_etfs_register("/diskdev", IMGNAME, RUMP_ETFS_BLK); 188 1.7 hannken 189 1.7 hannken mount_diskfs("/diskdev", "/mnt"); 190 1.7 hannken 191 1.7 hannken /* Start file system activity. */ 192 1.7 hannken RL(wrkpid = rump_sys_getpid()); 193 1.7 hannken for (i = 0; i < NACTIVITY; i++) { 194 1.7 hannken snprintf(prefix[i], sizeof(prefix[i]), "/mnt/a%d", i); 195 1.7 hannken RL(pthread_create(&at[i], NULL, fs_activity, prefix[i])); 196 1.7 hannken sleep(1); 197 1.7 hannken } 198 1.7 hannken 199 1.7 hannken fssfd = rump_sys_open("/dev/rfss0", O_RDWR); 200 1.7 hannken if (fssfd == -1) 201 1.7 hannken atf_tc_fail_errno("cannot open fss"); 202 1.7 hannken makefile(BAKNAME); 203 1.7 hannken memset(&fss, 0, sizeof(fss)); 204 1.7 hannken fss.fss_mount = __UNCONST("/mnt"); 205 1.7 hannken fss.fss_bstore = __UNCONST(BAKNAME); 206 1.7 hannken fss.fss_csize = 0; 207 1.7 hannken if (rump_sys_ioctl(fssfd, FSSIOCSET, &fss) == -1) 208 1.7 hannken atf_tc_fail_errno("create snapshot"); 209 1.7 hannken 210 1.7 hannken activity_stop = true; 211 1.7 hannken for (i = 0; i < NACTIVITY; i++) 212 1.7 hannken RL(pthread_join(at[i], NULL)); 213 1.7 hannken 214 1.7 hannken RL(system(FSCK " /dev/rfss0")); 215 1.7 hannken } 216 1.7 hannken 217 1.7 hannken ATF_TC_CLEANUP(snapshotstress, tc) 218 1.7 hannken { 219 1.7 hannken 220 1.7 hannken unlink(IMGNAME); 221 1.7 hannken } 222 1.7 hannken 223 1.1 pooka ATF_TP_ADD_TCS(tp) 224 1.1 pooka { 225 1.1 pooka ATF_TP_ADD_TC(tp, snapshot); 226 1.7 hannken ATF_TP_ADD_TC(tp, snapshotstress); 227 1.8 maya return atf_no_error(); 228 1.1 pooka } 229