For some time, I have been concerned about the amount of data I store on Google. This post aims to show alternatives to the service.
This is primarily for two reasons. The first is simple. I would like to avoid a single point of failure, and the risk that I could be suspended for a number of months with no recourse.
The second if more political. I'm worried about the way that certain governments can subpoena information which they may not be able to collect directly. Now, don't get me wrong. Google is good at transparency. They also provide a very useful service that works incredibly well. In fact, the quality of the integration and services provided is the primary reason I have not changed previously.
Calendaring is something that I naturally feel shouldn't be hard, but somehow is. Google Calendaring service is rather good, and far outstrips anything open source I've found so far. However, I've managed to migrate to Zoho which offers a very similar level of functionality. It's also very easy to extract your entire calendar from Google, which makes the transition easier.
Reader is a service provided to subscribe and read RSS feeds. In the past, I've used Gregarius as a self hosted solution, but this seems to have disappeared recently. I briefly flirted with NetVibes, which works well once you turn off the frustrating 'widget' mode, but has completely failed to address the need to have native tablet apps. In the end, I settled for NewsBlur which also has the clever use of hotkeys for navigation which I found essential in Google's products.
Picasa has stood me well for hosting photos for some time. And photo hosting is something I have quite a large amount of professional experience with :) Despite having previously been in competition with them, I can heartily recommend Flickr, even with it's dogmatic reliance to creating a Yahoo! email address for each account.
Search still has some way to go to find a viable replacement. I've tried DuckDuckGo, but found it lacking. Much like the mistake that Apple seem to have made with the launch of Apple Maps, there seems to be a misunderstanding that search is actually HARD.
So we finally made it, and sent out an
official announcement for
apt.postgresql.org.
This new repository hosts packages for all PostgreSQL server versions (at the
moment 8.3, 8.4, 9.0, 9.1, 9.2) for several Debian/Ubuntu distributions
(squeeze, wheezy, sid, precise) on two architectures (amd64, i386). Now add
packages for extension modules on top of all these, and you get a really large
amount of binaries from a small number of sources. Right now there's 1670 .deb
files and 148 .dsc files, but the .dsc count includes variants that only differ
in the version number per distribution (we attach .pgdg60+1 for squeeze
packages, .pgdg70+1 for wheezy and so on), so the real number of different
sources is rather something like 81, with 38 distinct source package names.
Dimitri Fontaine,
Magnus Hagander, and I have been working
on this since I first presented the idea at PGconf.EU 2011 in Amsterdam. We now
have a Jenkins server building all the packages, an archive server with the
master repository, and a feed that syncs the repository to the postgresql.org
FTP (well, mostly http) server.
If you were previously using pgapt.debian.net, that's the same archive as on
apt.postgresql.org (one rsync away). Please update your sources.list to point
to apt.postgresql.org, I'll shut down the archive at that location at the end
of January.
Here's the Quickstart
instructions from the Wiki page:
Import the repository key from http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc:
wget -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc sudo apt-key add -Edit /etc/apt/sources.list.d/pgdg.list. The distributions are called codename-pgdg. In the example, replace squeeze with the actual distribution you are using:
deb http://apt.postgresql.org/pub/repos/apt/ squeeze-pgdg mainConfigure apt's package pinning to prefer the PGDG packages over the Debian ones in /etc/apt/preferences.d/pgdg.pref:
Package: * Pin: release o=apt.postgresql.org Pin-Priority: 500Note: this will replace all your Debian/Ubuntu packages with available packages from the PGDG repository. If you do not want this, skip this step. Update the package lists, and install the pgdg-keyring package to automatically get repository key updates:
apt-get update apt-get install pgdg-keyring
Not that I'm bored or anything, but I spent some more time on this
since last month, and apparently some people are interested enough, so
here's the recent news about wiigh2midi.
program_changes in the sample
configuration file, and a new rhythmbox-midi script. The goal is
to control a Rhythmbox music player with your Wiimote (or possibly
the attached drumkit).python-cwiid license.https://alioth.debian.org/~lolando/bzr/wiimidi/trunk/. So, to
grab a copy:
Patches welcome, of course! Also, I'll be interested to hear about your applications. I've been told about a Wiimote-powered foot controller, which is exactly the kind of unpredictable results I was hoping to achieve by publishing my code. Keep it up, I want to hear about Wiimote-controlled robot dinosaurs next! Update: Wiimidi now has its dedicated page at Wiimidi.bzr checkout https://alioth.debian.org/~lolando/bzr/wiimidi/trunk/
| Publisher: | HarperTorch |
| Copyright: | July 2001 |
| Printing: | May 2002 |
| ISBN: | 0-380-78903-5 |
| Format: | Mass market |
| Pages: | 588 |
"Back in my day, we had it all set up. You lined up when you died, and you'd answer for your evil deeds and for your good deeds, and if your evil deeds outweighed a feather, we'd feed your soul and your heart to Ammet, the Eater of Souls." "He must have eaten a lot of people." "Not as many as you'd think. It was a really heavy feather. We had it made special. You had to be pretty damn evil to tip the scales on that baby."Like so much of Gaiman's work, this is the sort of book that contributed a half-dozen quotes to my quote file during my first reading. Gaiman always impresses me by not only managing to portray gods as human without losing the numinous edge, but sustaining that portrayal through very extended contact with the same god. And despite the interlude with the undertakers, the long interlude in small-town life in Lakeside, and the numerous other digressions and meanderings of a book that's not in much of a hurry to get anywhere, there is a plot and a definite conclusion, and Gaiman has some interesting twists in store at the end of that road. There's a lot of philosophical currents going on under the surface, not all of which cohere, but Gaiman does pull a lot of them together. The resolution can be a bit of an anticlimax, but I think it's a fitting one that's true to the nature of the story. I didn't enjoy this as much on the second reading as I did on the first. It didn't feel quite as coherent as I'd remembered it, and the meandering pace occasionally made the story feel stretched. But I do like Shadow, I love spending time in Gaiman's head and with his portrayals of deities, and American Gods is a treasure of great quotes. If you enjoy Gaiman's other work and aren't looking for a lot of plot and forward-moving energy, this is definitely recommended. Rating: 7 out of 10
Build-Depends: foo (>=0.1) [amd64] <!stage1 bootstrap> bar.| Attachment | Size |
|---|---|
| debminiconf2012.pdf | 271.56 KB |
qcontrol's
configuration files are actually simple Lua
programs and the state of the GPIO lines can be accessed via sysfs and
so we can read the state directly from the configuration file itself.
While looking into this I happened to notice that the various
board-specific configuration files are actually very similar and that
the differences can all be detected by a combination of the Hardware
field in /proc/cpuinfo and the GPIO lines.
So I started looking into whether I could write a single consolidated
qcontrol.conf file to replace the various variant specific files. It
turns out to be quite possible, the resulting consolidated file has
been posted to the bug
log
(see also my
mail).
The danger with configuration files which are also
fully-fledged programming languages is that there is a temptation to
write more and more complex configuration files with the danger that
the primary purpose of the file (configuration) can be obscured. I
think in this case it is a close call but on balance I think the
downsides outweigh the advantages, so I've uploaded qcontrol
0.4.2+svn-r40-2 which simply adds LCD support to the relevant board
specific configuration file.
In process of doing so I seem to have fallen into a trap which seems
to catch out many sbuild users at least once and uploaded a package
with "UNRELEASED" still in the changelog. To try and save myself (and
others) some blushes in the future I've filed Debian bug #693841
(wishlist) against dput to see if it can catch this case, I've also
added to my prerelease checklist.
As it happens my own TS-419P II arrived today. I intend to use it for
second tier storage (mythtv recordings, music, mirrors) as well as
light server duties (MTA, internal DNS etc) which should allow me to
turn off the existing PC in the cupboard under the stairs which is
getting a bit long in the tooth and starting to become a bit
unreliable (I also suspect its costing a fortune to run).
When someone wants to give you access to a Cisco VPN, they might give you a .mobileconfig file. This is apparently used by MacOS and iOS to encapsulate the configuration parameters needed to connect to a VPN. You should be able to connect to it with open source software (such as NetworkManager and vpnc) as long as you have the right configuration. Some helpful soul has tried to give you that configuration, but it s wrapped up in an Apple-specific container. Here s how you rip it open and get the goodies.
File format
A .mobileconfig appears to contain:
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>IPSec</key>
<dict>
<key>AuthenticationMethod</key>
<string>SharedSecret</string>
<key>LocalIdentifier</key>
<string>LOCAL_IDENTIFIER_HERE</string>
<key>LocalIdentifierType</key>
<string>KeyID</string>
<key>RemoteAddress</key>
<string>REMOTE_ADDRESS_HERE</string>
<key>SharedSecret</key>
<data>
BASE64_ENCODED_SHARED_SECRET_HERE
</data>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>0</integer>
</dict>
<key>PayloadDescription</key>
<string>...</string>
<key>PayloadDisplayName</key>
<string>...</string>
<key>PayloadIdentifier</key>
<string>...</string>
<key>PayloadOrganization</key>
<string>...</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string>...</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>Proxies</key>
<dict>
<key>HTTPEnable</key>
<integer>0</integer>
<key>HTTPSEnable</key>
<integer>0</integer>
<key>ProxyAutoConfigEnable</key>
<integer>0</integer>
<key>ProxyAutoDiscoveryEnable</key>
<integer>0</integer>
</dict>
<key>UserDefinedName</key>
<string>...</string>
<key>VPNType</key>
<string>IPSec</string>
</dict>
</array>
<key>PayloadDescription</key>
<string>...</string>
<key>PayloadDisplayName</key>
<string>...</string>
<key>PayloadIdentifier</key>
<string>...</string>
<key>PayloadOrganization</key>
<string>...</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>...</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
The shared secret is base64-encoded, so you can decode it with:
$ echo -n 'BASE64_ENCODED_SECRET_HERE' base64 -d
Network Manager configuration
| Publisher: | Perennial |
| Copyright: | 2003 |
| Printing: | 2004 |
| ISBN: | 0-06-095485-X |
| Format: | Trade paperback |
| Pages: | 479 |
pyBit - cross-platform package building using AMQP
Since October 2011 my flatmate and I where quite busy realizing a little pet project of ours called The Art of Asking. The ultimate goal is to visualize the world s opinion in an intuitive fashion and make it easy for everyone to play around with the data.
The idea behind The Art of Asking is that users submit interesting questions which are answered by users around the world. But instead of showing only the boring result, we want to provide interesting insights and statistics about the answers given.
For now the users can see the results of the question visualized by geographical regions. For example on the page for the question How are you today? you can see the interactive map with the pie chart. The map shows the average/dominating answer for each continent encoded by color, and the pie chart the distribution of the different answers for that region. If you move the mouse over a continent the pie chart updates and shows the distribution of answers for that continent. You can also click to zoom into the map to see the same for countries and regions. This allows you to investigate how the answers are distributed around the world.
This is already quite nice and fancy to play around with, but of course we want much more. Right now we re working on a feature which will users allow to combine two arbitrary questions and see how the answers are related. This doesn t sound like much, but it is very addictive to crawl through the list of questions and find interesting correlations. Here is a little plot how it could look like (the data is from the actual data base of answers).
For each possible combination of answers it shows the percentage of people who answered in that combination. Of course those plots only make sense when enough users answered for both questions you want to compare which is right now not very often the case, so I guess we ll roll out that feature sometime later when we have more data. But we have lots of ideas and are working on further ways to investigate the answers. Obviously one low hanging fruit for example would be the distribution of the answers over time.
We ve been working for over a year now on this project in our spare time and we built it more or less from scratch. I wrote a small WSGI framework in Python and on top of that the WSGI application which runs the site. We use MongoDB for the storage of the data, uWSGI and nginx for the server, Jinja2 and Bootstrap for the HTML and D3.js for the visualization of the data, where Maci did a wonderful job realizing the interactive map and charts.
We re running this site since July 2012 now and are already quite satisfied with the number of users, and the quality of the questions. But of course we could always use more (especially more answers). So if you want to try it out, go to theartofasking.com and fill out the blank spots on the map! We re happy about every answer and question we can get and are eager to hear your suggestions.
You certainly know Picasa Albums Web and Flickr, two commercial
picture hosting services. You probably know a few free software projects
that allow people to keep control of their own pictures, such as Gallery, Piwigo, Zenphoto or PhotoShow.
GNU MediaGoblin is a
similar project, but with some interesting characteristics and
features:
It's not difficult to write a UEFI application under Linux. You'll need three things:#include <efi.h>
#include <efilib.h>
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
conout = systab->ConOut;
InitializeLib(image, systab);
uefi_call_wrapper(conout->OutputString, 2, conout, L"Hello World!\n\r");
return EFI_SUCCESS;
The includes are fairly obvious. efi.h gives you UEFI functions defined by the specification, and efilib.h gives you functions provided by gnu-efi. The runtime will call efi_main() rather than main(), so that's our main function. It returns an EFI_STATUS which will in turn be returned to whatever executed the binary. The EFI_HANDLE image is a pointer to the firmware's context for this application, which is used in certain calls. The EFI_SYSTEM_TABLE *systab is a pointer to the UEFI system table, which in turn points to various other tables.typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
EFI_TEXT_RESET Reset;
EFI_TEXT_STRING OutputString;
EFI_TEXT_TEST_STRING TestString;
EFI_TEXT_QUERY_MODE QueryMode;
EFI_TEXT_SET_MODE SetMode;
EFI_TEXT_SET_ATTRIBUTE SetAttribute;
EFI_TEXT_CLEAR_SCREEN ClearScreen;
EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition;
EFI_TEXT_ENABLE_CURSOR EnableCursor;
SIMPLE_TEXT_OUTPUT_MODE *Mode;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
The majority of these are functions - the only exception is the SIMPLE_TEXT_OUTPUT_MODE pointer, which points to the current mode. In an ideal world you'd be able to just call these directly, but sadly UEFI and Linux calling conventions are different and we need some thunking. That's where the uefi_call_function() call comes in. This takes a UEFI function as its first argument (in this case, conout->OutputString), the number of arguments (2, in this case) and then the arguments. Checking the spec for OutputString, we see this:typedef
EFI_STATUS
(EFIAPI *EFI_TEXT_STRING) (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *String
);The first argument is a pointer to the specific instance of the simple text output protocol. This permits multiple instances of the same protocol to exist on a single machine, without having to duplicate all of the code. The second argument is simply a UCS-2 string. Our conout pointer is a pointer to the protocol, so we pass that as the first argument. For the second argument, we pass L"Hello World!\n", with the L indicating that this is a wide string rather than a simple 8-bit string. uefi_call_function() then rearranges these arguments into the appropriate calling convention and calls the UEFI function. The firmware then prints "Hello World!" on the screen. Success.#include <efi.h>
#include <efilib.h>
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
EFI_LOADED_IMAGE *loaded_image = NULL;
EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL;
EFI_STATUS status;
InitializeLib(image, systab);
status = uefi_call_wrapper(systab->BootServices->HandleProtocol,
3,
image,
&loaded_image_protocol,
(void **) &loaded_image);
if (EFI_ERROR(status))
Print(L"handleprotocol: %r\n", status);
Print(L"Image base : %lx\n", loaded_image->ImageBase);
Print(L"Image size : %lx\n", loaded_image->ImageSize);
Print(L"Image file : %s\n", DevicePathToStr(loaded_image->FilePath));
return EFI_SUCCESS;
UEFI handles can have multiple protocols attached to them. A handle may represent a piece of physical hardware, or (as in this case) it can represent a software object. In this case we're going to get a pointer to the loaded image protocol that's associated with the binary we're running. To do this we call the HandleProtocol() function from the Boot Services table. Boot services are documented in section 6 of the UEFI specification and are the interface to the majority of UEFI functionality. HandleProtocol takes an image and a protocol identifier, and hands back a pointer to the protocol. UEFI protocol identifiers are all GUIDs and defined in the specification. If you call HandleProtocol on a handle that doesn't implement the protocol you request, you'll simply get an error back in the status argument. No big deal.#include <efi.h>
#include <efilib.h>
EFI_STATUS
efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
EFI_STATUS status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
InitializeLib(image_handle, systab);
status = uefi_call_wrapper(systab->BootServices->LocateProtocol,
3,
&gop_guid,
NULL,
&gop);
Print(L"Framebuffer base is at %lx\n", gop->Mode->FrameBufferBase);
return EFI_SUCCESS;
This will find the first (where first is an arbitrary platform ordering) instance of a protocol and return a pointer to it. If there may be multiple instances of a protocol (as there often are with the graphics output protocol) you should use LocateHandleBuffer() instead. This returns an array of handles that implement the protocol you asked for - you can then use HandleProtocol() to give you the instance on the specific handle. There's various helpers in gnu-efi like LibLocateHandle() that make these boilerplate tasks easier. You can find the full list in /usr/include/efi/efilib.h. ARCH = $(shell uname -m sed s,i[3456789]86,ia32,)
LIB_PATH = /usr/lib64
EFI_INCLUDE = /usr/include/efi
EFI_INCLUDES = -nostdinc -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
EFI_PATH = /usr/lib64/gnuefi
EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o
EFI_LDS = $(EFI_PATH)/elf_$(ARCH)_efi.lds
CFLAGS = -fno-stack-protector -fpic -fshort-wchar -mno-red-zone $(EFI_INCLUDES)
ifeq ($(ARCH),x86_64)
CFLAGS += -DEFI_FUNCTION_WRAPPER
endif
LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) \
$(EFI_CRT_OBJS) -lefi -lgnuefi
TARGET = test.efi
OBJS = test.o
SOURCES = test.c
all: $(TARGET)
test.so: $(OBJS)
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
%.efi: %.so
objcopy -j .text -j .sdata -j .data \
-j .dynamic -j .dynsym -j .rel \
-j .rela -j .reloc -j .eh_frame \
--target=efi-app-$(ARCH) $^ $@There's rather a lot going on here, but the important stuff is the CFLAGS line and everything after that. First, we need to disable the stack protection code - there's nothing in the EFI runtime for it to call into, so we'll build a binary with unresolved symbols otherwise. Second, we need to build position independent code, since UEFI may relocate us anywhere. short-wchar is needed to indicate that strings like L"Hi!" should be 16 bits per character, rather than gcc's default of 32 bits per character. no-red-zone tells the compiler not to assume that there's 256 bytes of stack available to it. Without this, the firmware may modify stack that the binary was depending on.
Inspired by this clock, which made the rounds a few weeks back, and fueled by a bet to see who could make it first (hi Fabs!), ladies and gentleman, I m honored to introduce to you, the Silly Wal(l Cloc)k:
This is a prototype version, done without any fancy precision tools and whatnot, so you can easily see that it s not the most high quality product you ll ever get your hands on. If anyone wants to reproduce this at home, here s how it was done:
First get a hold of some cheap wall clock like this one:
Some things to think about when buying this beauty *cough*:
As a base image I used this and traced it to produce this SVG with the legs in different layers and a marker for the holes. For this prototype, it would probably have been ok to use the original photo directly, but having the vector version ready means it s easy to use a 3d printer and laser-cutter to make the next version of the hands and face, which will definitely look and behave a lot better.
Next step is printing the three layers body and two legs. Since this specific clock is wider than an A4 sheet, I had to use some white cardboard as background (the clock s own box hurray for resourcefulness) and painstakingly cut the printed body s outline, to avoid the slight tone difference between cardboard and paper. If you use the provided SVG and a laser-cutter, you d hopefully avoid this sort of issue.
I didn t have any black cardboard lying around, so I had to print the legs, cut the outline again and strengthen them with some thin cardboard from tea boxes (taken directly from the trash hurray for resourcefulness again). Again something that 3d printing will hopefully side-step. It s important to use light materials for the legs, since most clock mechanisms don t have enough force to move heavy hands, which would cause the clock to quickly loose precision.
Depending on the width of the clock s axis, a paper hole puncher might be the ideal tool to make holes in the legs. Since the prototype was largely made with paper, there was no point in going for precision when making the holes, as there s no way to fit the legs tightly to the clock s axis. For this, the original hands were cut in length and used as a base on which to super-glue the legs, so the original holes could be used.
After these few easy steps, it s only a matter of reassembling the clock and voil !
| Attachment | Size |
|---|---|
| PA250002.JPG | 134.19 KB |
| PA250003.JPG | 131.11 KB |
To experiment with network stuff, I was using
UML-based network labs. Many alternatives exist, like
GNS3, Netkit, Marionnet or Cloonix. All of them are
great viable solutions but I still prefer to stick to my minimal
home-made solution with UML virtual machines. Here is why:
make defconfig,
removed everything that was not necessary, added what I needed for my
lab (mostly network stuff) and added the appropriate options for VirtIO drivers:
CONFIG_NET_9P_VIRTIO=y CONFIG_VIRTIO_BLK=y CONFIG_VIRTIO_NET=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM_VIRTIO=y CONFIG_VIRTIO=y CONFIG_VIRTIO_RING=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y
$LINUX is the appropriate bzImage):
kvm \ -m 256m \ -display none \ -nodefconfig -no-user-config -nodefaults \ \ -chardev stdio,id=charserial0,signal=off \ -device isa-serial,chardev=charserial0,id=serial0 \ \ -chardev socket,id=con0,path=$TMP/vm-$name-console.pipe,server,nowait \ -mon chardev=con0,mode=readline,default \ \ -kernel $LINUX \ -append "init=/bin/sh console=ttyS0"
-display none). A serial port is defined and
uses stdio as a backend1. The kernel is configured to use
this serial port as a console (console=ttyS0). A VirtIO console
could have been used instead but it seems this is not possible to make
it work early in the boot process.
The KVM monitor is setup to listen on an Unix socket. It is possible
to connect to it with socat UNIX:$TMP/vm-$name-console.pipe -.
/dev/root as the mount tag to solve this problem. I keep using an
initrd in this post but the lab on Github has been updated
to not use one.
Here is how to build a small initial ramdisk:
# Setup initrd setup_initrd() info "Build initrd" DESTDIR=$TMP/initrd mkdir -p $DESTDIR # Setup busybox copy_exec $($WHICH busybox) /bin/busybox for applet in $($ DESTDIR /bin/busybox --list); do ln -s busybox $ DESTDIR /bin/$ applet done # Setup init cp $PROGNAME $ DESTDIR /init cd "$ DESTDIR " && find . \ cpio --quiet -R 0:0 -o -H newc \ gzip > $TMP/initrd.gz
copy_exec function is stolen from the initramfs-tools package
in Debian. It will ensure that the appropriate libraries are also
copied. Another solution would have been to use a static busybox.
The setup script is copied as /init in the initial ramdisk. It will
detect it has been invoked as such. If it was omitted, a shell would
be spawned instead. Remove the cp call if you want to experiment manually.
The flag -initrd allows KVM to use this initial ramdisk.
kvm \ $ PREVIOUS_ARGS \ -fsdev local,security_model=passthrough,id=fsdev-root,path=$ ROOT ,readonly \ -device virtio-9p-pci,id=fs-root,fsdev=fsdev-root,mount_tag=rootshare
$ ROOT can either be / or any directory containing a complete
filesystem. Mounting it from the guest is quite easy:
mkdir -p /target/ro mount -t 9p rootshare /target/ro -o trans=virtio,version=9p2000.u
/target/ro. I have
used version=9p2000.u instead of version=9p2000.L because the
later does not allow a program to mount() a host mount
point2.
Now, you have a read-only root filesystem (because you don t want to
mess with your existing root filesystem and moreover, you did not run
this lab as root, did you?). Let s use an union filesystem. Debian
comes with AUFS while Ubuntu and OpenWRT have migrated to
overlayfs. I was previously using AUFS but got errors on some
specific cases. It is still not clear
which one will end up in the kernel. So, let s try
overlayfs.
I didn t find any patchset ready to be applied on top of my kernel
tree. I was working with David Miller s net-next tree. Here
is how I have applied the overlayfs patch on top of it:
$ git remote add torvalds git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git $ git fetch torvalds $ git remote add overlayfs git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git $ git fetch overlayfs $ git merge-base overlayfs.v15 v3.6 4cbe5a555fa58a79b6ecbb6c531b8bab0650778d $ git checkout -b net-next+overlayfs $ git cherry-pick 4cbe5a555fa58a79b6ecbb6c531b8bab0650778d..overlayfs.v15
CONFIG_OVERLAYFS_FS in .config. Here is how
I configured the whole root filesystem:
info "Setup overlayfs" mkdir /target mkdir /target/ro mkdir /target/rw mkdir /target/overlay # Version 9p2000.u allows to access /dev, /sys and mount new # partitions over them. This is not the case for 9p2000.L. mount -t 9p rootshare /target/ro -o trans=virtio,version=9p2000.u mount -t tmpfs tmpfs /target/rw -o rw mount -t overlayfs overlayfs /target/overlay -o lowerdir=/target/ro,upperdir=/target/rw mount -n -t proc proc /target/overlay/proc mount -n -t sysfs sys /target/overlay/sys info "Mount home directory on /root" mount -t 9p homeshare /target/overlay/root -o trans=virtio,version=9p2000.L,access=0,rw info "Mount lab directory on /lab" mkdir /target/overlay/lab mount -t 9p labshare /target/overlay/lab -o trans=virtio,version=9p2000.L,access=0,rw info "Chroot" export STATE=1 cp "$PROGNAME" /target/overlay exec chroot /target/overlay "$PROGNAME"
$ HOME and the lab directory from host:
kvm \ $ PREVIOUS_ARGS \ -fsdev local,security_model=passthrough,id=fsdev-root,path=$ ROOT ,readonly \ -device virtio-9p-pci,id=fs-root,fsdev=fsdev-root,mount_tag=rootshare \ -fsdev local,security_model=none,id=fsdev-home,path=$ HOME \ -device virtio-9p-pci,id=fs-home,fsdev=fsdev-home,mount_tag=homeshare \ -fsdev local,security_model=none,id=fsdev-lab,path=$(dirname "$PROGNAME") \ -device virtio-9p-pci,id=fs-lab,fsdev=fsdev-lab,mount_tag=labshare
# Setup a VDE switch setup_switch() info "Setup switch $1" screen -t "sw-$1" \ start-stop-daemon --make-pidfile --pidfile "$TMP/switch-$1.pid" \ --start --startas $($WHICH vde_switch) -- \ --sock "$TMP/switch-$1.sock" screen -X select 0
mac=$(echo $name-$net sha1sum \ awk ' print "52:54:" substr($1,0,2) ":" substr($1, 2, 2) ":" substr($1, 4, 2) ":" substr($1, 6, 2) ') kvm \ $ PREVIOUS_ARGS \ -net nic,model=virtio,macaddr=$mac,vlan=$net \ -net vde,sock=$TMP/switch-$net.sock,vlan=$net
-net user flag or using slirpvde on a special switch. I
prefer the latest solution since it will allow the VM to speak to each others.
kvm \ $ PREVIOUS_ARGS \ -gdb unix:$TMP/vm-$name-gdb.pipe,server,nowait
vmlinux file at the root of the source tree and run GDB on it. The
kernel has to be compiled with CONFIG_DEBUG_INFO=y to get the
appropriate debugging symbols. Then, use socat with the Unix socket
to attach to the remote debugger:
$ gdb vmlinux GNU gdb (GDB) 7.4.1-debian Reading symbols from /home/bernat/src/linux/vmlinux...done. (gdb) target remote socat UNIX:$TMP/vm-$name-gdb.pipe - Remote debugging using socat UNIX:/tmp/tmp.W36qWnrCEj/vm-r1-gdb.pipe - native_safe_halt () at /home/bernat/src/linux/arch/x86/include/asm/irqflags.h:50 50 (gdb)
net/ipv6/route.c, just add
CFLAGS_route.o = -O0 to net/ipv6/Makefile, remove
net/ipv6/route.o and type make.
gdb as usual. Your
$HOME directory is available and it should be therefore
straightforward. However, if you want to perform some remote
debugging, that s quite easy. Add a new serial port to KVM:
kvm \ $ PREVIOUS_ARGS \ -chardev socket,id=charserial1,path=$TMP/vm-$name-serial.pipe,server,nowait \ -device isa-serial,chardev=charserial1,id=serial1
gdbserver in the guest:
$ libtool execute gdbserver /dev/ttyS1 zebra/zebra Process /root/code/orange/quagga/build/zebra/.libs/lt-zebra created; pid = 800 Remote debugging using /dev/ttyS1
$ libtool execute gdb zebra/zebra GNU gdb (GDB) 7.4.1-debian Reading symbols from /home/bernat/code/orange/quagga/build/zebra/.libs/lt-zebra...done. (gdb) target remote socat UNIX:/tmp/tmp.W36qWnrCEj/vm-r1-serial.pipe Remote debugging using socat UNIX:/tmp/tmp.W36qWnrCEj/vm-r1-serial.pipe Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 0x00007ffff7dddaf0 in ?? () from /lib64/ld-linux-x86-64.so.2 (gdb)
Next.