Tag Archives: linux

Kernel Development with VMs: Some Tips

When doing kernel development, doing it in a virtual machine can be very convenient, if there’s no need for actual hardware devices or features. This is especially true for network or client/server development where multiple physical machines would otherwise be needed. Plus, VMs reboot much faster than actual hardware!

The #1 tip: a shared development directory

My preferred setup is to use KVM via virt-manager. I use my editor and the compiler on the host, and then mount my development directory on the guest, and then install the compiled modules there. This lets development on the host remain undisturbed by unstable kernel versions and new target distro versions. In fact, my host is still on RHEL 6, although I’m working on features for much more current kernels and distro releases.

I use NFS to export a mount point, and then mount it in an identical location in each guest. Then, edit and build the kernel on the host, using the ‘O’ kernel make option to keep .config and build files separate from the kernel’s git tree, although both the source and build dirs are under the mount point accessible to the guest. Finally on the guest, “make O=/path/to/buildfiles modules_install install” and everything’s ready to test.

On a more recent host, and with guests that support it, an easier way to set up a shared directory would be using VirtFS. NFS is a little fiddly to set up for the first time, and virtfs looks pretty easy, and a little faster and secure, even.

Other tips

  1. Guest debug output onto the host. Set up a virtual serial port and point it at a file on the host. Then, add “console=ttyS0,115200 console=tty0” to the guest kernel command line. This will output everything to the file as well as keep outputting to the guest console. Then ‘tail -f’ the file, and you can be assured any kernel oopses or other messages will be captured. The file will be truncated every time the guest is restarted, BTW.
  2. Turn on all relevant debugging options (under “kernel hacking”) when compiling your kernel. If you start with the distribution’s .config file, many won’t be set. I’d recommend turning everything on. Also turn on frame pointers, and configure out drivers and subsystems the guest won’t need. ‘make localmodconfig’ (run from the guest) might help here.
  3. If you are in an edit/compile loop, use the ‘M=’ make option to just build where you’re hacking, and save make from scanning the whole tree. Just use ‘make modules’ (on the host) and ‘make modules_install’ (on the guest) to save time (posttest??? arrgh) and not reinstall a kernel if it hasn’t actually changed. The build will increment the kernel version, which is printed during build and in ‘uname -v’ output, only if it actually built a new kernel image.
  4. Get an SSD. Pays for itself in saved time almost instantly.
  5. Use ccache. If a source file has already been built with identical headers, ccache keeps the object around and saves the build from doing repeated work. This is as simple as installing ccache on the host, and then setting ‘export CC="ccache gcc"’ in your .bash_profile.
  6. Make sure your guest has two or more virtual CPUs, in order to properly expose yourself to races when testing.
  7. Set guests to auto-login and turn off screen savers. Use Ctrl-R (reverse history search) in bash aggressively when repeating test steps on the guest. Give different guests different-colored backgrounds to tell them apart more easily.
  8. Make sure lockdep checking is enabled, and hasn’t fired earlier in the boot process, because then it turns itself off.
  9. Familiarize yourself with magic-sysrq feature in Documentation/sysrq.txt, and poking it via /proc/sysrq-trigger.

I hope some of this is helpful, and I’d love to know about more tips and techniques people have.

EDIT: Some more tips in G+ comments here!

O’Reilly Webcast: The Linux Way, and natural selection among distros

Before speaking at OSCON 2013, I gave a webcast version of my talk, and it’s now posted to Youtube (actual talk starting at 4m30s.)

  1. Tenets of the Unix Way
  2. History of Unix and Linux
  3. Modern Linux and how it may diverge from Unix
  4. The Linux Way — What is it?

The most significant change between this talk and the talk I gave six weeks later was that I figured out what the actual conclusion of the talk was:

Just like the Unix philosophies enabled the Unix command-line to develop and evolve more rapidly, the mix-and-match nature of Linux distros enables the Linux OS to also evolve more rapidly.

A distro is essentially its pool of packages, plus a handful of mutually-exclusive choices about how to run things. For example, init system, packaging system, and update frequency. These are intrinsic to the distro’s make-up, its ‘DNA’, and go beyond mutually-installable packages like apps and even desktop environments.

The cool thing is that the packages themselves are not part of a distro’s DNA. A new distro can rise up, change fundamental things about how the OS runs, and not have to fork those packages. Compared to forking more monolithic Unixes like *BSD or OpenSolaris, the barrier to entry for a new distro is relatively low, which is maybe why there are so many!

We now have a ‘gene pool’ of distros making different choices, and natural selection acts on this pool as users pick which distro they will use, and developers pick which to build on. This ensures that the Linux OS’s evolution is ultimately driven by its users. A popular distro can make some unpopular changes, but if it keeps doing so, eventually it will hurt its user base so much that other distros will take its place. This is a very good thing, and the conclusion I was trying to reach at the end of this webcast.

New screencast: 10 New Features in LIO and targetcli

I posted a new screencast that talks about ten new ease-of-use features that are new in Fedora 18.

