Skip to content

Commit f6e09c0

Browse files
committed
zfs: support building rofs+zfs image and second ZFS disk
This patch enhances the build scriots and run.py to allow build the images as described by #1200: 1. Run OSv from a single disk with two partitions: ROFS + ZFS (on /dev/vblk0.2) ./scripts/build image=tests,zfs,zfs-tools fs=rofs_with_zfs fs_size_mb=5000 ./scripts/run.py --execute='--mount-fs=zfs,/dev/vblk0.2,/data /tests/misc-zfs-io.so --random --file-path /data/file' 2. Run OSv with 2 disks: 1st one with ROFS and second one with ZFS (/dev/vblk1.1): ./scripts/build image=tests,zfs,zfs-tools fs=rofs fs_size_mb=5000 --create-zfs-disk ./scripts/run.py --execute='--mount-fs=zfs,/dev/vblk1.1,/data /tests/misc-zfs-io.so --random --file-path /data/file' --second-disk-image build/release/zfs_disk.img Fixes #1200 Signed-off-by: Waldemar Kozaczuk <[email protected]>
1 parent 9cc49b3 commit f6e09c0

File tree

4 files changed

+73
-13
lines changed

4 files changed

+73
-13
lines changed

scripts/build

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ usage() {
2626
mode=release|debug Specify the build mode; default is release
2727
export=none|selected|all If 'selected' or 'all' export the app files to <export_dir>
2828
export_dir=<dir> The directory to export the files to; default is build/export
29-
fs=zfs|rofs|ramfs|virtiofs Specify the filesystem of the image partition
29+
fs=zfs|rofs|rofs_with_zfs| Specify the filesystem of the image partition
30+
ramfs|virtiofs
3031
fs_size=N Specify the size of the image in bytes
3132
fs_size_mb=N Specify the size of the image in MiB
3233
app_local_exec_tls_size=N Specify the size of app local TLS in bytes; the default is 64
@@ -36,6 +37,7 @@ usage() {
3637
-j<N> Set number of parallel jobs for make
3738
--append-manifest Append build/<mode>/append.manifest to usr.manifest
3839
--create-disk Instead of usr.img create kernel-less disk.img
40+
--create-zfs-disk Create extra empty disk with ZFS filesystem
3941
4042
Examples:
4143
./scripts/build -j4 fs=rofs image=native-example # Create image with native-example app
@@ -77,7 +79,7 @@ do
7779
case $i in
7880
--help|-h)
7981
usage ;;
80-
image=*|modules=*|fs=*|usrskel=*|check|--append-manifest|--create-disk) ;;
82+
image=*|modules=*|fs=*|usrskel=*|check|--append-manifest|--create-disk|--create-zfs-disk) ;;
8183
clean)
8284
stage1_args=clean ;;
8385
arch=*)
@@ -159,6 +161,8 @@ do
159161
vars[append_manifest]="true";;
160162
--create-disk)
161163
vars[create_disk]="true";;
164+
--create-zfs-disk)
165+
vars[create_zfs_disk]="true";;
162166
esac
163167
done
164168

@@ -195,7 +199,7 @@ usrskel_arg=
195199
case $fs_type in
196200
zfs)
197201
;; # Nothing to change here. This is our default behavior
198-
rofs|virtiofs)
202+
rofs|rofs_with_zfs|virtiofs)
199203
# Both are read-only (in OSv) and require nothing extra on bootfs to work
200204
manifest=bootfs_empty.manifest.skel
201205
usrskel_arg="--usrskel usr_rofs.manifest.skel";;
@@ -293,6 +297,7 @@ cd $OUT
293297

294298
if [ "$export" != "none" ]; then
295299
export_dir=${vars[export_dir]-$SRC/build/export}
300+
rm -rf "$export_dir"
296301
"$SRC"/scripts/export_manifest.py -e "$export_dir" -m usr.manifest -D libgcc_s_dir="$libgcc_s_dir"
297302
fi
298303

