Skip to content

Commit f935ca1

Browse files
committed
zfs: new zfs_builder to create ZFS images
This patch makes some incremental improvements to the process of building ZFS images. However, the main driving force here is to support building and running ZFS images with the kernel built with most symbols hidden. The key missing part to support the above is adding libstdc++.so to the image so that it can be loaded as needed by cpiod.so and mkfs.so. However, this would make the loader.elf even larger than the non-hidden version of it. So instead this patch adds new artifact - zfs_builder.elf - which is intended to be used by upload_manifest.py only to build ZFS-images. In essence this patch modifies the main makefile to build new zfs_builder.elf with bootfs populated with all artifacts necessary to build and load ZFS filesystem (cpiod.so, mkfs.so, etc). At the same time we drop support of building kernel.elf which became obsolete in favor of standard loader.elf which now is even leaner - it does not carry the bootfs footprint with ZFS building tools. On top of that we optimise the build time of ZFS image by making it run zfs_builder.elf in QEMU kernel direct mode and VGA console off that cuts boot time to around 20ms. At the end of the day we come close to satisfying #1068 - "Building a full OSv image without running it" - we use new OSv-based build tool zfs_builder.elf to build final ZFS image - usr.img. Another benefit of this approach is that we can use some "old" pre-existing version of zfs_builder.elf (possibly retrieved from github) to build ZFS image that includes new version of kernel (loader.elf). Refs #1068 Refs #1186 Signed-off-by: Waldemar Kozaczuk <[email protected]>
1 parent 311d07c commit f935ca1

File tree

10 files changed

+58
-41
lines changed

10 files changed

+58
-41
lines changed

Makefile

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,13 @@ endif
144144
quiet = $(if $V, $1, @echo " $2"; $1)
145145
very-quiet = $(if $V, $1, @$1)
146146

147-
all: $(out)/loader.img links $(out)/kernel.elf
147+
all: $(out)/loader.img links $(out)/zfs_builder-stripped.elf
148148
ifeq ($(arch),x64)
149149
all: $(out)/vmlinuz.bin
150150
endif
151+
ifeq ($(arch),aarch64)
152+
all: $(out)/zfs_builder.img
153+
endif
151154
.PHONY: all
152155

153156
links:
@@ -532,6 +535,12 @@ $(out)/loader.img: $(out)/preboot.bin $(out)/loader-stripped.elf
532535
$(call quiet, scripts/imgedit.py setsize_aarch64 "-f raw $@" $(image_size), IMGEDIT $@)
533536
$(call quiet, scripts/imgedit.py setargs "-f raw $@" $(cmdline), IMGEDIT $@)
534537

538+
$(out)/zfs_builder.img: $(out)/preboot.bin $(out)/zfs_builder-stripped.elf
539+
$(call quiet, dd if=$(out)/preboot.bin of=$@ > /dev/null 2>&1, DD $@ preboot.bin)
540+
$(call quiet, dd if=$(out)/zfs_builder-stripped.elf of=$@ conv=notrunc obs=4096 seek=16 > /dev/null 2>&1, DD $@ zfs_builder-stripped.elf)
541+
$(call quiet, scripts/imgedit.py setsize_aarch64 "-f raw $@" $(image_size), IMGEDIT $@)
542+
$(call quiet, scripts/imgedit.py setargs "-f raw $@" $(cmdline), IMGEDIT $@)
543+
535544
endif # aarch64
536545

