Skip to content

HACKONDEX/KUnit_tests_virtio-net

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kernel-Virtio-Research

Linux kernel Virtio-net test research

KUnit test

Commands

  • ./tools/testing/kunit/kunit.py run "virt*" - run all kunit tests that starts with virt

  • ./tools/testing/kunit/kunit.py run --arch=x86_64 - run on other architectures using qemu

  • ./tools/testing/kunit/kunit.py run --arch=s390 --cross_compile=s390x-linux-gnu - specify toolchain for compilation

  • scripts/decode_stacktrace.sh .kunit/vmlinux .kunit < .kunit/test.log | tee .kunit/decoded.log | ./tools/testing/kunit/kunit.py parse - get more detailed, advantage is that stacktrace contains filenames of the functions

  • qemu-system-x86_64 -kernel ./arch/x86_64/boot/bzImage -initrd ramdisk.img -m 4G - run kernel image in qemu

  • mkinitramfs -o ramdiks.img - create ramfs

  • unmkinitramfs <file> <target directory> - unwrap ramfs into a dircetory

  • mount -t debugfs none /sys/kernel/debug - mount debugfs and get the coverage gdna gdno files

  • lcov -t "virtio_test" -o coverage.info -c -d gcovFiles - get coverage from gcda & gcno files which lay in gcovFiles directory

  • genhtml -o coverage.result coverage.info - generates coverage visualisation in directory coverage.results


Configs

  • To run kuint tests for virtio_net add configuration in file linux/drivers/net/Kconfig

      config VIRTIO_NET_TEST
      	tristate "Test for virtio_net" if !KUNIT_ALL_TESTS
      	depends on KUNIT=y
      	select NETDEVICES
      	select NET_CORE
      	select VIRTIO
      	select VIRTIO_NET
      	select NET
      	default KUNIT_ALL_TESTS
    
  • Select will add the dependencies and they will compile with our VIRTIO_NET_TEST, also we add our file with test ot the config VIRTIO_NET_TEST in linux/drivers/net/Makefile

      obj-$(CONFIG_VIRTIO_NET_TEST) += virtio_net.o
    
  • Finally enable test configuration in linux/.kunit/.config and linux/.kunit/.config. Note that we should enable the configuration in both files because, kunit.py script parses both the existing .config and the .kunitconfig files to ensure that .config is a superset of .kunitconfig

      CONFIG_VIRTIO_NET_TEST=y
    
  • Configs for kernel address sanitizer

      CONFIG_KASAN=y
      CONFIG_KASAN_VMALLOC=y
      CONFIG_KASAN_INLINE=y
      CONFIG_KASAN_GENERIC=y
      CONFIG_STACKTRACE=y
    
  • Configs for gdb debugger

      CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
      CONFIG_DEBUG_KERNEL=y
    
  • Confgis for gcov to get coverage data for kernel

      CONFIG_DEBUG_FS=y
      CONFIG_GCOV_KERNEL=y
    
  • Configs for virtio-fs

      CONFIG_VIRTIO=y
      CONFIG_VIRTIO_FS=y
      CONFIG_DAX=y
      CONFIG_FS_DAX=y
      CONFIG_DAX_DRIVER=y
      CONFIG_ZONE_DEVICE=y
    

Running in qemu with kunit_tool

  • Run test isolated using arg --run_isolated "test"

  • ./tools/testing/kunit/kunit.py run --arch=x86_64 --run_isolated "test"

Running with gcov tool

  • In order to get coverage .gcno .gcda files, we need to compile and run the kernel.

  • We can do it manually installing compiled kernel into our OS, or run a VM with compiled kernel using qemu.

  • We want virtio_net.c to be profiled with gcov, so we add these line in linux/drivers/net/Makefile

      GCOV_PROFILE_virtio_net.o := y
    
  • Also to run with gcov we should add appropriate configs to .config.

      CONFIG_DEBUG_FS=y
      CONFIG_GCOV_KERNEL=y
    
  • Compile the kernel and run in VM

  • In guest VM terminal run next command to get the appropiate files

mount -t debugfs none /sys/kernel/debug

  • After that you can find .gcda file in /sys/kernel/debug/gcov

  • The .gcno file must be available after compiling the kernel