@@ -314,6 +319,7 @@ create_zfs_disk() {
314319
qemu-img convert -f raw -O qcow2 $raw_disk.raw $qcow2_disk.img
315320
qemu-img resize $qcow2_disk.img ${image_size}b >/dev/null 2>&1
316321
"$SRC"/scripts/upload_manifest.py --arch=$arch -o $qcow2_disk.img -m usr.manifest -D libgcc_s_dir="$libgcc_s_dir"
322+
#"$SRC"/scripts/zfs-image-on-host.sh build $qcow2_disk.img $partition_offset osv zfs
317323
}
318324

319325
create_rofs_disk() {
@@ -324,6 +330,22 @@ create_rofs_disk() {
324330
qemu-img convert -f raw -O qcow2 $raw_disk.raw $qcow2_disk.img
325331
}
326332

333+
create_zfs_filesystem() {
334+
local image_path=$1
335+
local device_path=$2
336+
local qemu_arch=$arch
337+
if [[ "$qemu_arch" == 'aarch64' ]]; then
338+
console=''
339+
zfs_builder_name='zfs_builder.img'
340+
else
341+
qemu_arch='x86_64'
342+
console='--console=serial'
343+
zfs_builder_name='zfs_builder-stripped.elf'
344+
fi
345+
"$SRC"/scripts/run.py -k --kernel-path $zfs_builder_name --arch=$qemu_arch --vnc none -m 512 -c1 -i ${image_path} \
346+
--block-device-cache unsafe -s -e "${console} --norandom --nomount --noinit --preload-zfs-library /tools/mkfs.so ${device_path}; /zfs.so set compression=off osv"
347+
}
348+
327349
if [[ "$arch" == 'aarch64' ]]; then
328350
export STRIP=${CROSS_PREFIX:-aarch64-linux-gnu-}strip
329351
fi
@@ -332,13 +354,27 @@ case $fs_type in
332354
zfs)
333355
partition_size=$((fs_size - partition_offset))
334356
image_size=$fs_size
335-
create_zfs_disk ;;
357+
create_zfs_disk ;;
336358
rofs)
337359
rm -rf rofs.img
338360
"$SRC"/scripts/gen-rofs-img.py -o rofs.img -m usr.manifest -D libgcc_s_dir="$libgcc_s_dir"
339361
partition_size=`stat --printf %s rofs.img`
340362
image_size=$((partition_offset + partition_size))
341-
create_rofs_disk ;;
363+
create_rofs_disk ;;
364+
rofs_with_zfs)
365+
# Create disk with rofs image on it 1st partition
366+
rm -rf rofs.img
367+
"$SRC"/scripts/gen-rofs-img.py -o rofs.img -m usr.manifest -D libgcc_s_dir="$libgcc_s_dir"
368+
partition_size=`stat --printf %s rofs.img`
369+
image_size=$((fs_size+partition_size))
370+
create_rofs_disk
371+
# Resize the disk to fit ZFS on it after rofs
372+
qemu-img resize $qcow2_disk.img ${image_size}b >/dev/null 2>&1
373+
# Create filesystem on ZFS partition
374+
zfs_partition_offset=$((partition_offset + partition_size))
375+
zfs_partition_size=$((image_size-zfs_partition_offset))
376+
"$SRC"/scripts/imgedit.py setpartition "$qcow2_disk.img" 3 $zfs_partition_offset $zfs_partition_size
377+
create_zfs_filesystem $qcow2_disk.img "/dev/vblk0.2";;
342378
ramfs|virtiofs)
343379
# No need to create extra fs like above: ramfs is already created (as the
344380
# bootfs) and virtio-fs is specified with virtiofsd at run time
@@ -352,6 +388,19 @@ if [[ -f "$OSV_BUILD_PATH/usr.img" ]]; then
352388
"$SRC"/scripts/imgedit.py setargs usr.img `cat cmdline`
353389
fi
354390

391+
if [[ ${vars[create_zfs_disk]} == "true" ]]; then
392+
partition_offset=512
393+
partition_size=$((fs_size - partition_offset))
394+
image_size=$fs_size
395+
raw_disk=zfs_disk
396+
qcow2_disk=zfs_disk
397+
cp "$SRC"/scripts/disk.bin $raw_disk.raw
398+
"$SRC"/scripts/imgedit.py setpartition "-f raw ${raw_disk}.raw" 2 $partition_offset $partition_size
399+
qemu-img convert -f raw -O qcow2 $raw_disk.raw $qcow2_disk.img
400+
qemu-img resize $qcow2_disk.img ${image_size}b >/dev/null 2>&1
401+
create_zfs_filesystem $qcow2_disk.img "/dev/vblk0.1"
402+
fi
403+
355404
# Support "build check"
356405
for i
357406
do

