Google Summer of Code 2021 (2)

Configure your environment

Before diving into libvirt's codebase, you may need to configure your system and IDE to assist your development. If you are familiar with these things, you can just start to read codes or write some codes right now. And according to libvirt's contributing guidance, there are a lot of things we have to comply with.

Configure git send-mail

As you may notice, people are sending patches to the mailing lists, and they are not copying-pasting patches to mail clients and send, they are using git send-mail, so you have to configure it before we send patches. You have to configure an SMTP client before we start to configure git send-mail, and I'm using msmtp here, you can choose your own one. Here is my ~/.msmtprc config without my privacy info.

# Set default values for all following accounts.
defaults
auth           oauthbearer
tls            on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        ~/.msmtp.log

# Gmail
account        gmail
host           smtp.gmail.com
# If you need a proxy
# proxy_host     127.0.0.1
# proxy_port     7891
port           587
from           youraddr@gmail.com
user           youraddr@gmail.com
passwordeval   "Your own script to renew Gmail OAuth tokens"

account default : gmail

For more info, please check out ArchWiki. And just like what I said in the previous post, if you are in China and you insist to use Gmail, you may need a proxy to use it normally, and configure that on your own. Note that Gmail won't support login with password unless you adjust some settings, or you should write or search for a script to do OAuth login. After testing your msmtp config works, you can now add these to your git config file.

[sendemail]
        from = Your Name <youraddr@gmail.com>
        smtpuser =
        smtpserver = "/usr/bin/msmtp"
        smtpencryption = tls

Test config with git send-email --confirm=always --to=someaddr@gmail.com master, edit the mails according to the comments, send emails, and see if you receive them, if not, fix your configs, if you receive patches, congratulations! You are done with this part. Remember to comply with libvirt's advice, and there are a lot of git send-email options you can adjust, like --suppress-cc=all if you don't want to cc the mail to someone by accident.

Configure your IDE

To have a better development experience, I suggest you developing libvirt in Linux instead of other systems, because we would have a package manager to install some libs which we need to compile the libvirt. Of course, you can use Windows / FreeBSD / macOS or some other systems if you know how to solve problems (and luckily, for developing the test driver, we don't need to care about which virtualization tech does the OS support).

You can choose your favorite IDE or text editor, I'm using Virtual Studio Code so I will show how I configure it below.

Compile

First, you have to install dependencies before compiling libvirt, you can look for them in your system's libvirt package file. For example, I am using Arch Linux, so I can head to PKGBUILD for libvirt

depends=('libpciaccess' 'yajl' 'fuse2' 'gnutls' 'parted' 'libssh' 'libxml2' 'numactl' 'polkit')
makedepends=('meson' 'libxslt' 'python-docutils' 'lvm2' 'open-iscsi' 'libiscsi' 'ceph-libs' 'glusterfs' 'bash-completion' 'rpcsvc-proto' 'dnsmasq' 'iproute2' 'qemu-headless')
optdepends=('libvirt-storage-gluster: Gluster storage backend'
            'libvirt-storage-iscsi-direct: iSCSI-direct storage backend'
            'libvirt-storage-rbd: RBD storage backend'
            'gettext: required for libvirt-guests.service'
            'openbsd-netcat: for remote management over ssh'
            'dmidecode: DMI system info support'
            'dnsmasq: required for default NAT/DHCP for guests'
            'radvd: IPv6 RAD support'
            'ebtables: required for default NAT networking'
            'qemu: QEMU/KVM support'
            'lvm2: Logical Volume Manager support'
            'open-iscsi: iSCSI support via iscsiadm')

So just install packages in depends and makedepends with pacman, don't forget to install gcc or clang as a compiler, and we can start to compile.

Libvirt's website also gives some examples on how to compile here, you can follow them.

Now we have self-compiled virsh binary in /path/to/your/source/build/tools/virsh, if you only want to develop the test driver, we don't need to run a daemon, just debug with virsh is enough.

Debug

Now, we have codes, we have binaries, but how can we debug? With VSCode, we can use the cpptools plugin in the official market, and make a new dir called .vscode in your source code dir, place a launch.json file in it.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "/path/to/your/source/code/build/tools/virsh",
            "args": [
                "-c", "test:///path/to/your/source/code/examples/xml/test/testnode.xml",
            ],
            "cwd": "${workspaceRoot}",
            "MiMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
        }
    ]
}

And a c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/clang",
            "compileCommands": "${workspaceFolder}/build/compile_commands.json"
        }
    ],
    "version": 4
}

Then you can use the VSCode's debug option in the sidebar, begin the debug, add breakpoints, checkout call stacks, inspect variables, it's pretty convenient. If you have known gdb or lldb well, it's also pretty nice to run them in cli.

Memory leak?

Normally, I am using

$ valgrind --tool=memcheck --leak-check=full --track-origins=yes --keep-stacktraces=alloc-and-free -s ./build/tools/virsh -c test:///path/to/your/source/examples/xml/test/testnode.xml

and execute some commands to see if there are memory leaks, if you know how to adjust valgrind options and find out these options are not good enough, please tell me, thanks :). You don't have to debug with valgrind though, cause running the program with valgrind is pretty slow, just check it before your commit.

Now, you can start to code, and submit your patches, don't forget to run ninja -C build test before your commit (or you can add git hooks) and you can also fork the libvirt repo in GitLab, so you could have CI (for FreeBSD and macOS CI, you have to configure it according to ci/README.rst) to help you find if there are any problems. Commit messages sometimes are pretty important, if your code uses some tricks or changed something, you'd better state them clearly in your commit message, you can look at how other people do.

Some advice

Happy coding! :)