537546
$(out)/bsd/sys/crypto/rijndael/rijndael-api-fst.o: COMMON+=-fno-strict-aliasing
@@ -2068,7 +2077,7 @@ $(loader_options_dep): stage1
20682077
ifeq ($(conf_hide_symbols),1)
20692078
version_script_file:=$(out)/version_script
20702079
#Detect which version script to be used and copy to $(out)/version_script
2071-
#so that loader.elf/kernel.elf is rebuilt accordingly if version script has changed
2080+
#so that loader.elf/zfs_builder.elf is rebuilt accordingly if version script has changed
20722081
ifdef conf_version_script
20732082
ifeq (,$(wildcard $(conf_version_script)))
20742083
$(error Missing version script: $(conf_version_script))
@@ -2121,13 +2130,14 @@ $(out)/loader.elf: $(stage1_targets) arch/$(arch)/loader.ld $(out)/bootfs.o $(lo
21212130
@scripts/libosv.py $(out)/osv.syms $(out)/libosv.ld `scripts/osv-version.sh` | $(CC) -c -o $(out)/osv.o -x assembler -
21222131
$(call quiet, $(CC) $(out)/osv.o -nostdlib -shared -o $(out)/libosv.so -T $(out)/libosv.ld, LIBOSV.SO)
21232132

2124-
$(out)/kernel.elf: $(stage1_targets) arch/$(arch)/loader.ld $(out)/empty_bootfs.o $(loader_options_dep) $(version_script_file)
2133+
$(out)/zfs_builder.elf: $(stage1_targets) arch/$(arch)/loader.ld $(out)/zfs_builder_bootfs.o $(loader_options_dep) $(version_script_file)
21252134
$(call quiet, $(LD) -o $@ $(def_symbols) \
21262135
-Bdynamic --export-dynamic --eh-frame-hdr --enable-new-dtags -L$(out)/arch/$(arch) \
21272136
$(patsubst %version_script,--version-script=%version_script,$(patsubst %.ld,-T %.ld,$^)) \
21282137
$(linker_archives_options) $(conf_linker_extra_options), \
2129-
LINK kernel.elf)
2130-
$(call quiet, $(STRIP) $(out)/kernel.elf -o $(out)/kernel-stripped.elf, STRIP kernel.elf -> kernel-stripped.elf )
2138+
LINK zfs_builder.elf)
2139+
$(out)/zfs_builder-stripped.elf: $(out)/zfs_builder.elf
2140+
$(call quiet, $(STRIP) $(out)/zfs_builder.elf -o $(out)/zfs_builder-stripped.elf, STRIP zfs_builder.elf -> zfs_builder-stripped.elf )
21312141

21322142
$(out)/bsd/%.o: COMMON += -DSMP -D'__FBSDID(__str__)=extern int __bogus__'
21332143

@@ -2163,9 +2173,8 @@ libgcc_s_dir := ../../$(aarch64_gccbase)/lib64
21632173
endif
21642174

21652175
$(out)/bootfs.bin: scripts/mkbootfs.py $(bootfs_manifest) $(bootfs_manifest_dep) $(tools:%=$(out)/%) \
2166-
$(out)/zpool.so $(out)/zfs.so $(out)/libenviron.so $(out)/libvdso.so
2167-
$(call quiet, olddir=`pwd`; cd $(out); "$$olddir"/scripts/mkbootfs.py -o bootfs.bin -d bootfs.bin.d -m "$$olddir"/$(bootfs_manifest) \
2168-
-D libgcc_s_dir=$(libgcc_s_dir), MKBOOTFS $@)
2176+
$(out)/libenviron.so $(out)/libvdso.so $(out)/libsolaris.so
2177+
$(call quiet, olddir=`pwd`; cd $(out); "$$olddir"/scripts/mkbootfs.py -o bootfs.bin -d bootfs.bin.d -m "$$olddir"/$(bootfs_manifest), MKBOOTFS $@)
21692178

21702179
$(out)/bootfs.o: $(out)/bootfs.bin
21712180
$(out)/bootfs.o: ASFLAGS += -I$(out)
@@ -2184,7 +2193,17 @@ else
21842193
endif
21852194
endif
21862195

2187-
$(out)/empty_bootfs.o: ASFLAGS += -I$(out)
2196+
$(shell mkdir -p $(out) && cp zfs_builder_bootfs.manifest.skel $(out)/zfs_builder_bootfs.manifest)
2197+
ifeq ($(conf_hide_symbols),1)
2198+
$(shell echo "/usr/lib/libstdc++.so.6: $$(readlink -f $(libstd_dir))/libstdc++.so" >> $(out)/zfs_builder_bootfs.manifest)
2199+
endif
2200+
$(out)/zfs_builder_bootfs.bin: scripts/mkbootfs.py $(zfs_builder_bootfs_manifest) $(tools:%=$(out)/%) \
2201+
$(out)/zpool.so $(out)/zfs.so $(out)/libenviron.so $(out)/libvdso.so $(out)/libsolaris.so
2202+
$(call quiet, olddir=`pwd`; cd $(out); "$$olddir"/scripts/mkbootfs.py -o zfs_builder_bootfs.bin -d zfs_builder_bootfs.bin.d -m zfs_builder_bootfs.manifest \
2203+
-D libgcc_s_dir=$(libgcc_s_dir), MKBOOTFS $@)
2204+
2205+
$(out)/zfs_builder_bootfs.o: $(out)/zfs_builder_bootfs.bin
2206+
$(out)/zfs_builder_bootfs.o: ASFLAGS += -I$(out)
21882207