scripts/export_manifest.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ def export_package(manifest, dest):
1010
abs_dest = os.path.abspath(dest)
1111
print("[INFO] exporting into directory %s" % abs_dest)
1212

13-
# Remove and create the base directory where we are going to put all package files.
14-
if os.path.exists(abs_dest):
15-
shutil.rmtree(abs_dest)
16-
os.makedirs(abs_dest)
13+
# Create the base directory where we are going to put all package files.
14+
if not os.path.exists(abs_dest):
15+
os.makedirs(abs_dest)
1716

1817
files = list(expand(manifest))
1918
files = [(x, unsymlink(y % defines)) for (x, y) in files]

scripts/run.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ def start_osv_qemu(options):
177177
"-device", "virtio-blk-pci,id=blk1,bootindex=1,drive=hd1,scsi=off%s" % options.virtio_device_suffix,
178178
"-drive", "file=%s,if=none,id=hd1" % (options.cloud_init_image)]
179179

180+
if options.second_disk_image:
181+
args += [
182+
"-device", "virtio-blk-pci,id=blk1,drive=hd1,scsi=off%s" % options.virtio_device_suffix,
183+
"-drive", "file=%s,if=none,id=hd1" % (options.second_disk_image)]
184+
180185
if options.virtio_fs_tag:
181186
dax = (",cache-size=%s" % options.virtio_fs_dax) if options.virtio_fs_dax else ""
182187
args += [
@@ -589,6 +594,8 @@ def main(options):
589594
help="specify gdb port number")
590595
parser.add_argument("--script", action="store",
591596
help="XEN define configuration script for vif")
597+
parser.add_argument("--second-disk-image", action="store",
598+
help="Path to the optional second disk image that should be attached to the instance")
592599
parser.add_argument("--cloud-init-image", action="store",
593600
help="Path to the optional cloud-init image that should be attached to the instance")
594601
parser.add_argument("-k", "--kernel", action="store_true",
@@ -630,6 +637,11 @@ def main(options):
630637
if not os.path.exists(cmdargs.cloud_init_image):
631638
raise Exception('Cloud-init image %s does not exist.' % cmdargs.cloud_init_image)
632639

640+
if cmdargs.second_disk_image:
641+
cmdargs.second_disk_image = os.path.abspath(cmdargs.second_disk_image)
642+
if not os.path.exists(cmdargs.second_disk_image):
643+
raise Exception('Second disk image %s does not exist.' % cmdargs.second_disk_image)
644+
633645
if cmdargs.virtio_fs_dir and not os.path.exists(cmdargs.virtio_fs_dir):
634646
raise Exception('Directory %s to be exposed through virtio-fs does not exist.' % cmdargs.virtio_fs_dir)
635647

tools/mkfs/mkfs.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static void get_blk_devices(vector<string> &zpool_args)
5151
}
5252

5353
extern "C" void zfsdev_init();
54-
static void mkfs(void)
54+
static void mkfs(int ac, char** av)
5555
{
5656
// Create zfs device, then /etc/mnttab which is required by libzfs
5757
zfsdev_init();
@@ -62,8 +62,8 @@ static void mkfs(void)
6262
assert(fd != -1);
6363
close(fd);
6464

65-
vector<string> zpool_args = {"zpool", "create", "-f", "-R", "/zfs", "osv",
66-
"/dev/vblk0.1"};
65+
const char *dev_name = ac == 2 ? av[1] : "/dev/vblk0.1";
66+
vector<string> zpool_args = {"zpool", "create", "-f", "-R", "/zfs", "osv", dev_name};
6767

6868
get_blk_devices(zpool_args);
6969

@@ -86,7 +86,7 @@ __attribute__((__visibility__("default")))
8686
int main(int ac, char** av)
8787
{
8888
cout << "Running mkfs...\n";
89-
mkfs();
89+
mkfs(ac, av);
9090
sync();
9191
return 0;
9292
}

0 commit comments

Comments
 (0)