t_resize.c revision 1.2
1/*	$NetBSD: t_resize.c,v 1.2 2025/10/30 15:30:17 perseant Exp $	*/
2
3#include <sys/types.h>
4#include <sys/mount.h>
5#include <sys/wait.h>
6
7#include <atf-c.h>
8#include <ctype.h>
9#include <errno.h>
10#include <fcntl.h>
11#include <limits.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <string.h>
16
17#include <rump/rump.h>
18#include <rump/rump_syscalls.h>
19
20#include <ufs/ufs/ufsmount.h>
21#include <ufs/lfs/lfs.h>
22#include <ufs/lfs/lfs_extern.h>
23
24#include "h_macros.h"
25#include "util.h"
26
27/* Debugging conditions */
28/* #define FORCE_SUCCESS */ /* Don't actually revert, everything worked */
29/* #define USE_DUMPLFS */ /* Dump the filesystem at certain steps */
30
31#define UNCHANGED_CONTROL MP "/3-a-random-file"
32#define BIGSIZE 15000
33#define SMALLSIZE 10000
34__CTASSERT(BIGSIZE > SMALLSIZE);
35
36/* Resize filesystem */
37void resize(int, size_t);
38
39/* Actually run the test */
40void test(int);
41
42ATF_TC(resize32);
43ATF_TC_HEAD(resize32, tc)
44{
45	atf_tc_set_md_var(tc, "descr",
46		"LFS32 resize_lfs creates an inconsistent filesystem");
47	atf_tc_set_md_var(tc, "timeout", "20");
48}
49
50ATF_TC(resize64);
51ATF_TC_HEAD(resize64, tc)
52{
53	atf_tc_set_md_var(tc, "descr",
54		"LFS64 resize_lfs creates an inconsistent filesystem");
55	atf_tc_set_md_var(tc, "timeout", "20");
56}
57
58ATF_TC_BODY(resize32, tc)
59{
60	test(32);
61}
62
63ATF_TC_BODY(resize64, tc)
64{
65	test(64);
66}
67
68void test(int width)
69{
70	struct ufs_args args;
71	int fd;
72
73	setvbuf(stdout, NULL, _IONBF, 0);
74
75	/*
76	 * Initialize.
77	 */
78
79	/* Create image file larger than filesystem */
80	create_lfs(BIGSIZE, SMALLSIZE, width, 1);
81
82	/* Mount filesystem */
83	fprintf(stderr, "* Mount fs [1]\n");
84	memset(&args, 0, sizeof(args));
85	args.fspec = __UNCONST(FAKEBLK);
86	if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1)
87		atf_tc_fail_errno("rump_sys_mount failed");
88
89	/* Payload */
90	fprintf(stderr, "* Initial payload\n");
91	write_file(UNCHANGED_CONTROL, CHUNKSIZE, 1, 0);
92
93	/* Unmount */
94	rump_sys_unmount(MP, 0);
95	if (fsck())
96		atf_tc_fail_errno("fsck found errors after first unmount");
97
98	/*
99	 * Remount and resize.
100	 */
101
102	/* Reconfigure and mount filesystem again */
103	fprintf(stderr, "* Remount fs [2, to enlarge]\n");
104	if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1)
105		atf_tc_fail_errno("rump_sys_mount failed [2]");
106
107	/* Get a handle to the root of the file system */
108	fd = rump_sys_open(MP, O_RDONLY);
109	if (fd < 0)
110		atf_tc_fail_errno("rump_sys_open mount point root failed");
111
112	/* Enlarge filesystem */
113	fprintf(stderr, "* Resize (enlarge)\n");
114	resize(fd, BIGSIZE);
115
116	/* Unmount fs and check */
117	rump_sys_close(fd);
118	rump_sys_unmount(MP, 0);
119	if (fsck())
120		atf_tc_fail_errno("fsck found errors after enlarge");
121
122	/* Mount filesystem for shrink */
123	fprintf(stderr, "* Mount fs [3, to shrink]\n");
124	if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1)
125		atf_tc_fail_errno("rump_sys_mount failed [3]");
126
127	/* Get a handle to the root of the file system */
128	fd = rump_sys_open(MP, O_RDONLY);
129	if (fd < 0)
130		atf_tc_fail_errno("rump_sys_open mount point root failed");
131
132	/* Shrink filesystem */
133	fprintf(stderr, "* Resize (shrink)\n");
134	resize(fd, SMALLSIZE);
135
136	/* Unmount and check again */
137	rump_sys_close(fd);
138	if (rump_sys_unmount(MP, 0) != 0)
139		atf_tc_fail_errno("rump_sys_umount failed after shrink");
140	fprintf(stderr, "* Fsck after shrink\n");
141	if (fsck())
142		atf_tc_fail("fsck found errors after shrink");
143
144	/*
145	 * Check file system contents
146	 */
147
148	/* Mount filesystem one last time */
149	fprintf(stderr, "* Mount fs [4, to check contents]\n");
150	if (rump_sys_mount(MOUNT_LFS, MP, 0, &args, sizeof(args)) == -1)
151		atf_tc_fail_errno("rump_sys_mount failed [4]");
152
153	if (check_file(UNCHANGED_CONTROL, CHUNKSIZE, 0) != 0)
154		atf_tc_fail("Unchanged control file differs(!)");
155
156	/* Umount filesystem */
157	rump_sys_unmount(MP, 0);
158
159	/* Final fsck to double check */
160	fprintf(stderr, "* Fsck after final unmount\n");
161	if (fsck())
162		atf_tc_fail("fsck found errors after final unmount");
163}
164
165ATF_TP_ADD_TCS(tp)
166{
167
168	ATF_TP_ADD_TC(tp, resize32);
169	ATF_TP_ADD_TC(tp, resize64);
170	return atf_no_error();
171}
172
173void
174resize(int fd, size_t size)
175{
176	int newnseg = (size * DEV_BSIZE) / SEGSIZE;
177
178	if (rump_sys_fcntl(fd, LFCNRESIZE, &newnseg) != 0)
179		atf_tc_fail_errno("LFCNRESIZE failed");
180}
181