1 /* $NetBSD: util.c,v 1.1 2025/10/13 00:44:35 perseant Exp $ */ 2 3 #include <sys/mount.h> 4 5 #include <ctype.h> 6 #include <fcntl.h> 7 8 #include <rump/rump.h> 9 #include <rump/rump_syscalls.h> 10 11 #include "h_macros.h" 12 #include "util.h" 13 14 long long sbaddr[2] = { -1, -1 }; 15 16 /* Create filesystem, note superblock locations */ 17 void create_lfs(size_t imgsize, size_t fssize, int width, int do_setup) 18 { 19 FILE *pipe; 20 char cmd[MAXLINE]; 21 char buf[MAXLINE]; 22 23 /* Create image file larger than filesystem */ 24 sprintf(cmd, "dd if=/dev/zero of=%s bs=512 count=%zd", 25 IMGNAME, imgsize); 26 if (system(cmd) == -1) 27 atf_tc_fail_errno("create image failed"); 28 29 /* Create filesystem */ 30 fprintf(stderr, "* Create file system\n"); 31 sprintf(cmd, "newfs_lfs -D -F -s %zd -w%d ./%s > %s", 32 fssize, width, IMGNAME, LOGFILE); 33 if (system(cmd) == -1) 34 atf_tc_fail_errno("newfs failed"); 35 pipe = fopen(LOGFILE, "r"); 36 if (pipe == NULL) 37 atf_tc_fail_errno("newfs failed to execute"); 38 while (fgets(buf, MAXLINE, pipe) != NULL) { 39 if (sscanf(buf, "%lld,%lld", sbaddr, sbaddr + 1) == 2) 40 break; 41 } 42 while (fgets(buf, MAXLINE, pipe) != NULL) 43 ; 44 fclose(pipe); 45 if (sbaddr[0] < 0 || sbaddr[1] < 0) 46 atf_tc_fail("superblock not found"); 47 fprintf(stderr, "* Superblocks at %lld and %lld\n", 48 sbaddr[0], sbaddr[1]); 49 50 if (do_setup) { 51 /* Set up rump */ 52 rump_init(); 53 if (rump_sys_mkdir(MP, 0777) == -1) 54 atf_tc_fail_errno("cannot create mountpoint"); 55 rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK); 56 } 57 } 58 59 /* Write some data into a file */ 60 int write_file(const char *filename, off_t len, int close) 61 { 62 int fd, size, i; 63 struct stat statbuf; 64 unsigned char b; 65 int flags = O_CREAT|O_WRONLY; 66 67 if (rump_sys_stat(filename, &statbuf) < 0) 68 size = 0; 69 else { 70 size = statbuf.st_size; 71 flags |= O_APPEND; 72 } 73 74 fd = rump_sys_open(filename, flags); 75 76 for (i = 0; i < len; i++) { 77 b = ((unsigned)(size + i)) & 0xff; 78 rump_sys_write(fd, &b, 1); 79 } 80 if (close) { 81 rump_sys_close(fd); 82 fd = -1; 83 } 84 85 return fd; 86 } 87 88 /* Check file's existence, size and contents */ 89 int check_file(const char *filename, int size) 90 { 91 int fd, i; 92 struct stat statbuf; 93 unsigned char b; 94 95 if (rump_sys_stat(filename, &statbuf) < 0) { 96 fprintf(stderr, "%s: stat failed\n", filename); 97 return 1; 98 } 99 if (size != statbuf.st_size) { 100 fprintf(stderr, "%s: expected %d bytes, found %d\n", 101 filename, size, (int)statbuf.st_size); 102 return 2; 103 } 104 105 fd = rump_sys_open(filename, O_RDONLY); 106 for (i = 0; i < size; i++) { 107 rump_sys_read(fd, &b, 1); 108 if (b != (((unsigned)i) & 0xff)) { 109 fprintf(stderr, "%s: byte %d: expected %x found %x\n", 110 filename, i, ((unsigned)(i)) & 0xff, b); 111 rump_sys_close(fd); 112 return 3; 113 } 114 } 115 rump_sys_close(fd); 116 fprintf(stderr, "%s: no problem\n", filename); 117 return 0; 118 } 119 120 /* Run a file system consistency check */ 121 int fsck(void) 122 { 123 char s[MAXLINE]; 124 int i, errors = 0; 125 FILE *pipe; 126 char cmd[MAXLINE]; 127 128 for (i = 0; i < 2; i++) { 129 sprintf(cmd, "fsck_lfs -n -b %jd -f " IMGNAME, 130 (intmax_t)sbaddr[i]); 131 pipe = popen(cmd, "r"); 132 while (fgets(s, MAXLINE, pipe) != NULL) { 133 if (isdigit((int)s[0])) /* "5 files ... " */ 134 continue; 135 if (isspace((int)s[0]) || s[0] == '*') 136 continue; 137 if (strncmp(s, "Alternate", 9) == 0) 138 continue; 139 if (strncmp(s, "ROLL ", 5) == 0) 140 continue; 141 fprintf(stderr, "FSCK[sb@%lld]: %s", sbaddr[i], s); 142 ++errors; 143 } 144 pclose(pipe); 145 if (errors) { 146 break; 147 } 148 } 149 150 return errors; 151 } 152 153 /* Run dumplfs */ 154 void dumplfs() 155 { 156 char s[MAXLINE]; 157 FILE *pipe; 158 159 pipe = popen("dumplfs -S -s 2 -s 1 -s 0 " IMGNAME, "r"); 160 while (fgets(s, MAXLINE, pipe) != NULL) 161 fprintf(stderr, "DUMPLFS: %s", s); 162 pclose(pipe); 163 } 164