21892208
$(out)/tools/mkfs/mkfs.so: $(out)/tools/mkfs/mkfs.o $(out)/libzfs.so
21902209
$(makedir)

bootfs.manifest.skel

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
11
[manifest]
2-
/libvdso.so: libvdso.so
3-
/libuutil.so: libuutil.so
4-
/zpool.so: zpool.so
5-
/libzfs.so: libzfs.so
62
/libsolaris.so: libsolaris.so
7-
/zfs.so: zfs.so
8-
/tools/mkfs.so: tools/mkfs/mkfs.so
9-
/tools/cpiod.so: tools/cpiod/cpiod.so
10-
/usr/lib/libgcc_s.so.1: %(libgcc_s_dir)s/libgcc_s.so.1

modules/zfs-tools/usr.manifest

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[manifest]
2+
/zpool.so: zpool.so
3+
/libzfs.so: libzfs.so
4+
/libuutil.so: libuutil.so
5+
/libsolaris.so: libsolaris.so

scripts/build

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,6 @@ if [[ ${vars[create_disk]} == "true" ]]; then
301301
bare="$SRC"/scripts/disk.bin
302302
raw_disk=disk
303303
qcow2_disk=disk
304-
if [[ "$arch" == 'x64' ]]; then
305-
upload_kernel_mode="-k"
306-
fi
307304
else
308305
partition_offset=$kernel_end
309306
bare=loader.img
@@ -316,7 +313,7 @@ create_zfs_disk() {
316313
"$SRC"/scripts/imgedit.py setpartition "-f raw ${raw_disk}.raw" 2 $partition_offset $partition_size
317314
qemu-img convert -f raw -O qcow2 $raw_disk.raw $qcow2_disk.img
318315
qemu-img resize $qcow2_disk.img ${image_size}b >/dev/null 2>&1
319-
"$SRC"/scripts/upload_manifest.py --arch=$arch -o $qcow2_disk.img -m usr.manifest -D libgcc_s_dir="$libgcc_s_dir" $upload_kernel_mode
316+
"$SRC"/scripts/upload_manifest.py --arch=$arch -o $qcow2_disk.img -m usr.manifest -D libgcc_s_dir="$libgcc_s_dir"
320317
}
321318

