1 #!/bin/bash 2 3 # Kernel configuration options. 4 OPTIONS=" DEBUG_SPINLOCK DEBUG_ATOMIC_SLEEP DEBUG_MUTEXES DEBUG_RT_MUTEXES" 5 OPTIONS="$OPTIONS IPV6 IPV6_ROUTER_PREF IPV6_MULTIPLE_TABLES IPV6_ROUTE_INFO" 6 OPTIONS="$OPTIONS TUN SYN_COOKIES IP_ADVANCED_ROUTER IP_MULTIPLE_TABLES" 7 OPTIONS="$OPTIONS NETFILTER NETFILTER_ADVANCED NETFILTER_XTABLES" 8 OPTIONS="$OPTIONS NETFILTER_XT_MARK NETFILTER_XT_TARGET_MARK" 9 OPTIONS="$OPTIONS IP_NF_IPTABLES IP_NF_MANGLE IP_NF_FILTER" 10 OPTIONS="$OPTIONS IP6_NF_IPTABLES IP6_NF_MANGLE IP6_NF_FILTER INET6_IPCOMP" 11 OPTIONS="$OPTIONS IPV6_PRIVACY IPV6_OPTIMISTIC_DAD" 12 OPTIONS="$OPTIONS CONFIG_IPV6_ROUTE_INFO CONFIG_IPV6_ROUTER_PREF" 13 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_TARGET_NFLOG" 14 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA" 15 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA2" 16 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG" 17 OPTIONS="$OPTIONS CONFIG_NETFILTER_TPROXY" 18 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_SOCKET" 19 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QTAGUID" 20 OPTIONS="$OPTIONS CONFIG_INET_UDP_DIAG CONFIG_INET_DIAG_DESTROY" 21 OPTIONS="$OPTIONS IP_SCTP INET_SCTP_DIAG" 22 OPTIONS="$OPTIONS CONFIG_IP_NF_TARGET_REJECT CONFIG_IP_NF_TARGET_REJECT_SKERR" 23 OPTIONS="$OPTIONS CONFIG_IP6_NF_TARGET_REJECT CONFIG_IP6_NF_TARGET_REJECT_SKERR" 24 OPTIONS="$OPTIONS BPF_SYSCALL NET_KEY XFRM_USER XFRM_STATISTICS CRYPTO_CBC" 25 OPTIONS="$OPTIONS CRYPTO_CTR CRYPTO_HMAC CRYPTO_AES CRYPTO_SHA1 CRYPTO_SHA256" 26 OPTIONS="$OPTIONS CRYPTO_SHA12 CRYPTO_USER INET_AH INET_ESP INET_XFRM_MODE" 27 OPTIONS="$OPTIONS TRANSPORT INET_XFRM_MODE_TUNNEL INET6_AH INET6_ESP" 28 OPTIONS="$OPTIONS INET6_XFRM_MODE_TRANSPORT INET6_XFRM_MODE_TUNNEL" 29 OPTIONS="$OPTIONS CRYPTO_SHA256 CRYPTO_SHA512 CRYPTO_AES_X86_64" 30 OPTIONS="$OPTIONS CRYPTO_ECHAINIV NET_IPVTI IP6_VTI" 31 OPTIONS="$OPTIONS SOCK_CGROUP_DATA CGROUP_BPF" 32 33 # For 3.1 kernels, where devtmpfs is not on by default. 34 OPTIONS="$OPTIONS DEVTMPFS DEVTMPFS_MOUNT" 35 36 # These two break the flo kernel due to differences in -Werror on recent GCC. 37 DISABLE_OPTIONS=" CONFIG_REISERFS_FS CONFIG_ANDROID_PMEM" 38 # This one breaks the fugu kernel due to a nonexistent sem_wait_array. 39 DISABLE_OPTIONS="$DISABLE_OPTIONS CONFIG_SYSVIPC" 40 41 # How many TAP interfaces to create to provide the VM with real network access 42 # via the host. This requires privileges (e.g., root access) on the host. 43 # 44 # This is not needed to run the tests, but can be used, for example, to allow 45 # the VM to update system packages, or to write tests that need access to a 46 # real network. The VM does not set up networking by default, but it contains a 47 # DHCP client and has the ability to use IPv6 autoconfiguration. This script 48 # does not perform any host-level setup beyond configuring tap interfaces; 49 # configuring IPv4 NAT and/or IPv6 router advertisements or ND proxying must 50 # be done separately. 51 NUMTAPINTERFACES=0 52 53 # The root filesystem disk image we'll use. 54 ROOTFS=net_test.rootfs.20150203 55 COMPRESSED_ROOTFS=$ROOTFS.xz 56 URL=https://dl.google.com/dl/android/$COMPRESSED_ROOTFS 57 58 # Parse arguments and figure out which test to run. 59 J=${J:-64} 60 MAKE="make" 61 OUT_DIR=$(readlink -f ${OUT_DIR:-.}) 62 KERNEL_DIR=$(readlink -f ${KERNEL_DIR:-.}) 63 if [ "$OUT_DIR" != "$KERNEL_DIR" ]; then 64 MAKE="$MAKE O=$OUT_DIR" 65 fi 66 SCRIPT_DIR=$(dirname $(readlink -f $0)) 67 CONFIG_SCRIPT=${KERNEL_DIR}/scripts/config 68 CONFIG_FILE=${OUT_DIR}/.config 69 consolemode= 70 testmode= 71 blockdevice=ubda 72 nobuild=0 73 norun=0 74 75 while [ -n "$1" ]; do 76 if [ "$1" = "--builder" ]; then 77 consolemode="con=null,fd:1" 78 testmode=builder 79 shift 80 elif [ "$1" == "--readonly" ]; then 81 blockdevice="${blockdevice}r" 82 shift 83 elif [ "$1" == "--nobuild" ]; then 84 nobuild=1 85 shift 86 elif [ "$1" == "--norun" ]; then 87 norun=1 88 shift 89 else 90 test=$1 91 break # Arguments after the test file are passed to the test itself. 92 fi 93 done 94 95 # Check that test file exists and is readable 96 test_file=$SCRIPT_DIR/$test 97 if [[ ! -e $test_file ]]; then 98 echo "test file '${test_file}' does not exist" 99 exit 1 100 fi 101 102 if [[ ! -x $test_file ]]; then 103 echo "test file '${test_file}' is not executable" 104 exit 1 105 fi 106 107 # Collect trailing arguments to pass to $test 108 test_args=${@:2} 109 110 function isRunningTest() { 111 [[ -n "$test" ]] && ! (( norun )) 112 } 113 114 function isBuildOnly() { 115 [[ -z "$test" ]] && (( norun )) && ! (( nobuild )) 116 } 117 118 if ! isRunningTest && ! isBuildOnly; then 119 echo "Usage:" >&2 120 echo " $0 [--builder] [--readonly] [--nobuild] <test>" >&2 121 echo " $0 --norun" >&2 122 exit 1 123 fi 124 125 cd $OUT_DIR 126 echo Running tests from: `pwd` 127 128 set -e 129 130 # Check if we need to uncompress the disk image. 131 # We use xz because it compresses better: to 42M vs 72M (gzip) / 62M (bzip2). 132 cd $SCRIPT_DIR 133 if [ ! -f $ROOTFS ]; then 134 echo "Deleting $COMPRESSED_ROOTFS" >&2 135 rm -f $COMPRESSED_ROOTFS 136 echo "Downloading $URL" >&2 137 wget -nv $URL 138 echo "Uncompressing $COMPRESSED_ROOTFS" >&2 139 unxz $COMPRESSED_ROOTFS 140 fi 141 echo "Using $ROOTFS" 142 cd - 143 144 # If network access was requested, create NUMTAPINTERFACES tap interfaces on 145 # the host, and prepare UML command line params to use them. The interfaces are 146 # called <user>TAP0, <user>TAP1, on the host, and eth0, eth1, ..., in the VM. 147 if (( $NUMTAPINTERFACES > 0 )); then 148 user=${USER:0:10} 149 tapinterfaces= 150 netconfig= 151 for id in $(seq 0 $(( NUMTAPINTERFACES - 1 )) ); do 152 tap=${user}TAP$id 153 tapinterfaces="$tapinterfaces $tap" 154 mac=$(printf fe:fd:00:00:00:%02x $id) 155 netconfig="$netconfig eth$id=tuntap,$tap,$mac" 156 done 157 158 for tap in $tapinterfaces; do 159 if ! ip link list $tap > /dev/null; then 160 echo "Creating tap interface $tap" >&2 161 sudo tunctl -u $USER -t $tap 162 sudo ip link set $tap up 163 fi 164 done 165 fi 166 167 if [ -n "$KERNEL_BINARY" ]; then 168 nobuild=1 169 else 170 KERNEL_BINARY=./linux 171 fi 172 173 if ((nobuild == 0)); then 174 # Exporting ARCH=um SUBARCH=x86_64 doesn't seem to work, as it "sometimes" 175 # (?) results in a 32-bit kernel. 176 177 # If there's no kernel config at all, create one or UML won't work. 178 [ -f $CONFIG_FILE ] || (cd $KERNEL_DIR && $MAKE defconfig ARCH=um SUBARCH=x86_64) 179 180 # Enable the kernel config options listed in $OPTIONS. 181 cmdline=${OPTIONS// / -e } 182 $CONFIG_SCRIPT --file $CONFIG_FILE $cmdline 183 184 # Disable the kernel config options listed in $DISABLE_OPTIONS. 185 cmdline=${DISABLE_OPTIONS// / -d } 186 $CONFIG_SCRIPT --file $CONFIG_FILE $cmdline 187 188 # olddefconfig doesn't work on old kernels. 189 if ! $MAKE olddefconfig ARCH=um SUBARCH=x86_64 CROSS_COMPILE= ; then 190 cat >&2 << EOF 191 192 Warning: "make olddefconfig" failed. 193 Perhaps this kernel is too old to support it. 194 You may get asked lots of questions. 195 Keep enter pressed to accept the defaults. 196 197 EOF 198 fi 199 200 # Compile the kernel. 201 $MAKE -j$J linux ARCH=um SUBARCH=x86_64 CROSS_COMPILE= 202 fi 203 204 if (( norun == 1 )); then 205 exit 0 206 fi 207 208 # Get the absolute path to the test file that's being run. 209 dir=/host$SCRIPT_DIR 210 211 # Start the VM. 212 exec $KERNEL_BINARY umid=net_test $blockdevice=$SCRIPT_DIR/$ROOTFS \ 213 mem=512M init=/sbin/net_test.sh net_test=$dir/$test \ 214 net_test_args=\"$test_args\" \ 215 net_test_mode=$testmode $netconfig $consolemode >&2 216