diff --git a/.github/workflows/demo_test.yml b/.github/workflows/demo_test.yml index d373896f..e89229a4 100644 --- a/.github/workflows/demo_test.yml +++ b/.github/workflows/demo_test.yml @@ -1289,3 +1289,22 @@ jobs: - name: Clean Swtpm test run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos && rm -rf ./swtpm" + + + Filebench_test: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v1 + with: + submodules: true + + - uses: ./.github/workflows/composite_action/sim + with: + container-name: ${{ github.job }} + build-envs: 'OCCLUM_RELEASE_BUILD=1' + + - name: Preinstall dependencies and build Filebench + run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/benchmarks/filebench && ./preinstall_deps.sh && ./dl_and_build_filebench.sh" + + - name: Prepare occlum instance and Run Filebench on Ext2 + run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/benchmarks/filebench && SGX_MODE=SIM ./run_workload.sh readfiles" diff --git a/demos/benchmarks/filebench/.gitignore b/demos/benchmarks/filebench/.gitignore new file mode 100644 index 00000000..4ecd517b --- /dev/null +++ b/demos/benchmarks/filebench/.gitignore @@ -0,0 +1,3 @@ +filebench +filebench*.tar.gz +occlum_instance diff --git a/demos/benchmarks/filebench/README.md b/demos/benchmarks/filebench/README.md new file mode 100644 index 00000000..c91e095e --- /dev/null +++ b/demos/benchmarks/filebench/README.md @@ -0,0 +1,25 @@ +## Run Filebench on Occlum + +[Filebench](https://github.com/Filebench/Filebench) is a benchmark tool aiming to test the file system and the storage system under certain workloads. This demo demonstrates how can Filebench run on Occlum. + +### Step 1: Preinstall dependencies +Related dependencies: bison flex +``` +cd demos/benchmarks/filebench && ./preinstall_deps.sh +``` + +### Step 2: Build Filebench from source +``` +cd demos/benchmarks/filebench && ./dl_and_build_Filebench.sh +``` + +The script will download the source code, make some adaptation then compile Filebench into a binary. + +### Step 3: Run Filebench workloads +``` +cd demos/benchmarks/filebench && ./run_workload.sh +``` + +The script will run user-specific workloads under `filebench/workloads`. The corresponding results will be outputed. + +Refer to [Filebench/wiki/Workload-model-language](https://github.com/Filebench/Filebench/wiki/Workload-model-language) and see more information about workloads. diff --git a/demos/benchmarks/filebench/apply-filebench-to-occlum.patch b/demos/benchmarks/filebench/apply-filebench-to-occlum.patch new file mode 100644 index 00000000..43556128 --- /dev/null +++ b/demos/benchmarks/filebench/apply-filebench-to-occlum.patch @@ -0,0 +1,63 @@ +diff --color -ruN filebench/config.h modify/config.h +--- filebench/config.h 2022-05-10 11:24:44.393676003 +0800 ++++ modify/config.h 2022-05-10 11:15:23.769794727 +0800 +@@ -295,6 +295,7 @@ + + /* Define if you have SYSV sems */ + #define HAVE_SYSV_SEM 1 ++#undef HAVE_SYSV_SEM + + /* Define to 1 if you have the header file, and it defines `DIR'. + */ +diff --color -ruN filebench/ipc.c modify/ipc.c +--- filebench/ipc.c 2022-05-10 11:24:44.393676003 +0800 ++++ modify/ipc.c 2022-05-10 11:16:06.768145518 +0800 +@@ -400,21 +400,22 @@ + int + ipc_attach(void *shmaddr, char *shmpath) + { +- int shmfd; ++ // int shmfd; + +- if ((shmfd = open(shmpath, O_RDWR)) < 0) { +- filebench_log(LOG_FATAL, "Could not open shared memory " +- "file %s: %s", shmpath, strerror(errno)); +- return (-1); +- } ++ // if ((shmfd = open(shmpath, O_RDWR)) < 0) { ++ // filebench_log(LOG_FATAL, "Could not open shared memory " ++ // "file %s: %s", shmpath, strerror(errno)); ++ // return (-1); ++ // } + +- if ((filebench_shm = (filebench_shm_t *)mmap(shmaddr, +- sizeof (filebench_shm_t), PROT_READ | PROT_WRITE, +- MAP_SHARED | MAP_FIXED, shmfd, 0)) == MAP_FAILED) { +- filebench_log(LOG_FATAL, "Could not mmap the shared " +- "memory file: %s", strerror(errno)); +- return (-1); +- } ++ // if ((filebench_shm = (filebench_shm_t *)mmap(shmaddr, ++ // sizeof (filebench_shm_t), PROT_READ | PROT_WRITE, ++ // MAP_SHARED | MAP_FIXED, shmfd, 0)) == MAP_FAILED) { ++ // filebench_log(LOG_FATAL, "Could not mmap the shared " ++ // "memory file: %s", strerror(errno)); ++ // return (-1); ++ // } ++ filebench_shm = (filebench_shm_t *)shmaddr; + + if (filebench_shm != shmaddr) { + filebench_log(LOG_FATAL, "Could not mmap the shared " +diff --color -ruN filebench/procflow.c modify/procflow.c +--- filebench/procflow.c 2022-05-10 11:24:44.393676003 +0800 ++++ modify/procflow.c 2022-05-10 11:16:35.772217279 +0800 +@@ -90,7 +90,8 @@ + return (-1); + } + #else +- if ((pid = fork()) < 0) { ++ // if ((pid = fork()) < 0) { ++ if ((pid = vfork()) < 0) { + filebench_log(LOG_ERROR, + "procflow_createproc fork failed: %s", + strerror(errno)); diff --git a/demos/benchmarks/filebench/dl_and_build_filebench.sh b/demos/benchmarks/filebench/dl_and_build_filebench.sh new file mode 100755 index 00000000..763d660a --- /dev/null +++ b/demos/benchmarks/filebench/dl_and_build_filebench.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -e + +BLUE='\033[1;34m' +NC='\033[0m' +echo -e "${BLUE}Start building filebench from tarball.${NC}" + +# Download release tarball +VERSION="1.5-alpha3" +TARBALL="filebench-${VERSION}.tar.gz" +rm -f ${TARBALL} +wget https://github.com/filebench/filebench/releases/download/${VERSION}/${TARBALL} +rm -rf filebench && mkdir filebench +tar -zxvf filebench-${VERSION}.tar.gz -C filebench --strip-components 1 +pushd filebench + +./configure +popd + +# Make modification to +# 1. Replace fork to vfork +# 2. Prepare shared memory region for child processes +# 3. Disable SYSV semaphores +patch -s -p0 < apply-filebench-to-occlum.patch + +pushd filebench +# Build and install filebench tool +make -j$(nproc) +make install +echo -e "${BLUE}Finish building filebench from tarball.${NC}" + +popd diff --git a/demos/benchmarks/filebench/filebench.yaml b/demos/benchmarks/filebench/filebench.yaml new file mode 100644 index 00000000..523f70c0 --- /dev/null +++ b/demos/benchmarks/filebench/filebench.yaml @@ -0,0 +1,18 @@ +includes: + - base.yaml +# filebench +targets: + # copy filebench, bash and busybox + - target: /bin + copy: + - files: + - /usr/local/bin/filebench + # copy workload files + - target: / + copy: + - dirs: + - ../workloads + - target: /opt/occlum/glibc/lib + copy: + - files: + - /lib/x86_64-linux-gnu/libgcc_s.so.1 diff --git a/demos/benchmarks/filebench/preinstall_deps.sh b/demos/benchmarks/filebench/preinstall_deps.sh new file mode 100755 index 00000000..d0deea1a --- /dev/null +++ b/demos/benchmarks/filebench/preinstall_deps.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +BLUE='\033[1;34m' +NC='\033[0m' +echo -e "${BLUE}Start installing dependencies.${NC}" + +DEPS="bison flex" + +OS=`awk -F= '/^NAME/{print $2}' /etc/os-release` +if [ "$OS" == "\"Ubuntu\"" ]; then + apt-get update -y && apt-get install -y ${DEPS} +else + echo "Unsupported OS: $OS" + exit 1 +fi + +echo -e "${BLUE}Finish installing dependencies.${NC}" diff --git a/demos/benchmarks/filebench/run_workload.sh b/demos/benchmarks/filebench/run_workload.sh new file mode 100755 index 00000000..3a055e4c --- /dev/null +++ b/demos/benchmarks/filebench/run_workload.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -e + +WORKLOAD_LIST=("readfiles" "videoserver" "fileserver" "varmail" "oltp") +# More about workload model language at +# https://github.com/filebench/filebench/wiki/Workload-model-language + +WORKLOAD_FILE=$1 +if [[ ! " ${WORKLOAD_LIST[@]} " =~ " ${WORKLOAD_FILE} " ]]; then + echo "Please select a workload from: readfiles | videoserver | fileserver | varmail | oltp" + exit +fi + +# 1. Init Occlum Workspace +rm -rf occlum_instance && occlum new occlum_instance +cd occlum_instance + +# Enlarge "kernel_space_heap_size" when "pre-allocating files failed" occurs +# Enlarge "user_space_size" when "procflow exec proc failed" occurs +TCS_NUM=$(($(nproc) * 2)) +new_json="$(jq --argjson THREAD_NUM ${TCS_NUM} '.resource_limits.user_space_size="2000MB" | + .resource_limits.kernel_space_heap_max_size="1000MB" | + .resource_limits.max_num_of_threads = $THREAD_NUM | + .mount += [{"target": "/ext2", "type": "ext2", "options": {"disk_size": "10GB"}}]' Occlum.json)" && \ +echo "${new_json}" > Occlum.json + +# 2. Copy files into Occlum Workspace and build +rm -rf image +copy_bom -f ../filebench.yaml --root image --include-dir /opt/occlum/etc/template + +occlum build + +# 3. Run benchmark under different workloads +BLUE='\033[1;34m' +NC='\033[0m' +echo -e "${BLUE}Run filebench on Occlum.${NC}" + +occlum run /bin/filebench -f /workloads/${WORKLOAD_FILE}.f diff --git a/demos/benchmarks/filebench/workloads/fileserver.f b/demos/benchmarks/filebench/workloads/fileserver.f new file mode 100644 index 00000000..08b4c41c --- /dev/null +++ b/demos/benchmarks/filebench/workloads/fileserver.f @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +set $dir=/ext2/fbtest_ext2 +set $nfiles=10000 +set $meandirwidth=20 +set $filesize=128k +set $nthreads=16 +set $iosize=1m +set $meanappendsize=16k + +define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80 + +define process name=filereader,instances=1 +{ + thread name=filereaderthread,memsize=10m,instances=$nthreads + { + flowop createfile name=createfile1,filesetname=bigfileset,fd=1 + flowop writewholefile name=wrtfile1,srcfd=1,fd=1,iosize=$iosize + flowop closefile name=closefile1,fd=1 + flowop openfile name=openfile1,filesetname=bigfileset,fd=1 + flowop appendfilerand name=appendfilerand1,iosize=$meanappendsize,fd=1 + flowop closefile name=closefile2,fd=1 + flowop openfile name=openfile2,filesetname=bigfileset,fd=1 + flowop readwholefile name=readfile1,fd=1,iosize=$iosize + flowop closefile name=closefile3,fd=1 + flowop deletefile name=deletefile1,filesetname=bigfileset + flowop statfile name=statfile1,filesetname=bigfileset + } +} + +echo "File-server Version 3.0 personality successfully loaded" + +run 60 diff --git a/demos/benchmarks/filebench/workloads/oltp.f b/demos/benchmarks/filebench/workloads/oltp.f new file mode 100644 index 00000000..7e6f8f29 --- /dev/null +++ b/demos/benchmarks/filebench/workloads/oltp.f @@ -0,0 +1,82 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# Workload "oltp" from filebench cannot run directly on Occlum +# since aio write/wait and semaphore-related flowops are not supported. +# We replace some flowops to achieve similar performance quota. + +set $dir=/root/fbtest +set $eventrate=0 +set $iosize=2k +set $nshadows=200 +set $ndbwriters=10 +set $usermode=200000 +set $filesize=10m +set $memperthread=1m +set $workingset=0 +set $logfilesize=10m +set $nfiles=10 +set $nlogfiles=1 +set $directio=0 +eventgen rate = $eventrate + +# Define a datafile and logfile +define fileset name=datafiles,path=$dir,size=$filesize,entries=$nfiles,dirwidth=1024,prealloc=100,reuse +define fileset name=logfile,path=$dir,size=$logfilesize,entries=$nlogfiles,dirwidth=1024,prealloc=100,reuse + +define process name=lgwr,instances=1 +{ + thread name=lgwr,memsize=$memperthread + { + flowop write name=lg-write,filesetname=logfile, + iosize=256k,random,directio=$directio,dsync + } +} + +# Define database writer processes +define process name=dbwr,instances=$ndbwriters +{ + thread name=dbwr,memsize=$memperthread + { + flowop write name=dbwrite-a,filesetname=datafiles, + iosize=$iosize,workingset=$workingset,random,iters=100,opennext,directio=$directio,dsync + flowop hog name=dbwr-hog,value=10000 + } +} + +define process name=shadow,instances=$nshadows +{ + thread name=shadow,memsize=$memperthread + { + flowop read name=shadowread,filesetname=datafiles, + iosize=$iosize,workingset=$workingset,random,opennext,directio=$directio + flowop hog name=shadowhog,value=$usermode + flowop eventlimit name=random-rate + } +} + +echo "OLTP Version 3.0 personality successfully loaded" + +run 60 diff --git a/demos/benchmarks/filebench/workloads/readfiles.f b/demos/benchmarks/filebench/workloads/readfiles.f new file mode 100644 index 00000000..018f4756 --- /dev/null +++ b/demos/benchmarks/filebench/workloads/readfiles.f @@ -0,0 +1,11 @@ +# A simple readfiles workload + +define fileset name="testF",entries=16,filesize=4k,path="/ext2/fbtest_ext2",prealloc +define process name="readerP",instances=1 { +thread name="readerT",instances=1 { + flowop openfile name="openOP",filesetname="testF" + flowop readwholefile name="readOP",filesetname="testF" + flowop closefile name="closeOP" +} +} +run 30 diff --git a/demos/benchmarks/filebench/workloads/varmail.f b/demos/benchmarks/filebench/workloads/varmail.f new file mode 100644 index 00000000..bb68f84d --- /dev/null +++ b/demos/benchmarks/filebench/workloads/varmail.f @@ -0,0 +1,60 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# flowop openfile name=openfile2,filesetname=bigfileset,fd=1 +# + +set $dir=/root/fbtest +set $nfiles=8000 +set $meandirwidth=1000 +set $filesize=16k +set $nthreads=16 +set $iosize=1m +set $meanappendsize=16k + +define fileset name=bigfileset,path=$dir,size=$filesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80 + +define process name=filereader,instances=1 +{ + thread name=filereaderthread,memsize=10m,instances=$nthreads + { + flowop deletefile name=deletefile1,filesetname=bigfileset + flowop createfile name=createfile2,filesetname=bigfileset,fd=1 + flowop appendfilerand name=appendfilerand2,iosize=$meanappendsize,fd=1 + flowop fsync name=fsyncfile2,fd=1 + flowop closefile name=closefile2,fd=1 + flowop openfile name=openfile3,filesetname=bigfileset,fd=1 + flowop readwholefile name=readfile3,fd=1,iosize=$iosize + flowop appendfilerand name=appendfilerand3,iosize=$meanappendsize,fd=1 + flowop fsync name=fsyncfile3,fd=1 + flowop closefile name=closefile3,fd=1 + flowop openfile name=openfile4,filesetname=bigfileset,fd=1 + flowop readwholefile name=readfile4,fd=1,iosize=$iosize + flowop closefile name=closefile4,fd=1 + } +} + +echo "Varmail Version 3.0 personality successfully loaded" + +run 60 diff --git a/demos/benchmarks/filebench/workloads/videoserver.f b/demos/benchmarks/filebench/workloads/videoserver.f new file mode 100644 index 00000000..478000ef --- /dev/null +++ b/demos/benchmarks/filebench/workloads/videoserver.f @@ -0,0 +1,76 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This workloads emulates a video server. It has two filesets, one of videos +# being actively served, and one of videos availabe but currently inactive +# (passive). However, one thread, vidwriter, is writing new videos to replace +# no longer viewed videos in the passive set. Meanwhile $nthreads threads are +# serving up videos from the activevids fileset. If the desired rate is R mb/s, +# and $nthreads is set to T, then set the $srvbwrate to R * T to get the +# desired rate per video stream. The video replacement rate of one video +# file per replacement interval, is set by $repintval which defaults to +# 1 second. Thus the write bandwidth will be set as $filesize/$repintval. +# + +set $dir=/root/fbtest +set $eventrate=96 +set $filesize=1g +set $nthreads=48 +set $numactivevids=5 +set $numpassivevids=30 +set $reuseit=false +set $readiosize=256k +set $writeiosize=1m +set $passvidsname=passivevids +set $actvidsname=activevids +set $repintval=10 +eventgen rate=$eventrate + +define fileset name=$actvidsname,path=$dir,size=$filesize,entries=$numactivevids,dirwidth=4,prealloc,paralloc,reuse=$reuseit +define fileset name=$passvidsname,path=$dir,size=$filesize,entries=$numpassivevids,dirwidth=20,prealloc=50,paralloc,reuse=$reuseit + +define process name=vidwriter,instances=1 +{ + thread name=vidwriter,memsize=10m,instances=1 + { + flowop deletefile name=vidremover,filesetname=$passvidsname + flowop createfile name=wrtopen,filesetname=$passvidsname,fd=1 + flowop writewholefile name=newvid,iosize=$writeiosize,fd=1,srcfd=1 + flowop closefile name=wrtclose, fd=1 + flowop delay name=replaceinterval, value=$repintval + } +} + +define process name=vidreaders,instances=1 +{ + thread name=vidreaders,memsize=10m,instances=$nthreads + { + flowop read name=vidreader,filesetname=$actvidsname,iosize=$readiosize + flowop bwlimit name=serverlimit, target=vidreader + } +} + +echo "Video Server Version 3.0 personality successfully loaded" + +run 60