322319
create_rofs_disk() {

scripts/firecracker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ def main(options):
370370
parser.add_argument("-i", "--image", action="store", default=None, metavar="CMD",
371371
help="path to disk image file. defaults to ../build/last/usr.img")
372372
parser.add_argument("-k", "--kernel", action="store", default=None, metavar="CMD",
373-
help="path to kernel loader file. defaults to ../build/last/kernel.elf")
373+
help="path to kernel loader file. defaults to ../build/last/loader-stripped.elf")
374374
parser.add_argument("-n", "--networking", action="store_true",
375375
help="needs root to setup tap networking first time")
376376
parser.add_argument("-b", "--bridge", action="store", default=None,
@@ -390,7 +390,7 @@ def main(options):
390390
default_kernel_file_name = "loader.img"
391391
default_image_file_name = "disk.img"
392392
else:
393-
default_kernel_file_name = "kernel.elf"
393+
default_kernel_file_name = "loader-stripped.elf"
394394
default_image_file_name = "usr.img"
395395
cmdargs.kernel_path = os.path.abspath(cmdargs.kernel or os.path.join(osv_base, "build/%s/%s" % (cmdargs.opt_path, default_kernel_file_name)))
396396
cmdargs.image_path = os.path.abspath(cmdargs.image or os.path.join(osv_base, "build/%s/%s" % (cmdargs.opt_path, default_image_file_name)))

scripts/run.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ def main(options):
594594
parser.add_argument("-k", "--kernel", action="store_true",
595595
help="Run OSv in QEMU kernel mode as PVH.")
596596
parser.add_argument("--kernel-path", action="store",
597-
help="path to kernel.elf. defaults to build/$mode/kernel.elf")
597+
help="path to loader-stripped.elf. defaults to build/$mode/loader-stripped.elf")
598598
parser.add_argument("--virtio", action="store", choices=["legacy","transitional","modern"], default="transitional",
599599
help="specify virtio version: legacy, transitional or modern")
600600
parser.add_argument("--arch", action="store", choices=["x86_64","aarch64"], default=host_arch,
@@ -618,7 +618,7 @@ def main(options):
618618
default_kernel_file_name = "loader.img"
619619
default_image_file_name = "disk.img"
620620
else:
621-
default_kernel_file_name = "kernel.elf"
621+
default_kernel_file_name = "loader-stripped.elf"
622622
default_image_file_name = "usr.img"
623623
cmdargs.kernel_file = os.path.abspath(cmdargs.kernel_path or os.path.join(osv_base, "build/%s/%s" % (cmdargs.opt_path, default_kernel_file_name)))
624624
cmdargs.image_file = os.path.abspath(cmdargs.image or os.path.join(osv_base, "build/%s/%s" % (cmdargs.opt_path, default_image_file_name)))

scripts/upload_manifest.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,6 @@ def main():
136136
metavar='VAR=DATA',
137137
action='callback',
138138
callback=add_var),
139-
make_option('-k',
140-
dest='kernel',
141-
action='store_true',
142-
help='run OSv in direct kernel mode'),
143139
make_option('--arch',
144140
dest='arch',
145141
default=host_arch,
@@ -157,14 +153,18 @@ def main():
157153

158154
image_path = os.path.abspath(options.output)
159155
upload_port = find_free_port()
160-
if options.kernel:
161-
kernel_mode_flag = '-k --kernel-path build/release/loader-stripped.elf'
162-
else:
163-
kernel_mode_flag = ''
164156
arch = options.arch
165157
if arch == 'x64':
166158
arch = 'x86_64'
167-
osv = subprocess.Popen('cd ../..; scripts/run.py %s --arch=%s --vnc none -m 512 -c1 -i "%s" --block-device-cache unsafe -s -e "--norandom --nomount --noinit /tools/mkfs.so; /tools/cpiod.so --prefix /zfs/zfs/; /zfs.so set compression=off osv" --forward tcp:127.0.0.1:%s-:10000' % (kernel_mode_flag,arch,image_path,upload_port), shell=True, stdout=subprocess.PIPE)
159+
160+
if arch == 'aarch64':
161+
console = ''
162+
zfs_builder_name = 'zfs_builder.img'
163+
else:
164+
console = '--console=serial'
165+
zfs_builder_name = 'zfs_builder-stripped.elf'
166+
167+
osv = subprocess.Popen('cd ../..; scripts/run.py -k --kernel-path build/release/%s --arch=%s --vnc none -m 512 -c1 -i "%s" --block-device-cache unsafe -s -e "%s --norandom --nomount --noinit /tools/mkfs.so; /tools/cpiod.so --prefix /zfs/zfs/; /zfs.so set compression=off osv" --forward tcp:127.0.0.1:%s-:10000' % (zfs_builder_name,arch,image_path,console,upload_port), shell=True, stdout=subprocess.PIPE)
168168

169169
upload(osv, manifest, depends, upload_port)
170170

usr.manifest.skel

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
[manifest]
22
/libenviron.so: libenviron.so
33
/libvdso.so: libvdso.so
4-
/zpool.so: zpool.so
5-
/libzfs.so: libzfs.so
6-
/libuutil.so: libuutil.so
7-
/zfs.so: zfs.so
8-
/libsolaris.so: libsolaris.so
9-
/tools/mkfs.so: tools/mkfs/mkfs.so
10-
/tools/cpiod.so: tools/cpiod/cpiod.so
114
/tools/mount-fs.so: tools/mount/mount-fs.so
125
/tools/umount.so: tools/mount/umount.so
136
/usr/lib/libgcc_s.so.1: %(libgcc_s_dir)s/libgcc_s.so.1

empty_bootfs.S renamed to zfs_builder_bootfs.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
.global bootfs_start
33
.hidden bootfs_start
44
bootfs_start:
5+
.incbin "zfs_builder_bootfs.bin"
56
.popsection

zfs_builder_bootfs.manifest.skel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[manifest]
2+
/libvdso.so: libvdso.so
3+
/libuutil.so: libuutil.so
4+
/zpool.so: zpool.so
5+
/libzfs.so: libzfs.so
6+
/libsolaris.so: libsolaris.so
7+
/zfs.so: zfs.so
8+
/tools/mkfs.so: tools/mkfs/mkfs.so
9+
/tools/cpiod.so: tools/cpiod/cpiod.so
10+
/usr/lib/libgcc_s.so.1: %(libgcc_s_dir)s/libgcc_s.so.1

0 commit comments

Comments
 (0)