10 New Features in LIO and targetcli

  1. Easier storage->ACL setup
  2. Name shows up as LUN model name
  3. Tags for initiator aliases and grouping
  4. ‘info’ command
  5. IPv6 portal support
  6. WWNs normalized
  7. Only show HW fabrics that are present
  8. 10 previous configs saved
  9. More info in summary
  10. iSER support
  11. Better sorting

Fedora for short-lifespan server instances

I read Mรกirรญn Duffy’s coverage of the Fedora Board’s userbase discussion. Really interesting. I wanted to add my take.

tl;dr: Puppet/Chef make Fedora’s short support period much less of an issue.

The OS is a building block

I’ve been watching a lot of videos on DevOps lately. Several close friends of mine are sysadmins and I’ve been learning a lot from them about the transformation that their profession is undergoing. From this year’s ChefConf, Adam Jacob’s keynote and the talk by Sascha Bates really impressed on me the big change in how admins should view machines — They’re not permanent, or even semi-permanent. They are ephemeral snowflakes that may live a year, or just an hour, so don’t get too attached.

Part of why admins like VMs is because the isolation they provide between different services. I used to run mail, DNS, and httpd from a single machine. Everything was mostly separate but not quite everything. They had separate userids but everyone’s config was in /etc, even touching the same files, sometimes. A full disk affected everybody. /var/log/messages didn’t split up their logging cleanly (by default, anyway.) It all just was built assuming there would be an admin at a command shell who could use their brain to resolve the conflicts to make everything play nice on a single OS image.

One service per instance

Admins adopted VMs for isolation, increased density, and better per-service resource allocation, but then ran into other problems. The setup that they did by hand once per new-hardware now was once per instance. (Editing /etc/sudoers for the fiftieth time gets old.) The tools then evolved further, until today one may keep no persistent state in an instance. Now, an instance is kickstarted into existence and configured automatically for the one job it will ever do. The sysadmin’s job isn’t to herd boxen any more, it’s to build ’em, run ’em, and then reap ’em.

All the OS mechanisms for co-existing server processes, they’re now either obsolete or vestigial to some degree. What is important is the malleability of the OS to assume all the tasks it may be asked to – rather like a stem cell needs to be able to become a nerve or muscle, but never needs to be both.

Never upgrade, just redeploy

Let’s come back to the odd fact that Fedora is both a precursor to RHEL, and yet almost never used in production as a server OS. I think this is going to change. In a world where instances are deployed constantly, instances are born and die but the herd lives on. Once everyone has their infrastructure encoded into a configuration management system, Fedora’s short release cycle becomes much less of a burden. If I have service foo deployed on a Fedora X instance, I will never be upgrading that instance. Instead I’ll be provisioning a new Fedora X+1 instance to run the foo service, start it, and throw the old instance in the proverbial bitbucket once the new one works.

Cheap and easy virt and config management gives admins what they’ve always wanted — stability when they want it (run a LT support distro image, or for the VM host) or the latest stuff for their fast-moving business-oriented instances, by running a fast-update or rolling-release distro.

What Fedora should do

We’re already working on some of these to some degree — I think we should try to do even more to ensure Fedora is useful for the fast-update instance role.

First, Fedora needs to be able to be small. Nobody’s going to read the manpages on a throwaway instance, nobody’s even going to run vi. Image size matters when multiplied for each instance. Can we get by without /usr/share/doc/* and its thousands of copies of the GPL text? Fedora seems pretty good but there must be more we can do.

Second, we need to ensure Fedora supports the packages people are really using these days. Latest Ruby. Latest OpenStack. Vagrant. Django. Chef. Puppet. All the weird JS stuff that’s popular now on GitHub. ๐Ÿ™‚ Continue to improve packaging tools so it’s easier for new contributors to do their first package, as well as for long-time packagers to maintain more packages. And not just package for contribution to Fedora, but for admins to package for solely internal distribution. Like Sascha Bates stresses in her talk, packaging is a huge benefit to automation, but it does require effort. It can be easier.

Finally, I think we need to continue to look at how easy it is to configure and manage an instance of the OS, and tailor it more for automated configuration. I believe the key to this is adding programmatic interfaces where they are lacking. See my “All Plumbing needs an API” talk. Since we’re probably being configured by another piece of code rather than a person at the shell, we need clear, unambiguous programmatic interfaces with good error handling. Chef should not be calling cmdline tools and checking error codes, there should be a Ruby configuration library that natively controls the whatever-it-is directly! We want configuring Fedora to be fast, straightforward, and reliable.

Conclusion: Stable+fast-update is better than stable+self-built

Practically the whole history of Linux distros has been the conflict between stability and new features. With virtualization, one still must make this choice, but at a much finer granularity than before. If you’re going to re-instance within 6 months anyways, why manually build your latest-Ruby and whatnot to support your app on top of a stable distro image? Maybe just use Fedora for those.

Using qla2xxx with LIO on Fedora

In addition to turning your Fedora 18 box into an iSCSI target, LIO also supports other SCSI transport layers (‘fabrics’), such as Fibre Channel, with the qla2xxx fabric.

The most crucial bit is to verify that the qla2xxx driver has initiator mode disabled — it should be operating in target mode only. You can check this with:

cat /sys/module/qla2xxx/parameters/qlini_mode

It should say ‘disabled’. If it doesn’t, create a file called /usr/lib/modprobe.d/qla2xxx.conf and put:

options qla2xxx qlini_mode=disabled

in it. Then, run ‘dracut -f’ to rebuild your initrd, and reboot.

Some of you may be wondering: why /usr/lib/modprobe.d instead of /etc/modprobe.d ? This is because qla2xxx is likely loaded from the kernel’s initial ramdisk (initrd), and dracut, the initrd building tool, omits “host-specific” settings in /etc/modprobe.d. While you’re mucking around, also make sure the firmware package for your qla device, such as ql2200-firmware or similar, is also installed.

targetcli won’t let you create a qla2xxx fabric if qlini_mode is wrong. Once it lets you create the qla fabric, you can add luns to it and grant access permissions to acls exactly in the same manner as the other LIO fabrics.

tgtd -> LIO kernel target in RHEL 7

RHEL 7 will be using the LIO kernel target subsystem for iSCSI and other protocols, instead of the tgtd daemon, aka scsi-target-utils. This is a change from RHEL 6, where we use tgtd for iSCSI target support, and LIO only for FCoE targets, via the fcoe-target-utils package.

Users of tgtd can prepare for RHEL 7 by trying Fedora 17 or 18, which have current LIO/targetcli code. LIO has many features tgtd doesn’t, but LIO also won’t cover 100% of tgtd’s features at first, either. File bugs for these regressions and we’ll work to address them.

Other software that currently uses tgtd may wish to look at the rtslib Python library, and targetcli’s JSON config format — LIO has a nice API so if you find yourself wanting to parse targetcli output, please hold off and email me instead, ok? ๐Ÿ™‚

scsi-target-utils will still be available via EPEL for RHEL 7, and supported in RHEL 6 for its lifetime.

Plumbing needs an API: “libification”

Here are my slides and video from my talk “All Plumbing needs an API” from Linux Plumbers Conference 2012.

My thesis is we would improve the quality of our platform if we recognize the flaws in excessive use of other commandline tools by other tools, and worked towards more APIs and libraries for low-level parts of the Linux platform. There are many reasons given in the talk I don’t want to rehash; here are some more thoughts since I gave the talk:

First, this is not a push for every single instance of one program being called by another to be replaced by an API. But on the spectrum of cmdline-parsing vs libraries, I think we are too far towards the former, and should make an effort to shift dramatically towards the latter.

Second, we can take a “pave the cowpaths” approach toward this — we should first libify those tools most commonly parsed by other tools. I’ve been helping out on liblvm, a library for LVM (whose tools are unquestionably over-parsed.) There are also many other network, storage, and system configuration tools that are candidates for libification.

The move towards virtualization & cloud computing has led to many tools formerly configured directly by the sysadmin now being configured by other tools. Broadening the coverage of our system-level management APIs will improve Linux’s flexibility and reliability as a virtualized OS.

Screencast: targetd and lsmcli

I’ve whipped up a short (7min) screencast on targetd and lsmcli, two new additions to Fedora 18. targetd glues together LVM and LIO to expose a remote API for configuring a system for a storage array role. lsmcli is part of libstoragemgmt, which provides a common way to manage storage arrays from multiple vendors.

python-kmod will be in Fedora 18

python-kmod is a basic Python wrapper around the kmod library. It allows you to load, unload, and view Linux kernel modules without resorting to the subprocess module.

If you have Python code that works with kernel modules, please consider using this library in the future. If you have C code that works with modules, you should use libkmod directly! As I’ll be talking about at this years LPC, proper libraries are preferable to calling cmdline progams for low-level stuff, and now there’s one less reason to do so.

Using python-kmod, python-rtslib (and thus targetcli and targetd) now work with no use of subprocess, although rtslib will fall back to modprobe via subprocess if python-kmod is not present.

Thanks to Jiri Popelka for reviewing the python-kmod package, sorry it took me so long to fix it up ๐Ÿ™‚

targetd update: 0.2.2

targetd is up to version 0.2.2 from 0.1, just five weeks later.

  • Added manpage
  • Added API specification. API support for multiple storage pools.
  • Deferred completion for long-running operations
  • Volume copy
  • Config file format changed to YAML
  • Saves configuration across reboots
  • Packaged, submitted for inclusion, and accepted for Fedora 18

If you are interested in contributing to targetd, there are two things you could help with. First, now that we have an API specification, please review it and give feedback or submit a bug.

Second, I’m having trouble implementing SSL support. I searched around and found some pages that talked about easily adding SSL support to Python’s HTTPServer, but after spending a day on it, it still didn’t work. I’m sure this is easy for someone, but that someone is not me ๐Ÿ™‚ Anyone care to take a look?