Monday, December 16, 2013

automatic bisection of qemu with console and monitor interaction

I had some fun debugging a performance issue after VM migration on v1.0 [1]. Because this was fixed in newer versions, a bisect was in order. Doing this manually becomes very tedious so writing some scripts to use 'git bisect run' really helps. Here I'll document how I did this in case others find it useful when trying to bisect issues in qemu.

First step is getting the problem reproducible using the command line. In addition you will also need to output anything that be used to determine if the test case passes or fails using standard console output. This makes it easy to run the test case with expect. You will need to follow [2] on how to setup your VM to use serial output.

Next modify the expect script and ensure it works by just running it by itself. Identify which versions pass or fail (a coarse bisect). Once you can get between two release tags you should start a bisect between those tags.

Next run:
git bisect start
git bisect good <good tag>
git bisect bad <bad tag>
git bisect run ../bisect-run

I ran into a few gotchas that may be bugs that really need fixing. Occasionally when running in '-noconsole' mode, I wouldn't see any prompt for a very long time. When re-running with '-vga std', I'd see that it was waiting at GRUB. You may need to modify timeouts such that you don't hit those issues without a VGA console.

Overall, you can find these scripts here [3].

Hopefully they will evolve a bit once its used more and more.
  1. http://pad.lv/1100843
  2. https://help.ubuntu.com/community/SerialConsoleHowto
  3. https://github.com/arges/qemu-bisector

setup an external drives as raid1

I purchased a cheap two drive USB enclosure in order to setup an external drive that had RAID-1 so I could backup photos and recordings.

First, I formatted both drives. Then I ran extended smart self-tests to ensure I had decent drives. With RAID-1 and two drives I can only tolerate 1 drive failure.

Next ensure mdadm is installed.
sudo apt-get install mdadm

Determine which dev devices the disks show up as.
Next, create the raid device pointing at the correct dev directory.
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdx /dev/sdy
sudo mkfs.ext /dev/md0

The device will start a resync process which on my system takes a really long time (days). If you want to avoid this initial re-sync you can use '--assume-clean' to avoid this. I would recommend letting it resync.

And there ya go.

Tuesday, September 10, 2013

use default gpg key for debuild

When using debuild -S to build a package on new machines, I need to go through the process of ensuring that my gpg is set up properly. If set up incorrectly, I get the following message in debuild -S:
gpg: skipped "User <user@host.com>": secret key not available

To fix this, I go through the following steps:

1) Ensure I have proper gpg keys set up. You can check if yours is installed properly using:
gpg --list-keys

2) Add DEBEMAIL and DEBFULLNAME to ~/.bashrc:
Ensure DEBEMAIL matches the email in the matching gpg key, and ensure DEBFULLNAME matches the name in same key. Put these into your ~/.bashrc file or wherever they will be sourced into your environment.

3) Make sure your key is the default key:
Edit ~/.gnupg/gpg.conf such that default-key is set to the proper key. This should match the 8 character fingerprint that you verified in (1).

4) Make sure the same key is the default for debuilder:
Edit /etc/devscripts.conf with the folllowing:
DEBSIGN_KEYID=XXXXXXXX

where XXXXXXX is your key.

5) Now next time you use debuild -S it should use the proper gpg key, name and email address!

Friday, September 6, 2013

fixing a firewire audio interface

I had an issue where my Presonus Firestudio Project would have a red blinking light when I turned it on. This was before I even plugged it into my computer. Determining that it wasn't a software issue, I decided to open the thing up and figure out what's going on. I did the usual and checked for any bulging capacitors, burn marks, or just anything that would give me a clue why this wasn't working. I found some test points on the board labeled with voltages and decided to test them with a DMM. The DMM was reading way below the indicated voltages and they were actually swinging back and forth which led me to conclude that this must be a problem in the power supply board. I took the board out and visually inspected the capacitors and couldn't find one that looked bad. Therefore I ended up just purchasing replacements for all of the capacitors on the power supply board and decided to just replace them and see what happens. After replacing all the capacitors on the board, I carefully plugged in the board and a solid red light came on! Overall, be careful when working with large capacitors like this (There is a 450V one on this board). I made sure they were discharged with a large low ohm resistor to make sure I didn't get a nasty shock. Below is a picture of the board all fixed up!


diy kubb set

After a visit to England, I had the pleasure of playing this awesome game and decided I'd like to play it back home. After a bit of a sticker shock after seeing it on Amazon, I decided that it would be easy enough to build my own set. I enlisted the help of a friend and set out to the hardware store.  I would recommend buying a little bit extra, but overall the materials came to around $18. I recommend having a mitre saw, circular saw, and either a good supply of sandpaper or a floor sander handy. Below is a picture of the final product. To build your own set, just read the directions below and find out what works for you.


References

Thursday, September 5, 2013

building a proper debian source package with dkms



How can one use DKMS to build a proper debian source package? The ‘mkdsc’ command will actually generate one automatically, but there are a few more steps to simplify it, and bring it up to date.

First follow the steps in [1] for setting up a DKMS package. Make sure you can build it using dkms. Then do the following:


#First pull in some dependencies as necessary
sudo apt-get install devscripts debhelper

# Create the debian source package
sudo dkms mkdsc -m hello -v 0.1

# Create a directory to work in, and let’s copy those files into it
mkdir ~/dsc && cd ~/dsc
cp /var/lib/dkms/hello/0.1/dsc/* .

# Extract the .dsc to be able to edit the directory
dpkg-source -x hello-dkms_0.1.dsc 
cd hello-dkms-0.1

If we run debuild -uc -us, we see a few lintian errors and warnings:

W: hello-dkms source: package-file-is-executable debian/changelog
W: hello-dkms source: package-file-is-executable debian/control
W: hello-dkms source: package-file-is-executable debian/copyright
W: hello-dkms source: package-file-is-executable debian/dirs
E: hello-dkms source: no-human-maintainers
W: hello-dkms source: debian-rules-ignores-make-clean-error line 28
W: hello-dkms source: debian-rules-missing-recommended-target build-arch
W: hello-dkms source: debian-rules-missing-recommended-target build-indep
W: hello-dkms source: ancient-standards-version 3.8.1 (current is 3.9.3)
E: hello-dkms: no-copyright-file
E: hello-dkms: extended-description-is-empty
W: hello-dkms: non-standard-dir-perm usr/src/hello-0.1/ 0655 != 0755

The errors are normal, and if this was a real package those will be taken care of since that information will need to be filled in anyway.

To address the executable issues, just chmod -x those files.

chmod -x debian/co* debian/dirs debian/ch*

To address some of the other issues, we can just completely modify and change the rules file. Because debhelper has a helper for DKMS specifically we should use it.

In addition, if we do something like dch -i you’ll notice some errors, since our source directory is hardcoded to hello-0.1. So we can modify it to be in a ‘src’ directory and get around this.

mv hello-0.1 src

Here is how I modified my debian/rules file:

#!/usr/bin/make -f
# -*- makefile -*-

# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

NAME=hello
DEB_NAME=$(NAME)-dkms
VERSION=$(shell dpkg-parsechangelog |grep ^Version:|cut -d ' ' -f 2)

%:
        dh $@ --with dkms

override_dh_install:
        dh_install src/ usr/src/$(NAME)-$(VERSION)
        find "debian/$(DEB_NAME)/usr/src/$(NAME)-$(VERSION)" -type f -exec chmod 644 {} \;

override_dh_dkms:
        dh_dkms -V $(VERSION)

override_dh_auto_build:
override_dh_auto_install:


Now there are some things that can be removed from the package completely:

rm common.postinst Makefile

Now to update the control file to use modern versions, a proper description, and make yourself a maintainer!


Source: hello-dkms
Section: misc
Priority: optional
Maintainer: Dude Bodacious <dude@awesomeradical.com>
Build-Depends: debhelper (>= 8), dkms
Standards-Version: 3.9.3

Package: hello-dkms
Architecture: all
Depends: dkms, ${misc:Depends}
Description: hello driver in DKMS format.
A completely useful kernel module.

Now debuild -uc -us and fix remaining issues.

References

  1. https://wiki.ubuntu.com/Kernel/Dev/DKMSPackaging
  2. https://help.ubuntu.com/community/Kernel/DkmsDriverPackage
  3. http://basilevsthecat.blogspot.com/2011/11/how-to-build-dkms-debian-package.html

Tuesday, July 23, 2013

building a binary debian kernel module package with dkms

DKMS packaging works great for building out of tree kernel modules. However, what do you do when you need to install to a machine without a compiler? You can accompish this by using DKMS's mkdriverdisk functionality.

First follow the steps in [0] for setting up a proper DKMS package.

After you've built the module successfully, you can use the following bash script to extract the .deb installer from the driverdisk. This way you can copy the deb file to the target machine and install. You must ensure that $(uname -rm) on the target machine matches the build machine.

The Script

NAME=hello
VERSION=0.1

# Build in a temp dir
TMPDIR=$(mktemp -d)
cd $TMPDIR
sudo dkms mkdriverdisk $NAME/$VERSION -d ubuntu --media tar | tee build.log
TARBALL_PATH=$(grep "Disk image location" build.log | cut -d':' -f2)
echo $TARBALL_PATH
tar -xf $TARBALL_PATH
cd -

# Extract the build
mv $TMPDIR/ubuntu-drivers/*/*.deb .




References

  1. https://wiki.ubuntu.com/Kernel/Dev/DKMSPackaging

Thursday, July 18, 2013

using git send-email for sending kernel patches

Sending patches to a Linux kernel mailing list can be done easily using git-send-email. This post will help setup your environment and show you how to format the git send-email command. In addition there are some more advanced features that help when you need to send from multiple accounts.

Git Setup

First, install git and git-email. Then, setup ~/.gitconfig for your user and proper sendemail section. This shows a sendemail setup for a typical single gmail account.

[user]  
    name = Your Name
    email = user@gmail.com  
[sendemail]
    from = Your Name <user@gmail.com>
    smtpserver = smtp.gmail.com
    smtpuser = user@gmail.com
    smtpencryption = tls
    smtppass = PASSWORD
    chainreplyto = true
    smtpserverport = 587

However, it may be more useful to be able to easily send from multiple accounts. This can be accomplished using the --identify flag in git.

[user]
    name = Your Name
    email =user@gmail.com
[user "work"]
    email = user@work.com
[user "gmail"]
    email = user@gmail.com
[sendemail "work"]
    from = Your Name <user@work.com>
    smtpserver = smtp.work.com
    smtpuser = me
    smtppass = PASSWORD
    smtpencryption = tls
    smtpserverport = 587
    chainreplyto = false
[sendemail "gmail"]
    from = Your Name <user@gmail.com>
    smtpserver = smtp.gmail.com
    smtpuser = user@gmail.com
    smtppass = PASSWORD
    smtpencryption = tls
    smtpserverport = 587
    chainreplyto = false

This way when you can select your identity to fill in these values. In addition if you specify no identity you can have default fields if necessary. If you added a [sendemail] field this would be called by default. Man git-config can show you more options.

Formatting the Patch

Once we have the patch committed to the HEAD on our branch we format the patch using:

git format-patch -1

This should produce a patch like 0001-blah.patch.
Then check for formatting errors using the checkpatch script provided in the kernel repository:

./scripts/checkpatch.pl 0001-blah.patch

You should read the kernel documentation to get a better idea of what is expected.

Sending A Single Patch

Now we are ready to send a patch. The ./scripts/get_maintainer.pl in the kernel repository provides a way to specify whom needs to be CC'ed based on the maintainers file, the history of the file, and which lines of code are changed.


git send-email --to <ml_list> --cc-cmd="scripts/get_maintainer.pl -i" \
    <0001-patch.patch>

The -i means the script is interactive and you can edit the list before sending. Once you have completed the commands, the patch should be sent!

Pull Requests

If you have your patches in a public git repository, it is sometimes easier to send pull-requests for patches instead of sending.

git request-pull <hash right before your changes> \
    git://<public git repo> > request-pull.txt

Then add a 'Subject: ' line in the request-pull.txt that explains the pull request. Adding --subject doesn't seem to work for me. In additoin add any other tesxt


git send-email --identity=gmail --to=<mailing list> \
    ./request-pull.txt

With this you should have a pull request sent!

References

  1. http://git-scm.com/docs/git-send-email
  2. http://git-scm.com/docs/git-config
  3. https://www.kernel.org/doc/Documentation/SubmittingPatches
  4. http://git-scm.com/docs/gitcredentials.html