Virtual machine manager with Virtio-FS

  • Compile the kernel with required configs on

      	CONFIG_VIRTIO=y
      	CONFIG_VIRTIO_FS=y
          CONFIG_DAX=y
              CONFIG_FS_DAX=y
              CONFIG_DAX_DRIVER=y
              CONFIG_ZONE_DEVICE=y
    
  • After compilation finishes we can find bzImage with path arch/x86/boot/bzImage which is a binary file

  • Create ramfs ramdisk.img file with command mkinitramfs -o ramdiks.img and keep it in one directory with bzImage

  • Download, install and open Virtual Machine Manager

  • Click Create new instance and choose manual installaion

  • As operating system choose Generic linux 2020

  • Memory 4096, and cpu 2 (recommended parameters)

  • Disable storage for this virtual machine

  • Name VM and enable option Customize configuration before isntall

  • In Memory section enable Shared Memory option

  • In Boot options section open kernel manual boot and click Browse for Kernel Path

  • In opened menu click Add pool and choose the directory where bzImage and ramdisk.img already lay

  • Then from your new pool choose file bzImage, and click choose Volume

  • Click Browse for initrd path, and choose ramdisk.img from the same pool, click apply

  • Click add Hardware in the left bottom corner, choose section filesystem, choose virtiofs, choose path to the future shared directory, and also give it a name in target path field

  • Click start installation, after which you should see terminal of the VM

  • mount -t virtiofs <name> <path where you want to mount shared directory> - run this command to mount virtiofs shared folder

  • Now we can transfer files from host machine to VM and vice versa


kernel compile guide

  • make menuconfig - creates .config file in linux directory

  • Add next configs in order to compile with kunit test, gcov and virtiofs

      	CONFIG_KUNIT=y
      	CONFIG_KUNIT_ALL_TESTS=y
      	CONFIG_KUNIT_DEBUGFS=y
      	CONFIG_KUNIT_TEST=y
      	CONFIG_KUNIT_DEFAULT_ENABLED=y
    
      	CONFIG_VIRTIO=y
      	CONFIG_VIRTIO_FS=y
      	CONFIG_DAX=y
      	CONFIG_FS_DAX=y
      	CONFIG_DAX_DRIVER=y
      	CONFIG_ZONE_DEVICE=y
    
      	CONFIG_DEBUG_FS=y
      	CONFIG_GCOV_KERNEL=y
      	CONFIG_GCOV_PROFILE_FTRACE=y
    
  • If you have error like this on ubuntu

CC certs/system_keyring.o make[2]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop. make[1]: *** [scripts/Makefile.build:504: certs] Error 2 make: *** [Makefile:2021: .] Error 2

  • Then this commands can help

scripts/config --disable SYSTEM_TRUSTED_KEYS

scripts/config --disable SYSTEM_REVOCATION_KEYS

  • After running both commands above, run make and tab enter for both new options

Notes, Kernel, basics

Classes

Classes are not a construct that is built into the C programming language; however, it is an easily derived concept. Accordingly, in most cases, every project that does not use a standardized object oriented library (like GNOME’s GObject) has their own slightly different way of doing object oriented programming; the Linux kernel is no exception.

The central concept in kernel object oriented programming is the class. In the kernel, a class is a struct that contains function pointers. This creates a contract between implementers and users since it forces them to use the same function signature without having to call the function directly. To be a class, the function pointers must specify that a pointer to the class, known as a class handle, be one of the parameters. Thus the member functions (also known as methods) have access to member variables (also known as fields) allowing the same implementation to have multiple instances.

A class can be overridden by child classes by embedding the parent class in the child class. Then when the child class method is called, the child implementation knows that the pointer passed to it is of a parent contained within the child. Thus, the child can compute the pointer to itself because the pointer to the parent is always a fixed offset from the pointer to the child. This offset is the offset of the parent contained in the child struct.


Useful links

KernelSource

Introduction to virtio-networking and vhost-net

Build linux kernel

Linux kernel with qemu

Booting custom linux kernel in qemu

Tips for running kunit tests

Using gcov with linux kernel

List of maintainers and how to submit kernel changes

Tips for running kunit test

Kernel compilers

Kcov code coverage for fuzzing

Runnign test with kunit tool

How gcov works

virtio-fs kernel

virtio-fs.gitlab how to qemu

virtio-fs con

Securely booting confidential VMs with encrypting disk

elixir.bootlin.com

KConfig language

Martin Fowler, vocabulary


linux kernel testing and debugging

virtio networking red hat

virtio net failover introduction

deep into vhost, virtio-networking

docs oasis

  1. ibm software testing

  2. testing

  3. unit testing

  4. habr testing

  5. amazon debug

  6. Martin Fowler, vocabulary

StepByStep

  • cd ~

  • mkdir workspace

  • cd workspace

  • wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.3.tar.xz

  • tar xvf linux-5.10.3.tar.xz

  • wget https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.3.0/x86_64-gcc-11.3.0-nolibc-x86_64-linux.tar.xz

  • tar xvf x86_64-gcc-11.3.0-nolibc-x86_64-linux.tar.xz

  • cd linux-5.10.3

  • ./tools/testing/kunit/kunit.py run

  • cd drivers/net

  • touch virtio_net_test.c virtio_net_test.h

  • cd ../..

About

Linux Kernel VirtioNet test research

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages