RecentChanges

Recent changes to this wiki:

no message given
=== modified file 'posts/evolution-mail-send-undo.mdwn'
--- posts/evolution-mail-send-undo.mdwn 2010-08-26 07:15:51 +0000
+++ posts/evolution-mail-send-undo.mdwn 2010-08-26 07:26:13 +0000
@@ -17,3 +17,5 @@
 control-enter instead...
 
 Undoing sending an e-mail would allow you to recover from that.
+
+Edit: <https://bugzilla.gnome.org/show_bug.cgi?id=628007>


no message given
=== added file 'posts/evolution-mail-send-undo.mdwn'
--- posts/evolution-mail-send-undo.mdwn 1970-01-01 00:00:00 +0000
+++ posts/evolution-mail-send-undo.mdwn 2010-08-26 07:15:51 +0000
@@ -0,0 +1,19 @@
+[[!meta title="Undo for mail sending in Evolution"]]
+[[!tag idea]]
+
+I've just heard that Gmail has undo for sending e-mail.
+The way it works is that it delays sending the e-mail by,
+say, a minute, and during that time you can cancel the sending.
+
+This would totally rock in Evolution.
+You see, Evolution has two key combinations that are unfortunate
+in their proximity: control-backspace deletes a word, and
+control-enter sends the e-mail.
+
+Anyone who has written e-mail while angry knows the feeling
+of deleting words furiously.
+Consider what will happen if you're deleting an angry,
+half-written flame with control-backspace, and press
+control-enter instead...
+
+Undoing sending an e-mail would allow you to recover from that.


no message given
=== added file 'posts/cut-point.mdwn'
--- posts/cut-point.mdwn        1970-01-01 00:00:00 +0000
+++ posts/cut-point.mdwn        2010-08-12 17:22:46 +0000
@@ -0,0 +1,45 @@
+[[!meta title="Debian CUT"]]
+[[!tag debian]]
+
+[Joey Hess](http://kitenet.net/~joey/) had a BOF about
+[Constantly Usable Testing](http://penta.debconf.org/dc10_schedule/events/681.en.html) at [Debconf10](http://debconf10.debconf.org/)
+last week. I like the idea a lot, and here's why: I run Debian's
+testing distribution on my laptop. I like it to be reasonably up to 
+date with current upstream versions (if only because the lenny versions
+often don't work with the hardware), but I don't want to take
+the risk of breakage I get from running Debian unstable.
+
+In fact, I don't want to the take the risk of breakage I get with
+running Debian testing, either. CUT seems to me to be an opportunity
+to get the benefits of running testing without most of its risks.
+
+Now, the breakage I'm concerned with isn't the kind of breakage
+that makes the machine as a whole unusable. I am more worried about
+the kinds of small changes that will inevitably happen that I can
+work around, but that require more time and effort I like to spend.
+
+For example, it might be that when upgrading this morning, something
+changes in Firefox, which requires me to restart that. Or there's a
+new kernel that requires a reboot. Or the update breaks Evolution,
+and I'll need to wait for a fix from unstable for a week, or have
+to backport it myself, perhaps by installing the relevant half-dozen
+packages directly from unstable.
+
+None of that is a disaster, but it's all a hassle, and it's all
+a distraction from what I really want to do.
+
+Having resonably frequent pseudo-releases, cuts, based on testing,
+would mean I only need to worry about things breaking when I upgrade
+to the next cut release. Meanwhile, I will have months of stress-free
+Debian use.
+
+I could almost achieve that by only uprading my laptop every few
+months to whatever happens to be current in testing at that time.
+However, there's no security support in that case. The big, central,
+blinking improvement with cut releases (if I understand them
+correctly) is that I would have security updates if I stay within
+the cut release. The security update would possibly just require
+installing the relevant packages and their updated dependencies,
+but that's good enough.
+
+And that's why I like cut, at least as an idea.


no message given
=== modified file 'posts/debconf10.mdwn'
--- posts/debconf10.mdwn        2010-08-08 00:39:07 +0000
+++ posts/debconf10.mdwn        2010-08-08 00:47:35 +0000
@@ -8,7 +8,7 @@
   Franklin Street Statement -free as well.
 * [Freedom Box](http://wiki.debian.org/FreedomBox).
 * Meeting old friends, and some new people as well. Putting faces and names together.
-* [[My_own_talk|swimming-upstream]], of course.
+* [My own talk](http://liw.fi/swimming-upstream/), of course.
 * [Helicopter ride](http://soap.docstory.fi/posts/top/).
 
-Oh yeah, and I decided to re-join Debian, and a kilt.
+Oh yeah, and I decided to re-join Debian, and get a kilt.


no message given
=== added file 'posts/debconf10.mdwn'
--- posts/debconf10.mdwn        1970-01-01 00:00:00 +0000
+++ posts/debconf10.mdwn        2010-08-08 00:39:07 +0000
@@ -0,0 +1,14 @@
+[[!meta title="Debconf10"]]
+[[!tag debian debconf10]]
+
+Some of my personal highlights from Debconf10:
+
+* [Branchable](http://www.branchable.com/). It happened during and at Debconf10, even
+  if it is not directly related to Debian. All free software, though, all the way, and
+  Franklin Street Statement -free as well.
+* [Freedom Box](http://wiki.debian.org/FreedomBox).
+* Meeting old friends, and some new people as well. Putting faces and names together.
+* [[My_own_talk|swimming-upstream]], of course.
+* [Helicopter ride](http://soap.docstory.fi/posts/top/).
+
+Oh yeah, and I decided to re-join Debian, and a kilt.


no message given
=== added file 'posts/re-join-debian.mdwn'
--- posts/re-join-debian.mdwn   1970-01-01 00:00:00 +0000
+++ posts/re-join-debian.mdwn   2010-08-06 16:57:37 +0000
@@ -0,0 +1,28 @@
+[[!meta title="Should I re-join Debian?"]]
+[[!tag debian debconf10]]
+
+I've spent the past couple of weeks at Debconf10.
+As usual, Debconf has a huge motivational effect on me,
+and I am excited about doing all sorts of things for the project.
+
+I'm still not all that interested in doing distribution 
+development, which is why I retired last year. However, there's
+the [Freedom Box](http://wiki.debian.org/FreedomBox) project
+starting, which is distribution development, and I'm quite
+excited about it, but on the whole, I don't want to fix
+other people's bugs, I want to make my own.
+
+Should I re-join Debian? If I do, what would I do?
+
+I could develop tools for Debian to use. That doesn't
+technically require being a DD, but if I'm doing work for the project,
+I want voting rights.
+
+I could perhaps do some work on piuparts.
+Or write various small tools that other people would find
+useful, and would make their own development go smoother.
+
+(Ideally, I would find people willing to pay me to do that,
+but I have no idea how to find such people.)
+
+And lest I forget, Debian is my tribe.


no message given
=== added file 'posts/branchable-soft-launch.mdwn'
--- posts/branchable-soft-launch.mdwn   1970-01-01 00:00:00 +0000
+++ posts/branchable-soft-launch.mdwn   2010-08-05 21:15:31 +0000
@@ -0,0 +1,36 @@
+[[!meta title="Branchable"]]
+[[!tag branchable]]
+
+[Joey Hess](http://kitenet.net/~joey/) wrote 
+[Ikiwiki](http://ikiwiki.info/),
+a wiki engine that I really like:
+it generates static HTML pages whenever possible,
+and uses a real version control system for keeping track of changes.
+I have used Ikiwiki for some years now,
+for my web sites and blogs.
+It is an extremely versatile tool.
+
+Ikiwiki is not hard to use, but like any service, it requires a bit of
+attention and effort and skill to set up and keep running.
+
+Joey and I have set up a hosting service for Ikiwiki.
+We call it **[Branchable](http://www.branchable.com/)**.
+Branchable makes having an Ikiwiki site easy.
+
+We take **freedom** seriously.
+Branchable gives you access to the version control system
+(git by default) underlying your wiki.
+You can easily switch to another provider,
+and you can branch any other wiki on Branchable that allows it.
+**We will not take away your freedom to make more money.**
+
+We are now opening it up for a beta period.
+During the beta, we will offer
+[free accounts to free software 
+projects](http://www.branchable.com/news/free_hosting_for_Free_Software/):
+any project that signs up during the beta
+will have a free account after the beta as well.
+
+See also what [Joey 
+writes](http://kitenet.net/~joey/blog/entry/announcing_Branchable/)
+about this.


no message given
=== added file 'tag/branchable.mdwn'
--- tag/branchable.mdwn 1970-01-01 00:00:00 +0000
+++ tag/branchable.mdwn 2010-08-05 21:12:17 +0000
@@ -0,0 +1,4 @@
+This tag is for blog posts about 
+[Branchable](http://www.branchable.com/).
+
+[[inline archive=yes pages="link(tag/branchable)"]]


no message given
=== added file 'posts/dream-job.mdwn'
--- posts/dream-job.mdwn        1970-01-01 00:00:00 +0000
+++ posts/dream-job.mdwn        2010-07-26 16:57:38 +0000
@@ -0,0 +1,99 @@
+[[!meta title="Keyboard for hire"]]
+[[!tag personal]]
+
+I've been happily unemployed for a while now. I went to New Zealand
+with my significant other, and we've been there for some months. 
+Soon we'll be moving somewhere else. 
+I've hacked a lot on [Obnam](http://braawi.org/obnam/),
+my backup application. I've taken some photographs.
+I've generally enjoyed life.
+
+It's getting time to start thinking about making some money again.
+To kick that off, I wrote down some ideas on my dream job. They are
+a fantasy, of course&mdash;I don't expect to find anything that
+gives me everything in the list&mdash;but it's good to know what the fantasy
+is, so I can compare possible jobs against it.
+
+My dream job
+------------
+
+My dream job is to develop free software I use myself, either alone,
+or with co-workers with a good attitude towards work, 
+or as part of a true community project (one
+where the direction of the project is not decided based on corporate
+interests).
+
+I want to have some freedom in choosing each project, within the
+constraints of doing business.
+
+I want to have a significant part in the project, and not be just another 
+cog in the wheel. I need to be able to do large, sweeping changes to any 
+part of the project, or its architecture. This may mean I should be on
+the project from the beginning, though the project may be part of a
+large one where I have less influence.
+
+The project should be developed, from the start, using tools, technologies 
+and processes that I like and am conviced work well, for example, 
+using sensible languages,  TDD, high test coverage, and DVCS. 
+
+At least one of schedule or scope should be flexible. There should be 
+room in the schedule to occasionally stop and step back and look at 
+the bigger picture, or to go out on a walk to think deep thoughts about 
+what is going on.
+
+The work should be challenging, and should teach me new things. It should
+let me build on existing knowledge and experience.
+
+The job would involve me in just one project at a time. Multitasking
+between projects is so much less productive than concentrating on
+one project that it frustrates me to switch frequently.
+
+Projects should be shortish, up to a few months. 
+Larger projects should be broken down into shorter ones.
+
+Work should be done at home, or in a quiet office with private
+rooms, or rooms for small teams.
+
+There should be no NDAs, all development should be in public, and
+no copyright assignments should be required.
+
+The employer should not use software patents at all.
+
+Management should concentrate on providing a good working environment,
+and sufficient resources to do good work, and should not try to
+micro-manage me or my team.
+
+I should be compensated reasonably well. I should have at least five
+weeks of vacation per year. If work requires me to be away from home
+during weekends, or travel on weekends, those days should count as
+work and be compensated in some way.
+
+I would like my employer to send me to one or two interesting 
+conferences each year, perhaps even to give presentations about my
+work. One of the conferences should be Debconf, the yearly Debian
+conference.
+
+I must be able to other things in my free time, at least if they don't
+directly compete with what the employer has me do at work. This includes
+being a Debian developer, if I choose to do so.
+
+
+Ways of earning money
+---------------------
+
+The other thing I've been thinking about is ways of earning money.
+Here's a brief list:
+
+* Get a traditional job.
+* Do consulting jobs. I am bad at finding them, though. Some such jobs
+  would be interesting, others not so much. Perhaps the ideal form of
+  this would be to have a few companies hire me to do things like
+  piuparts development, or other tool development for Debian or Ubuntu.
+* Sell free software development in small units. For example, if there were
+  a lot of people interested in Obnam, they could buy an hour's or day's
+  worth of development at a time. This would let me work on things I'm
+  most interested in, as long as they're popular.
+* Set up an online service of some kind to generate revenue. Ads are
+  passé, so it'd probably have to be a subscription based service.
+
+There's more things, but those are at the top of my list right now.


no message given
=== added file 'posts/obnam-0.13.mdwn'
--- posts/obnam-0.13.mdwn       1970-01-01 00:00:00 +0000
+++ posts/obnam-0.13.mdwn       2010-07-12 22:14:26 +0000
@@ -0,0 +1,19 @@
+[[!meta title="Obnam version 0.13"]]
+[[!tag obnam btree]]
+
+I just pushed out release 0.13 of [Obnam](http://braawi.org/obnam/), 
+my backup utility, 
+and 0.13 of the [Python btree library](http://liw.fi/btree/)
+it uses.
+
+* Bug fix: a mistake in 0.12 caused checkpoints to happen after each
+  file after the first checkpoint. Now they happen at the right intervals
+  again.
+* Upload speed is now displayed during backups.
+* Obnam now tells the kernel that it shouldn't cache data it reads or
+  writes. It is not likely that data being backed up is going to be
+  needed again any time soon, so there's no point in caching it.
+  (The posix_fadvise call is used for this.)
+* New --lru-size option sets size of LRU cache for nodes in memory.
+  The obnam default is large enough to suit large backups. This uses more
+  memory, but is faster than btree's small default of 100.


no message given
=== added file 'posts/obnam-and-btree-0.12.mdwn'
--- posts/obnam-and-btree-0.12.mdwn     1970-01-01 00:00:00 +0000
+++ posts/obnam-and-btree-0.12.mdwn     2010-07-11 08:15:23 +0000
@@ -0,0 +1,22 @@
+[[!meta title="Obnam and btree versions 0.12"]]
+[[!tag obnam btree]]
+
+I've just published version 0.12 of 
+[Obnam](http://braawi.org/obnam/), my backup program, and 0.12 of 
+[btree](http://liw.fi/btree/), the B-tree implementation it uses. 
+Then I published obnam 0.12.1 on i386, to fix a problem with the
+Debian packages that did not affect my amd64 build.
+
+From the Obnam NEWS file:
+
+* NOTE: This version makes incompatible changes to the way data is stored
+  on-disk. Backups made with older versions are NOT supported. Sorry.
+* The run-benchmark script has dropped some smaller sizes (they're too
+  fast to be interesting), and adds a 10 GiB test size.
+* Various speed optimizations. Most importantly, the way file metadata
+  (results of lstat(2)) are encoded has changed. This is the incompatible
+  change from above. It's much faster now, though.
+* Preliminary support for using SFTP for the backup store added. Hasn't
+  been used much yet, so might well be very buggy.
+
+Btree has had a bit of speed optimization too.


added tag
=== added file 'tag/irony.mdwn'
--- tag/irony.mdwn      1970-01-01 00:00:00 +0000
+++ tag/irony.mdwn      2010-07-09 21:56:38 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts that are intended as ironic.
+
+[[inline archive=yes pages="link(tag/irony)"]]


no message given
=== added file 'posts/kd-tulee-lopettaa.mdwn'
--- posts/kd-tulee-lopettaa.mdwn        1970-01-01 00:00:00 +0000
+++ posts/kd-tulee-lopettaa.mdwn        2010-07-09 21:53:01 +0000
@@ -0,0 +1,14 @@
+[[!meta title="KD:n Maanselkä: pienpuolueiden toiminta lopetettava"]]
+[[!tag in-finnish finnish-politics irony]]
+
+Kristillisdemokraattisen puolueen viestintäjohtaja,
+Asmo Maanselkä, haluaa, että **pienpuolueet lopettavat toimintansa**. Hän esittää tätä [mielipidekirjoituksessa Keskisuomalainen-lehdessä](http://www.ksml.fi/mielipide/mielipidekirjoitukset/pride-paraati-on-my%C3%B6s-provokaatio/579061):
+
+> [m]arginaalin tulisi kunnioittaa enemmistön arvoja ja pitäisi ymmärtää 
+> jättää suomalainen valtakulttuuri rauhaan.
+
+Hyvin pieni osa suomalaisista on KD:n jäsen tai äänestää heitä, joten KD on katsottava
+marginaalipuolueeksi ja sen tulisi, Maanselän mukaan, lopettaa tomintansa.
+
+Sama pätee tietysti kaikkia pienpuolueita, mutta hyvänä ihmisenä Maanselkä haluaa
+toki ensin puhdistaa oman pesänsä, ennen kuin rupeaa vaatimaan muilta mitään.


Added a comment: i386 binary .deb
=== added directory 'posts/obnam-and-btree-0.11'
=== added file 'posts/obnam-and-btree-0.11/comment_1_0de9856f5acd668f574ef6df2f4549bc._comment'
--- posts/obnam-and-btree-0.11/comment_1_0de9856f5acd668f574ef6df2f4549bc._comment      1970-01-01 00:00:00 +0000
+++ posts/obnam-and-btree-0.11/comment_1_0de9856f5acd668f574ef6df2f4549bc._comment      2010-07-05 06:25:37 +0000
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="i386 binary .deb"
+ date="2010-07-05T06:25:37Z"
+ content="""
+It's now on code.liw.fi.
+"""]]


no message given
=== added file 'posts/obnam-and-btree-0.11.mdwn'
--- posts/obnam-and-btree-0.11.mdwn     1970-01-01 00:00:00 +0000
+++ posts/obnam-and-btree-0.11.mdwn     2010-07-05 05:50:01 +0000
@@ -0,0 +1,11 @@
+[[!meta title="Obnam version 0.11, btree version 0.11"]]
+[[!tag obnam btree]]
+
+I've just uploaded the new version 0.11 of my backup program
+Obnam version 0.11, and the new version 0.11 of my B-tree implementation
+as well, which Obnam requires.
+See <http://braawi.org/obnam/> and 
+<http://liw.fi/btree/> for more info on the two.
+
+My personal apt archive has amd64 packages; I am working on getting
+i386 packages out as well.


no message given
=== modified file 'index.mdwn'
--- index.mdwn  2010-07-01 05:23:29 +0000
+++ index.mdwn  2010-07-03 05:07:47 +0000
@@ -1,5 +1,6 @@
-[[img liw-by-soile-madrid.jpg alt="Photo by Soile Mottisenkangas"
-      class="floatTR" link="no"]]
+<img src="http://files.liw.fi/lars_ja_orava.jpg"
+     alt="Photo by Soile Mottisenkangas" 
+     class="floatTR" />
 
 Welcome to my web log. See the [[first_post|posts/welcome]] for an
 introduction. See the [[archive|posts]] page for all posts, and


no message given
=== added file 'tag/profiling.mdwn'
--- tag/profiling.mdwn  1970-01-01 00:00:00 +0000
+++ tag/profiling.mdwn  2010-07-01 22:45:08 +0000
@@ -0,0 +1,4 @@
+This tag is for blog posts about profiling computer software
+for optimization purposes.
+
+[[inline archive=yes pages="link(tag/profiling)"]]


no message given
=== modified file 'index.mdwn'
--- index.mdwn  2010-01-06 17:48:47 +0000
+++ index.mdwn  2010-07-01 05:23:29 +0000
@@ -2,7 +2,8 @@
       class="floatTR" link="no"]]
 
 Welcome to my web log. See the [[first_post|posts/welcome]] for an
-introduction. See the [[archive|posts]] page for all posts. See
+introduction. See the [[archive|posts]] page for all posts, and
+[[comments]] for a feed of comments only. See
 also [identi.ca](http://identi.ca/liw).
 
 [[inline pages="posts/* and !posts/*/*"]]


no message given
=== modified file 'comments.mdwn'
--- comments.mdwn       2010-07-01 03:56:34 +0000
+++ comments.mdwn       2010-07-01 03:58:33 +0000
@@ -1,3 +1,5 @@
-Testing.
+[[!meta title="blog.liw.fi comments"]]
+
+A feed of all comments to this blog.
 
 [[!inline  pages="internal(posts/*/comment_*)" template=comment]]


no message given
=== modified file 'comments.mdwn'
--- comments.mdwn       2010-07-01 03:55:18 +0000
+++ comments.mdwn       2010-07-01 03:56:34 +0000
@@ -1,3 +1,3 @@
 Testing.
 
-[[!inline  pages="comment(posts/*)" template=comment]]
+[[!inline  pages="internal(posts/*/comment_*)" template=comment]]


no message given
=== modified file 'comments.mdwn'
--- comments.mdwn       2010-07-01 03:53:20 +0000
+++ comments.mdwn       2010-07-01 03:55:18 +0000
@@ -1,3 +1,3 @@
 Testing.
 
-[[!inline  pages="comment(*)" template=comment]]
+[[!inline  pages="comment(posts/*)" template=comment]]


no message given
=== modified file 'comments.mdwn'
--- comments.mdwn       2010-07-01 03:51:07 +0000
+++ comments.mdwn       2010-07-01 03:53:20 +0000
@@ -1,3 +1,3 @@
 Testing.
 
-[[!inline pages="posts/*/comment*"]]
+[[!inline  pages="comment(*)" template=comment]]


no message given
=== added file 'comments.mdwn'
--- comments.mdwn       1970-01-01 00:00:00 +0000
+++ comments.mdwn       2010-07-01 03:51:07 +0000
@@ -0,0 +1,3 @@
+Testing.
+
+[[!inline pages="posts/*/comment*"]]


no message given
=== added file 'posts/obnam-0.10.mdwn'
--- posts/obnam-0.10.mdwn       1970-01-01 00:00:00 +0000
+++ posts/obnam-0.10.mdwn       2010-06-29 05:39:25 +0000
@@ -0,0 +1,216 @@
+[[!meta title="Obnam 0.10 (ALPHA)"]]
+[[!tag obnam]]
+
+TL;DR
+-----
+
+Obnam, a backup program, first ALPHA release, called version 0.10,
+at <http://braawi.org/obnam/>. Please try it out and tell me what
+you think.
+
+
+Obnam 0.10: A New Hope
+----------------------
+
+A long time ago, at a computer far, far away, I realized that I
+hate making backups.
+
+When the galaxy was still young, I made backups on 5.25 inch 
+floppies. I did not have much data, only the programs I had
+written myself, so they all fit on one floppy. I had another
+floppy for backups. I would make a backup every time I felt
+I had done something I wanted to keep.
+
+Later, as suns grew red and then white,
+I generated more data, and got a lot of data from
+elsewhere, and then got a hard disk. I made backups of that on 3.5 inch
+floppies, and needed a whole pile of them. It took an entire evening
+to make a full backup. I tried many programs for making
+incremental backups, but they all got confused, or made me
+confused, or couldn't handle the inevitable failure of a
+floppy.
+
+For a while I had a tape drive. It failed more often than it
+worked. When it worked, it still took an evening to make a backup.
+
+Then CDs happened, and later DVDs. They were much more reliable than
+floppies, and you needed many fewer of them. As long as everything
+fit on one disk, I was happy, but that didn't last too long.
+
+Eventually I ended up backing up to a USB disk. Then two of them.
+It ended up as a pile of hard disks. After a couple of years I
+upgraded the disks to double the size, and halved the pile, but it
+was still too many.
+
+I would still occasionally spend an evening doing backups. That's
+an evening I could spend on something interesting. Since it isn't
+fun, it also happens too rarely, and when I needed my backups, they're
+too old. Screw that.
+
+There had to be an easier way. In 2004 I figured out what that was:
+a combination of fast networks (1 Mbit/s!), online storage (gigabytes
+of it!), and
+a sophisticated backup application would make backups easy, fast,
+automatic. I would never, ever have to pay any attention to
+them, they would just be there, ready for when I needed them.
+
+I started thinking about ways to implement this, and sketched
+out some code, and experimented a bit. However, I was distracted by stupid
+things like having to make a living, and making several false
+starts in development. While I was doing my thing, on my own,
+the world moved on, and now everyone's dog are doing backups
+online. There are, I think, about 12765 applications for
+making online backups.
+
+That's a good thing. At least one of them will be good.
+
+However, I am now finally getting ready to start using my own application
+for real. In case anyone else is interested, I am making a release.
+This is the first alpha release of the fourth complete rewrite from
+scratch. 
+
+I have not made detailed comparisons between Obnam and all the other
+programs for online backups. I don't intend to start: there's too many
+of them. Here's the core of my vision (not all of it yet implemented):
+
+* The backup server can be anything I can access via ssh. No special
+  software on the server end.
+* Entirely free software. I do not want to rely on a server that uses
+  proprietary software to provide me disk space.
+* Everything is encrypted locally, before sent to the server.
+* Fast enough to saturate the network link.
+* Non-intrusive enough to run all the time in the backgroun on my laptop.
+* Handles all corner cases (empty files, device files, etc).
+* Handles duplicate files, and moving files, efficiently.
+
+Interested? Please try it out. I would very much welcome any feedback 
+you may have, preferably via e-mail. Please be gentle.
+
+
+Highlights
+----------
+
+* Version: 0.10
+* Development status: ALPHA
+* License: GNU GPL 3 (or later)
+* Nota Bene: do not assume this works, and do not assume the on-disk
+  data structures won't change in incompatible ways.
+* On-disk data structure uses the same kind of copy-on-write B-tree
+  as btrfs, designed by Odeh Rodah. It's an independent implementation
+  in pure Python.
+* Test suite has almost 100% coverage (12 excluded statements).
+
+
+Links
+-----
+
+* Home page: <http://braawi.org/obnam/>
+* Release tarball: <http://code.liw.fi/debian/pool/main/o/obnam/obnam_0.10.tar.gz>
+* Bzr branch: <http://code.liw.fi/obnam/bzr/trunk/>
+* Benchmark results: <http://files.liw.fi/obnam-benchmarks/report.html>
+* Debian packages:
+  * `sources.list`: `deb http://code.liw.fi/debian squeeze main`
+  * <http://code.liw.fi/debian/pool/main/> (direct downloads)
+  * This is my personal apt repository, full of packages that I
+    make for myself, but it does have all the packages you need.
+    (Some day perhaps someone will upload them to Debian.)
+
+
+Dependencies
+------------
+
+* btree: <http://liw.fi/btree/> (at least version 0.10)
+* python-lru: <http://liw.fi/lru/>
+* ttystatus: <http://liw.fi/ttystatus/>
+* CoverageTestRunner: <http://liw.fi/coverage-test-runner/>
+  * You only need this for running the test suite.
+* See above for where to download Debian packages.
+* If you're not using Debian, there's tarballs there as well.
+
+
+Installation on Debian (squeeze or later)
+-----------------------------------------
+
+Add the following line to your `sources.list` file:
+
+    deb http://code.liw.fi/debian squeeze main
+
+Then:
+
+    # apt-get update
+    # apt-get install obnam
+
+
+Installation on other systems
+-----------------------------
+
+See above for where to download tarballs for Obnam and its dependencies.
+Unpack them, and install using the `setup.py` script in each. (I hope
+that works; I have only tested this on Debian.)
+
+
+What you get
+------------
+
+* Backups to local disk.
+  * Each backup generation looks like a full snapshot, but
+    only new files, and modified files are backed up.
+  * Data de-duplication: if a chunk of data is already backed up,
+    it won't be backed up again, even if it is in a different file,
+    or an older generation.
+    Renamed files, log files, etc, benefit greatly from this.
+* List generations.
+* List contents of generations.
+* Restore a full generation, or specific files.
+* Remove generations.
+
+
+Major missing features
+----------------------
+
+This is an alpha version, so obviously there are things still
+missing. I have so
+
+* Encryption. All data will be encrypted before it is put into the
+  backup store. This includes all metadata, such as filenames.
+* Online backups: the code for sftp is there, but not currently working.
+  * If someone wants to write a plugin to support another protocol,
+    I would very much welcome that. However, sftp is what I'll be
+    using myself.
+* Extreme speed. (It's slow, for now.)
+* ACLs and xattr support. Plus possibly other metadata (is there any?).
+* Stable on-disk data structures.
+  * I'm nowhere near finished optimizing, and many optimizations will
+    require changing the way things are stored on disk. I am not yet ready
+    to commit supporting the on-disk data structures indefinitely.
+
+
+Help!
+-----
+
+Help! I am trapped inside a ... no, wait, that's the wrong announcement.
+
+I would very much welcome help developing Obnam. If you'd like to
+help, here is a start of a list of things that need doing:
+
+* **Use it.** Does it work for you? If you see anything that could be

(Diff truncated)
no message given
=== added file 'posts/btree-0.10.mdwn'
--- posts/btree-0.10.mdwn       1970-01-01 00:00:00 +0000
+++ posts/btree-0.10.mdwn       2010-06-29 04:10:43 +0000
@@ -0,0 +1,20 @@
+[[!meta title="btree 0.10"]]
+[[!tag btree]]
+
+Version 0.10 of [btree](http://liw.fi/btree/), my pure Python implementation
+of the Odah Rodeh B-tree has just been released. From the NEWS file:
+
+* Storage of node reference counts is now more efficient. 
+* NodeStoreDisk stores reference counts and nodes in files in a subdirectory 
+  of the directory root, which is an incompatible change, so trees made by 
+  earlier versions can't be used anymore. (That's what you get for using 
+  alpha level code. Obviously, once btree is declared to be ready for
+  production, the on-disk data structures will be supported in future
+  versions.)
+* Nodes that exist in only one tree are modified in place, rather than
+  via copy-on-write. This is impure, but brings a big speed boost.
+* New test script: insert-remove-test. "make check" automatically runs it.
+* Many optimizations to NodeCodec and elsewhere, by Richard Braakman.
+
+There's still a lot of room for optimization, but it's starting to look
+good.


Added a comment
=== added file 'posts/python-profile-inspector/comment_2_958a8e1bf827c8c496b753cb385de09f._comment'
--- posts/python-profile-inspector/comment_2_958a8e1bf827c8c496b753cb385de09f._comment  1970-01-01 00:00:00 +0000
+++ posts/python-profile-inspector/comment_2_958a8e1bf827c8c496b753cb385de09f._comment  2010-06-28 17:55:18 +0000
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="Trundle"
+ subject="comment 2"
+ date="2010-06-28T17:55:18Z"
+ content="""
+There is <http://pypi.python.org/pypi/pyprof2calltree> which makes it possible to view profiling data in kcachegrind and there is <http://www.vrplumber.com/programming/runsnakerun/>.
+"""]]


Added a comment
=== added directory 'posts/python-profile-inspector'
=== added file 'posts/python-profile-inspector/comment_1_97a51786260db4bc90bd731cd4fe33e8._comment'
--- posts/python-profile-inspector/comment_1_97a51786260db4bc90bd731cd4fe33e8._comment  1970-01-01 00:00:00 +0000
+++ posts/python-profile-inspector/comment_1_97a51786260db4bc90bd731cd4fe33e8._comment  2010-06-28 16:06:22 +0000
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ subject="comment 1"
+ date="2010-06-28T16:06:21Z"
+ content="""
+On the perl side, I'm generally impressed with Devel::NYTProf. Generates static html files (with javascript for sorting) that allow drilling down from global hotspots t per-line profiling statistics. 
+"""]]


no message given
=== modified file 'posts/python-profile-inspector.mdwn'
--- posts/python-profile-inspector.mdwn 2010-06-28 09:10:11 +0000
+++ posts/python-profile-inspector.mdwn 2010-06-28 09:12:09 +0000
@@ -1,5 +1,5 @@
 [[!meta title="Python profile inspector"]]
-[[!tag idea]]
+[[!tag idea python profiling]]
 
 I've been in an optimization phase for 
 [obnam](http://braawi.org/obnam/) lately. This means running


no message given
=== added file 'posts/python-profile-inspector.mdwn'
--- posts/python-profile-inspector.mdwn 1970-01-01 00:00:00 +0000
+++ posts/python-profile-inspector.mdwn 2010-06-28 09:10:11 +0000
@@ -0,0 +1,17 @@
+[[!meta title="Python profile inspector"]]
+[[!tag idea]]
+
+I've been in an optimization phase for 
+[obnam](http://braawi.org/obnam/) lately. This means running
+it under the Python profiler, and examining the 
+[results](http://files.liw.fi/obnam-benchmarks/report.html).
+
+It is easy enough to generate a text file with the results,
+but it might be even better if one could have an interactive
+tool to examine the profiling results.
+
+It might, for example, be more efficient to sort the report
+in various ways interactively, or to drill down into the
+results to see where time is actually spent.
+
+Anyone want to write this for me? :)


no message given
=== added file 'tag/ttystatus.mdwn'
--- tag/ttystatus.mdwn  1970-01-01 00:00:00 +0000
+++ tag/ttystatus.mdwn  2010-06-23 16:44:34 +0000
@@ -0,0 +1,5 @@
+This tag is for blog posts about [ttystatus](http://liw.fi/ttystatus/),
+a Python library for progress and status information on terminals for
+command line utilities.
+
+[[inline archive=yes pages="link(tag/ttystatus)"]]


no message given
=== added file 'posts/ttystatus.mdwn'
--- posts/ttystatus.mdwn        1970-01-01 00:00:00 +0000
+++ posts/ttystatus.mdwn        2010-06-19 22:21:35 +0000
@@ -0,0 +1,39 @@
+[[!meta title="Python library for terminal status updates"]]
+[[!tag ttystatus python programming]]
+
+Oops, I did it again. Even though there exist some already, I made my own.
+
+This time, I wasn't happy with any of the Python libraries I could find 
+for providing progress reporting for command line applications. I admit I 
+didn't look very far, since this was a simple thing to write.
+
+Anyway, <http://liw.fi/ttystatus/> has the gory stuff. A mutilated part
+of the example program, to whet your appetite:
+
+    ts = ttystatus.TerminalStatus(period=0.1)
+    ts.add(ttystatus.Literal('Finding symlinks: '))
+    ts.add(ttystatus.Counter('symlink'))
+    ts.add(ttystatus.Literal(' found; now at '))
+    ts.add(ttystatus.Index('pathname', 'pathnames'))
+    ts.add(ttystatus.Literal(' ('))
+    ts.add(ttystatus.PercentDone('done', 'total', decimals=2))
+    ts.add(ttystatus.Literal(' done) '))
+    ts.add(ttystatus.RemainingTime('done', 'total'))
+    ts.add(ttystatus.Literal(' '))
+    ts.add(ttystatus.ProgressBar('done', 'total'))
+    ts['pathnames'] = pathnames
+    ts['done'] = 0
+    ts['total'] = len(pathnames)
+
+    for pathname in pathnames:
+        ts['pathname'] = pathname
+        if os.path.islink(pathname):
+            ts['symlink'] = pathname
+            ts.notify('Symlink! %s' % pathname)
+        ts['done'] += 1
+
+    ts.finish()
+
+I am going to be using this in obnam, obviously. Actually, obnam already had
+some code like this, but I wanted to use it in other programs as well, so I 
+extracted it, abstracted it, and make it more easily re-usable elsewhere.


no message given
=== modified file 'posts/write-intent-bitmaps.mdwn'
--- posts/write-intent-bitmaps.mdwn     2008-02-28 20:31:22 +0000
+++ posts/write-intent-bitmaps.mdwn     2010-06-14 05:09:26 +0000
@@ -46,3 +46,7 @@
 The **conclusion**: the performance impact of write-intent bitmaps is huge.
 I can't imagine anyone wanting to use them in a situation where write speed
 is at all interesting.
+
+--
+
+See some later [[discussion]].


removed
=== removed file 'tag/planet-ubuntu.mdwn'
--- tag/planet-ubuntu.mdwn      2008-02-28 21:02:34 +0000
+++ tag/planet-ubuntu.mdwn      1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-The **planet-ubuntu** tag is for posts that are meant to be syndicated to
-[Planet Ubuntu](http://planet.ubuntu.com).
-
-[[inline archive=yes pages="link(tag/planet-ubuntu)"]]


foo
=== added file 'tag/art.mdwn'
--- tag/art.mdwn        1970-01-01 00:00:00 +0000
+++ tag/art.mdwn        2010-06-14 05:02:41 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts about art.
+
+[[inline archive=yes pages="link(tag/art)"]]

=== added file 'tag/benchmark.mdwn'
--- tag/benchmark.mdwn  1970-01-01 00:00:00 +0000
+++ tag/benchmark.mdwn  2010-06-14 05:02:41 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts about benchmarking.
+
+[[inline archive=yes pages="link(tag/benchmark)"]]

=== added file 'tag/creative-commons.mdwn'
--- tag/creative-commons.mdwn   1970-01-01 00:00:00 +0000
+++ tag/creative-commons.mdwn   2010-06-14 05:02:41 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts about the Creative Commons.
+
+[[inline archive=yes pages="link(tag/creative-commons)"]]

=== added file 'tag/genbackupdata.mdwn'
--- tag/genbackupdata.mdwn      1970-01-01 00:00:00 +0000
+++ tag/genbackupdata.mdwn      2010-06-14 05:02:41 +0000
@@ -0,0 +1,4 @@
+This tag is for blog posts about
+[genbackupdata](http://braawi.org/genbackupdata/).
+
+[[inline archive=yes pages="link(tag/genbackupdata)"]]

=== added file 'tag/lru.mdwn'
--- tag/lru.mdwn        1970-01-01 00:00:00 +0000
+++ tag/lru.mdwn        2010-06-14 05:02:41 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts about [lru](http://liw.fi/lru/).
+
+[[inline archive=yes pages="link(tag/lru)"]]

=== added file 'tag/seivot.mdwn'
--- tag/seivot.mdwn     1970-01-01 00:00:00 +0000
+++ tag/seivot.mdwn     2010-06-14 05:02:41 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts about [seivot](http://liw.fi/seivot/).
+
+[[inline archive=yes pages="link(tag/seivot)"]]


no message given
=== modified file 'posts/obnam-benchmarking.mdwn'
--- posts/obnam-benchmarking.mdwn       2010-05-25 09:17:00 +0000
+++ posts/obnam-benchmarking.mdwn       2010-06-14 04:58:28 +0000
@@ -1,5 +1,5 @@
 [[!meta title="Obnam benchmarking"]]
-[[!tag obnam benchmarking seivot genbackupdata]]
+[[!tag obnam benchmark seivot genbackupdata]]
 
 [Obnam](http://braawi.org/obnam/) is still unusably slow,
 but thanks to [genbackupdata](http://braawi.org/genbackupdata/),


no message given
=== added file 'posts/soile-open-source-art.mdwn'
--- posts/soile-open-source-art.mdwn    1970-01-01 00:00:00 +0000
+++ posts/soile-open-source-art.mdwn    2010-06-07 05:47:08 +0000
@@ -0,0 +1,5 @@
+[[!meta title="Soile source"]]
+[[!tag creative-commons art]]
+
+[Soile](http://docstory.fi/) is getting interested in
+applying [open source to art](http://docstory.fi/posts/open_source/).


Added a comment
=== added file 'posts/python-lru/comment_2_a745c64fc3d07861ca2b0be41074be5d._comment'
--- posts/python-lru/comment_2_a745c64fc3d07861ca2b0be41074be5d._comment        1970-01-01 00:00:00 +0000
+++ posts/python-lru/comment_2_a745c64fc3d07861ca2b0be41074be5d._comment        2010-06-01 08:05:44 +0000
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="comment 2"
+ date="2010-06-01T08:05:43Z"
+ content="""
+Robert, you're almost certainly right that it might be worthwhile invest time and energy learning bzrlib so I could benefit from all the great work the bzr developers have done. It is not very high on my list of things to do, however.
+
+bzrlib is a huge big dependency that I do not want to inflict on people. Also, it's big enough that it'd take a long time to get familiar with it, and to keep track of it every month when it changes. And to backport it to the Debian stable release or wherever. All of which is not the kind of fun I want to have while programming in my free time. (Productivity being less important than fun in my free time.)
+
+I'm not saying it wouldn't be worthwhile, but, on the whole, the benefits have to be clear and immediate for me to overcome my NIH.
+
+In this particular case, I did a couple of quick speed tests. Both implementations are very close to the same speed. Mine is slightly slower, on the order of 20%, using a modified version of speed-test in my source tree. With max 100 elements, 18.5 versus 15.6 milliseconds per loop, according to timeit. With 10,000 elements, 13.1 versus 11.1 milliseconds.
+
+Not bad for an evening's work, if I say so myself.
+
+Do you think it might be possible for bzrlib to be broken down into smaller, more easily grokked libraries?
+
+Writing good reusable code is hard. Getting people to use it is harder.
+"""]]


Added a comment: bzrlib
=== added directory 'posts/python-lru'
=== added file 'posts/python-lru/comment_1_0e22d5687f6fceab9eb8a520e51c5562._comment'
--- posts/python-lru/comment_1_0e22d5687f6fceab9eb8a520e51c5562._comment        1970-01-01 00:00:00 +0000
+++ posts/python-lru/comment_1_0e22d5687f6fceab9eb8a520e51c5562._comment        2010-06-01 01:25:43 +0000
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~lifeless"
+ subject="bzrlib"
+ date="2010-06-01T01:25:42Z"
+ content="""
+import bzrlib.lru_cache
+
+You should probably start looking in bzrlib for your coding needs ;)
+
+-Rob
+"""]]


no message given
=== added file 'posts/python-lru.mdwn'
--- posts/python-lru.mdwn       1970-01-01 00:00:00 +0000
+++ posts/python-lru.mdwn       2010-05-29 22:45:45 +0000
@@ -0,0 +1,8 @@
+[[!meta title="LRU cache for Python"]]
+[[!tag python lru]]
+
+I needed a least-recently-used cache for Python, and wasn't happy with
+the ones I found on PyPi, so I wrote my own: [python-lru](http://liw.fi/lru/).
+
+(I wonder if I should learn how to put my own stuff on PyPi? Would anyone
+find any of it useful?)


no message given
=== added file 'posts/btree-0.9.mdwn'
--- posts/btree-0.9.mdwn        1970-01-01 00:00:00 +0000
+++ posts/btree-0.9.mdwn        2010-05-26 09:58:02 +0000
@@ -0,0 +1,9 @@
+[[!meta title="btree 0.9"]]
+[[!tag btree]]
+
+I pushed out release version 0.9 of my [B-tree library](http://liw.fi/btree/).
+Mostly optimizations, and a fix for one bad performance-related bug.
+
+I'm starting to feel carefully optimistic about this B-tree. It is still too slow, being able to do only about 1700 inserts per second on my laptop, but I'm not done working on it yet.
+
+(Patches welcome! Bug reports, too.)


no message given
=== added file 'posts/obnam-benchmarking.mdwn'
--- posts/obnam-benchmarking.mdwn       1970-01-01 00:00:00 +0000
+++ posts/obnam-benchmarking.mdwn       2010-05-25 09:17:00 +0000
@@ -0,0 +1,9 @@
+[[!meta title="Obnam benchmarking"]]
+[[!tag obnam benchmarking seivot genbackupdata]]
+
+[Obnam](http://braawi.org/obnam/) is still unusably slow,
+but thanks to [genbackupdata](http://braawi.org/genbackupdata/),
+[seivot](http://liw.fi/seivot/), and the Python profiler,
+I have made it be somewhat less unusably slow.
+
+It can now do about 1 Mbit/s, or almost 4 GiB overnight.


no message given
=== added file 'posts/obnam-benchmarkspec.mdwn'
--- posts/obnam-benchmarkspec.mdwn      1970-01-01 00:00:00 +0000
+++ posts/obnam-benchmarkspec.mdwn      2010-05-23 10:04:11 +0000
@@ -0,0 +1,8 @@
+[[!meta title="Obnam benchmark specification"]]
+[[!tag obnam benchmark]]
+
+I wrote a [specification for obnam benchmarking](http://braawi.org/obnam/benchmarkspec/)
+and implemented it.
+
+Obnam is unusably slow, but it seems to work correctly. Nobody can blame me
+for premature optimization...


no message given
=== modified file 'posts/glass-fact-19.mdwn'
--- posts/glass-fact-19.mdwn    2010-05-06 03:01:43 +0000
+++ posts/glass-fact-19.mdwn    2010-05-11 10:07:26 +0000
@@ -50,3 +50,23 @@
 
 This sounds to me like Glass either does not really understand open
 source software development, or is spreading some FUD about it.
+
+**Update:** In fact 34, in the context of using tools such as coverage
+testers, Glass discusses 
+[Linus's Law](http://en.wikipedia.org/wiki/Linus%27_Law), 
+"given enough eyeballs, all bugs are shallow", as follows:
+
+> Open sourcers expect that users of their software will read and
+> analyze it, thus finding the errors themselves.
+
+This is a subtle, but possibly poisonous distortion of the law. 
+The poison is in the implication
+that every user of free software is expected to participate
+in code reviews and debugging, which is tedious and time-consuming.
+That is not at all the case. Instead, only if users want problems to be fixed
+are they expected to do anything, and the expectation is to report the
+probem, and provide sufficient information to
+find the cause.
+
+It is entirely true that this only works for popular projects.
+Unpopular projects do not benefit from Linus's Law.


Added a comment: wotsap
=== added directory 'posts/gpg-trust-path-queries'
=== added file 'posts/gpg-trust-path-queries/comment_1_d210d3f5184ad80cf5b6ca9c9f9784de._comment'
--- posts/gpg-trust-path-queries/comment_1_d210d3f5184ad80cf5b6ca9c9f9784de._comment    1970-01-01 00:00:00 +0000
+++ posts/gpg-trust-path-queries/comment_1_d210d3f5184ad80cf5b6ca9c9f9784de._comment    2010-05-07 19:57:41 +0000
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="wotsap"
+ date="2010-05-07T19:57:40Z"
+ content="""
+The wotsap program solves most of this.
+
+<http://www.lysator.liu.se/~jc/wotsap/index.html> is the home page.
+"""]]


no message given
=== added file 'posts/glass-fact-19.mdwn'
--- posts/glass-fact-19.mdwn    1970-01-01 00:00:00 +0000
+++ posts/glass-fact-19.mdwn    2010-05-06 03:01:43 +0000
@@ -0,0 +1,52 @@
+[[!meta title="Glass's Fact 19 and open source"]]
+[[!tag rant]]
+
+I'm reading Robert Glass's "Facts and Fallacies of Software Engineering".
+He presents Fact 19:
+
+> Modification of reused code is particularly error-prone. If more
+> than 20 to 25 percent of a component is to be revised, it is more
+> efficient and effective to rewrite it from scratch.
+
+Then in the discussion of that fact:
+
+> Note that this same problem has interesting ramifications for the
+> open-source software movement. It is easy to access open-source code
+> to modify it, but the wisdom of doing so is clearly questionable,
+> unless the once-modified version of the open-source code is to
+> become a new fork in the system's development, never to merge with
+> the standard version again. I have never heard open-source advocates
+> discuss this particular problem. (One solution, of course, would be
+> for the key players for the open-source code in question to accept
+> those in-house modifications as part of the standard version. But
+> there is never any guarantee that they will choose to do that.)
+
+Let me express that in bullet points, in a slightly snarky manner:
+
+* Open source gives you access to source.
+* Modifying that source is therefore easy.
+* This results in a fork that you have to maintain.
+* There is no guarantee upstream will accept the change.
+* Open source loses.
+
+Well, duh. If you're going to be making modifications to upstream
+code, and upstream does not accept them, of course you're going 
+have to maintain those changes yourself. It doesn't matter whether
+it's open source or not.
+
+However, even though there is no guarantee, if the change is sensible,
+well made, and relevant to others than you, most upstream projects 
+will accept the change.
+
+In fact, the very reason open source flourishes is because upstream
+routinely, frequently, nay incessantly take changes others have made
+for their own purposes and incorporate them into the upstream code
+base.
+
+It's not unheard of that a proprietary project will accept patches
+from its users, but since those patches are so hard to make, and all
+sorts of licensing issues and financial considerations come into play,
+it's hard, and therefore rare.
+
+This sounds to me like Glass either does not really understand open
+source software development, or is spreading some FUD about it.


no message given
=== added file 'posts/btree-with-cloning.mdwn'
--- posts/btree-with-cloning.mdwn       1970-01-01 00:00:00 +0000
+++ posts/btree-with-cloning.mdwn       2010-05-05 08:58:38 +0000
@@ -0,0 +1,12 @@
+[[!meta title="B-trees with cloning"]]
+[[!tag btree obnam]]
+
+The B-tree implementation I am making for Obnam has reached an important
+milestone: it can clone trees. This is important because the way
+I [envision I will use the trees](http://braawi.org/obnam/ondisk/) will
+have one tree per backup generation, and each new generation starts by
+cloning the old one.
+
+I'm still not convinced I will actually be using my own B-tree implementation
+instead of an existing one, but I need to do this once, so I know how they
+work.


no message given
=== modified file 'posts/btree-code.mdwn'
--- posts/btree-code.mdwn       2010-03-14 04:04:36 +0000
+++ posts/btree-code.mdwn       2010-05-05 08:50:46 +0000
@@ -1,5 +1,5 @@
 [[!meta title="Lazyweb: B-tree code review?"]]
-[[!tag obnam]]
+[[!tag obnam btree]]
 
 I think I need a B-tree implementation for Obnam, in Python. I could not find anything suitable so I wrote my own. However, since it about two 
 decades since my data structures class at university, I probably


no message given
=== added file 'tag/btree.mdwn'
--- tag/btree.mdwn      1970-01-01 00:00:00 +0000
+++ tag/btree.mdwn      2010-05-05 08:48:52 +0000
@@ -0,0 +1,3 @@
+This tag is for blog entries having to with my B-tree implementation.
+
+[[inline archive=yes pages="link(tag/btree)"]]


no message given
=== added file 'posts/duplicate-data-in-fs.mdwn'
--- posts/duplicate-data-in-fs.mdwn     1970-01-01 00:00:00 +0000
+++ posts/duplicate-data-in-fs.mdwn     2010-04-28 09:51:59 +0000
@@ -0,0 +1,31 @@
+[[!meta title="Duplicate data in filesystems"]]
+[[!tag obnam]]
+
+For my backup program, I wish to store a chunk of content only once,
+regardless of how many times it appears in the filesystem. This can
+easily be done by having a way of looking up chunks via checksums.
+The lookup has some time and space overhead: the smaller the chunk,
+the more chunks there are, and the higher the overhead. On the other
+hand, intuition says that the smaller the chunk, the more likely it
+is to have a duplicate, and the more space can be saved.
+
+Is that true? Only one way to figure out.
+
+I wrote a little [program](http://files.liw.fi/find-duplicate-chunks) 
+to compute an MD5 checksum for each chunk of
+a given size, at given offsets. For example, 4096 byte chunks at 1024
+byte offsets (chunks overlap). Then I ran this program on a snapshot
+of my laptop's home directory.
+
+[[plot.png]]
+
+In the above plot, it looks to me like the size of the offset matters
+only if it is very small (up to about 4 KiB). However, the size
+of the chunk matters fairly much. Luckily there seems to be a large
+bump at 128 KiB. It is lucky because it is a pretty large chunk, so
+there are few of them, so the lookup overhead is much smaller.
+
+Or possibly I should learn some statistics.
+
+I have yet no idea whether this results in something useful for the
+actual backup program. It was just a small side project.


attachment upload
=== added directory 'posts/duplicate-data-in-fs'
=== added file 'posts/duplicate-data-in-fs/plot.png'
Binary files posts/duplicate-data-in-fs/plot.png        1970-01-01 00:00:00 +0000 and posts/duplicate-data-in-fs/plot.png       2010-04-28 09:51:37 +0000 differ

no message given
=== added file 'posts/locale-gui.mdwn'
--- posts/locale-gui.mdwn       1970-01-01 00:00:00 +0000
+++ posts/locale-gui.mdwn       2010-04-25 00:19:19 +0000
@@ -0,0 +1,37 @@
+[[!meta title="GUI app to configure locale for GNOME"]]
+[[!tag idea gnome]]
+
+[Enrico](http://www.enricozini.org/) wrote about 
+[setting locale variables for gdm](http://www.enricozini.org/2010/tips/locales/).
+This reminded me that it would be nice if one could **tweak the locale settings**
+for a user in GNOME with a **nice GUI app.** 
+
+There are a lot of people who might,
+for example, want to have their computer speak English to them, because the
+translations to their native language are not particularly good. Or perhaps
+they would prefer French, because they live in France, and it's practical to
+not have to keep translating between languages all the time. 
+
+At the same
+time, they might want to have things sorted in the order their native order,
+or dates in the way they are used to, or do some other tweaking.
+
+This is easy to achieve, as Enrico shows, by setting `LC_MESSAGES` to, say,
+`en_NZ.UTF-8`, but `LC_COLLATE` and `LC_TIME` to to `fi_FI.UTF-8`.
+
+For many people, the problem is that tweaking these things by setting 
+variables in a dot-file is scary. Having a GUI for doing that would make
+things easier.
+
+When I mentioned this to Enrico, he suggested: 
+
+> Very true indeed. A preview of things like sort order, messages, date
+> formatting, currency would also act as a fancy showcase of what locales
+> can do. Quite a lot of work to put them together, though.
+
+Anyone up for the task?
+
+Ideally, one would change the default GNOME session and/or gdm to source
+a file (`~/.config/locale.conf` if it exists) where these settings could
+be stored, but to start with, one could just edit `.xsessionrc`, with
+proper precautions.


no message given
=== added file 'tag/enemies-of-carlotta.mdwn'
--- tag/enemies-of-carlotta.mdwn        1970-01-01 00:00:00 +0000
+++ tag/enemies-of-carlotta.mdwn        2010-04-20 19:23:42 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts that are about [Enemies of Carlotta](http://liw.fi/eoc/), the mailing list manager.
+
+[[inline archive=yes pages="link(tag/enemies-of-carlotta)"]]


no message given
=== added file 'posts/eoc-hashlib-patch.mdwn'
--- posts/eoc-hashlib-patch.mdwn        1970-01-01 00:00:00 +0000
+++ posts/eoc-hashlib-patch.mdwn        2010-04-15 08:17:47 +0000
@@ -0,0 +1,14 @@
+[[!meta title="Hashlib patch for Enemies of Carlotta"]]
+[[!tag enemies-of-carlotta]]
+
+Tomi Tuominen sent me a patch to update [Enemies of Carlotta](http://liw.fi/eoc/)
+to use hashlib instead of the deprecated md5 module for Python.
+
+This prompted me to put the bzr branch I have at a new location. The domain
+we had for the project for a while expired, and since I am not into mailing
+list managers anymore, I didn't care to keep the domain alive. However, in
+case anyone wants to grab the code and run with it, it's public again.
+
+(Actually, I would not mind at all an opportunity to rewrite EoC to be truly
+powerful. However, it is not something I am willing to do on my own time.
+I wish someone else would, though.)


Added a comment
=== added directory 'posts/btree-code'
=== added file 'posts/btree-code/comment_1_b7c25bcb5a803e601fc36558440d9d63._comment'
--- posts/btree-code/comment_1_b7c25bcb5a803e601fc36558440d9d63._comment        1970-01-01 00:00:00 +0000
+++ posts/btree-code/comment_1_b7c25bcb5a803e601fc36558440d9d63._comment        2010-03-29 12:37:38 +0000
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~lifeless"
+ subject="comment 1"
+ date="2010-03-29T12:37:36Z"
+ content="""
+So, other implementations:
+ZopeDB
+bzrlib.btree_index
+bzrlib.chk_map (this is probably closest to what you want)
+
+Several others I found when researching whether we needed to write one for btree_index.
+
+I haven't looked at your code [yet]. Ping me in a while if I don't get back to you.
+"""]]


no message given
=== added file 'tag/system-administration.mdwn'
--- tag/system-administration.mdwn      1970-01-01 00:00:00 +0000
+++ tag/system-administration.mdwn      2010-03-19 06:02:06 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts that are about system administration.
+
+[[inline archive=yes pages="link(tag/system-administration)"]]


no message given
=== added file 'posts/server-maint-styles.mdwn'
--- posts/server-maint-styles.mdwn      1970-01-01 00:00:00 +0000
+++ posts/server-maint-styles.mdwn      2010-03-19 06:00:18 +0000
@@ -0,0 +1,22 @@
+[[!meta title="Server maintenance styles"]]
+[[!tag system-administration]]
+
+This thought struck me today, out of the blue.
+
+There are two ways of running servers: 
+
+1. Keep it rock solid, by avoiding change as much as possible. This
+   is quite excellent: nothing changes, so minimal effort is required
+   and costs are cheap. Those relying on the server can just assume it
+   is there. However, when there is a necessary change, such as a 
+   kernel security update, it is quite disruptive. Everything stops,
+   people get nervous, and deodorant sales go up.
+1. Make frequent changes, and build everything on the assumption that
+   the server may be out of service at any time. Replicate services,
+   avoid keeping state unnecessarily, and do anything else you need to
+   do to handle the constant rebooting and other outages. This is more
+   expensive to build, and to run, but perhaps not a lot more, and a 
+   kernel update will barely even be noticed. It is not disruptive at all.
+   You will save a lot on deodorant.
+
+Now, I do not run many servers, so this may be bogus.


Added a comment
=== added file 'posts/saving-instead-of-bookmarking/comment_2_8fb12a2356f36db5be30c68dd23dc2ce._comment'
--- posts/saving-instead-of-bookmarking/comment_2_8fb12a2356f36db5be30c68dd23dc2ce._comment     1970-01-01 00:00:00 +0000
+++ posts/saving-instead-of-bookmarking/comment_2_8fb12a2356f36db5be30c68dd23dc2ce._comment     2010-03-18 06:41:40 +0000
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="comment 2"
+ date="2010-03-18T06:41:39Z"
+ content="""
+Nope, I haven't tried it. Nor will I, since it is not free software.
+
+<http://www.ideashower.com/support/read-it-later/is-read-it-later-free/>
+"""]]


Added a comment: Suggestion
=== added directory 'posts/saving-instead-of-bookmarking'
=== added file 'posts/saving-instead-of-bookmarking/comment_1_ed3069df292d4217d558e380b148aaba._comment'
--- posts/saving-instead-of-bookmarking/comment_1_ed3069df292d4217d558e380b148aaba._comment     1970-01-01 00:00:00 +0000
+++ posts/saving-instead-of-bookmarking/comment_1_ed3069df292d4217d558e380b148aaba._comment     2010-03-18 01:53:52 +0000
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://daemonsadvocate.blogspot.com/"
+ subject="Suggestion"
+ date="2010-03-18T01:53:51Z"
+ content="""
+Hey Lars;
+
+Have you tried the Read it Later[1] plugin? It caches those pages in a much nicer way than saving pages from Firefox :).
+
+[1] Read it later - http://readitlaterlist.com/
+"""]]


no message given
=== added file 'posts/journal-ikiwiki.mdwn'
--- posts/journal-ikiwiki.mdwn  1970-01-01 00:00:00 +0000
+++ posts/journal-ikiwiki.mdwn  2010-03-16 09:25:57 +0000
@@ -0,0 +1,70 @@
+[[!meta title="Keeping a journal"]]
+[[!tag productivity journal ikiwiki]]
+
+For a while now, I have kept a journal of my programming related activities.
+I find this to be good for three things:
+
+1. I pour out all my thoughts about a problem I am solving, or task I am
+   doing, and this helps me think more clearly. The act of writing requires
+   me to think things through. When I write like this, I write to a future
+   self, who is angry and digging in the journal to find out why I did the
+   stupid thing I did. Sometimes, if I explain my reasoning, I realize
+   while writing that I am doing a stupid thing. Other times, my future
+   self will realize that my reasoning was sound, but something happened
+   to make it stupid later. In a more social setting, I could discuss
+   things with a co-worker to get the same benefit. 
+1. I write down steps to do specific tasks, which is sometimes helpful when
+   I need to do them again, or when I need to figure out what broke.
+1. If I am hacking on some code, and need to take a long break (for example,
+   to drive from Christchurch to Wellington via Auckland), I can more easily
+   pick up the work again. My journal will tell me where I was, and what I
+   was thinking.
+
+I do not keep the journal as regularly as I wish I would, but even when I update it only
+half the time, it is quite useful. When you can't walk, it helps if someone
+carries you, even if they only carry you half way.
+
+I started this journal on November 3, 2005, using a single plain text file. 
+Eventually that grew too big to be practical, 
+so it became a series of text files instead, one per day.
+For a while the files were in HTML, but that was tedious, so I switched
+back to plain text again.
+Now, I use [ikiwiki](http://ikiwiki.info/) and
+[markdown](http://ikiwiki.info/ikiwiki/markdown/).
+
+Markdown is a wonderful, minimal markup language. Almost all of my journal
+entries from the plain text era were already in markdown, perhaps with
+minor tweaks. When I need more power, I have it, but when I don't, I do not
+have to do suffer from the tediousness of writing HTML by hand.
+
+Ikiwiki is a wonderful wiki engine, which is quite flexible. It can use
+a real version control system to store the wiki contents. With modern
+distributed version control systems, this gives the additional possibility
+of having multiple instances of the wiki. For my journal, this is useful:
+I can have the same journal on my laptop, for personal projects, and on
+my work machine, for work stuff. Having the same journal on both places
+makes it easier to look things up.
+
+I could keep the journal on a server, of course, and access it over the
+Internet. That is what I would do, if I had good Internet access everywhere,
+but I don't.
+
+Using a good wiki engine for the journal has proven to be quite useful.
+I can use tagging to make it easier to see journal entries for specific
+topics. Ikiwiki uses the xapian search engine to provide handy full text
+searches.
+
+I am also experimenting with a feature to have wiki pages for people
+I mention in my journal entries. Each person has a dedicated page
+(`/person/wirzenius.lars`), and each entry that mentions that person,
+links to their page. The page then uses ikiwiki's
+`inline` directive to automatically list all journal entries that
+mention them.
+
+This makes it much easier for me to remember who the people are, for
+people I meet rarely. There is something wrong with my brain when it
+comes to remembering people, and I need every bit of help I can get.
+
+I may expand this to other things than people, some day, but I need
+to be careful about not making it too tedious, or I will stop keeping
+the journal. Full semantic web markup is not going to happen.


no message given
=== added file 'tag/journal.mdwn'
--- tag/journal.mdwn    1970-01-01 00:00:00 +0000
+++ tag/journal.mdwn    2010-03-16 09:22:39 +0000
@@ -0,0 +1,4 @@
+This tag is for blog posts that are about 
+keeping a journal.
+
+[[inline archive=yes pages="link(tag/journal)"]]


no message given
=== added file 'tag/ikiwiki.mdwn'
--- tag/ikiwiki.mdwn    1970-01-01 00:00:00 +0000
+++ tag/ikiwiki.mdwn    2010-03-16 09:20:52 +0000
@@ -0,0 +1,4 @@
+This tag is for blog posts that are about 
+[ikiwki](http://ikiwiki.info/).
+
+[[inline archive=yes pages="link(tag/ikiwiki)"]]


no message given
=== added file 'posts/btree-code.mdwn'
--- posts/btree-code.mdwn       1970-01-01 00:00:00 +0000
+++ posts/btree-code.mdwn       2010-03-14 04:04:36 +0000
@@ -0,0 +1,278 @@
+[[!meta title="Lazyweb: B-tree code review?"]]
+[[!tag obnam]]
+
+I think I need a B-tree implementation for Obnam, in Python. I could not find anything suitable so I wrote my own. However, since it about two 
+decades since my data structures class at university, I probably
+messed it up. Please tell me how?
+
+I include the code below, and it can also be found via bzr:
+
+    bzr get http://code.liw.fi/btree/bzr/trunk/
+
+The code in bzr may get updated; I will keep the code below static.
+The bzr branch also contains some automatic test cases.
+
+One of the requirements I have for the B-tree code is that it needs
+to update things via copy-on-write. In Obnam, I will not overwrite
+data on disk, I will instead write a new file, and then do garbage
+collection at a later time to reclaim the files that are no longer
+needed. This will be necessary for implementing backup generations,
+for example. That's why some of the code might be a bit weird.
+
+Once I have some confidence that my code works, I will extend
+the tree code to use some external, user-provided mechanism for
+storing the nodes, and to use the size of the nodes in bytes as
+the limiting factor, not the number of keys.
+
+In addition to bugs, I welcome any other feedback.
+
+    class Node(dict):
+
+        '''Abstract base class for index and leaf nodes.
+        
+        A node may be initialized with a list of (key, value) pairs. For
+        leaf nodes, the values are the actual values. For index nodes, they
+        are references to other nodes.
+        
+        '''
+
+        def keys(self):
+            '''Return keys in the node, sorted.'''
+            return sorted(dict.keys(self))
+
+        def first_key(self):
+            '''Return smallest key in the node.'''
+            return self.keys()[0]
+
+        def pairs(self, exclude=None):
+            '''Return (key, value) pairs in the node.
+            
+            ``exclude`` can be set to a list of keys that should be excluded
+            from the list.
+            
+            '''
+
+            if exclude is None:
+                exclude = []
+            return sorted((key, self[key]) for key in self if key not in exclude)
+
+
+    class LeafNode(Node):
+
+        '''Leaf node in the tree.
+        
+        A leaf node contains key/value pairs, and has no children.
+        
+        '''
+
+        pass
+
+
+    class IndexNode(Node):
+
+        '''Index node in the tree.
+        
+        An index node contains pairs of keys and references to other nodes.
+        The other nodes may be either index nodes or leaf nodes.
+        
+        '''
+
+        def __init__(self, pairs):
+            for key, child in pairs:
+                assert type(key) == str
+                assert isinstance(child, IndexNode) or isinstance(child, LeafNode)
+            dict.__init__(self, pairs)
+
+        def find_key_for_child_containing(self, key):
+            '''Return key for the child that contains ``key``.'''
+            for k in reversed(self.keys()):
+                if key >= k:
+                    return k
+            return None
+           
+
+    class BTree(object):
+
+        '''B-tree.
+        
+        The tree is balanced, and has a fan-out factor given to the initializer
+        as its only argument. The fan-out factor determines how aggressively
+        the tree expands at each level.
+        
+        Three basic operations are available to the tree: lookup, insert, and
+        remove.
+        
+        '''
+
+        def __init__(self, fanout):
+            self.root = IndexNode([])
+            self.fanout = fanout
+            self.min_index_length = self.fanout
+            self.max_index_length = 2 * self.fanout + 1
+            
+        def lookup(self, key):
+            '''Return value corresponding to ``key``.
+            
+            If the key is not in the tree, raise ``KeyError``.
+            
+            '''
+
+            return self._lookup(self.root, key)
+
+        def _lookup(self, node, key):
+            if isinstance(node, LeafNode):
+                return node[key]
+            else:
+                k = node.find_key_for_child_containing(key)
+                if k is None:
+                    raise KeyError(key)
+                else:
+                    return self._lookup(node[k], key)
+
+        def insert(self, key, value):
+            '''Insert a new key/value pair into the tree.
+            
+            If the key already existed in the tree, the old value is silently
+            forgotten.
+            
+            '''
+
+            a, b = self._insert(self.root, key, value)
+            if b is None:
+                self.root = a
+            else:
+                self.root = IndexNode([(a.first_key(), a),
+                                       (b.first_key(), b)])
+
+        def _insert(self, node, key, value):
+            if isinstance(node, LeafNode):
+                return self._insert_into_leaf(node, key, value)
+            elif len(node) == 0:
+                return self._insert_into_empty_root(key, value)
+            elif len(node) == self.max_index_length:
+                return self._insert_into_full_index(node, key, value)
+            else:
+                return self._insert_into_nonfull_index(node, key, value)
+
+        def _insert_into_leaf(self, leaf, key, value):
+            pairs = sorted(leaf.pairs(exclude=[key]) + [(key, value)])
+            if len(pairs) <= self.fanout:
+                return LeafNode(pairs), None
+            else:
+                n = len(pairs) / 2
+                leaf1 = LeafNode(pairs[:n])
+                leaf2 = LeafNode(pairs[n:])
+                return leaf1, leaf2
+
+        def _insert_into_empty_root(self, key, value):
+            leaf = LeafNode([(key, value)])
+            return IndexNode([(leaf.first_key(), leaf)]), None
+
+        def _insert_into_full_index(self, node, key, value):
+            # A full index node needs to be split, then key/value inserted into
+            # one of the halves.
+            pairs = node.pairs()
+            n = len(pairs) / 2
+            node1 = IndexNode(pairs[:n])
+            node2 = IndexNode(pairs[n:])
+            if key <  node2.first_key():
+                a, b = self._insert(node1, key, value)
+                assert b is None
+                return a, node2
+            else:
+                a, b = self._insert(node2, key, value)
+                assert b is None
+                return node1, a
+        
+        def _insert_into_nonfull_index(self, node, key, value):        
+            # Insert into correct child, get up to two replacements for
+            # that child.
+
+            k = node.find_key_for_child_containing(key)
+            if k is None:
+                k = node.first_key()
+
+            a, b = self._insert(node[k], key, value)
+            assert a is not None

(Diff truncated)
no message given
=== added file 'posts/obnam-performance-requirement.mdwn'
--- posts/obnam-performance-requirement.mdwn    1970-01-01 00:00:00 +0000
+++ posts/obnam-performance-requirement.mdwn    2010-02-28 05:53:30 +0000
@@ -0,0 +1,11 @@
+[[!meta title="Obnam performance requirement"]]
+[[!tag obnam]]
+
+I don't think I've said this publically yet, so I'll do it
+now: My performance goal with obnam for the 1.0 release
+is to be able to saturate a wifi connection. That means
+that it needs to be able to write at least 3 megabytes
+per second when doing a local backup.
+
+It's not a hugely impressive goal, but it satisfies my
+personal use cases.


no message given
=== modified file 'posts/saving-instead-of-bookmarking.mdwn'
--- posts/saving-instead-of-bookmarking.mdwn    2010-02-21 06:32:44 +0000
+++ posts/saving-instead-of-bookmarking.mdwn    2010-02-21 06:42:06 +0000
@@ -1,4 +1,4 @@
-[[!meta title="Living limited Internet access: saving web pages instead of bookmarking them"]]
+[[!meta title="Living with limited Internet access: saving web pages instead of bookmarking them"]]
 [[!tag productivity note-to-self]]
 
 I'm currently touring New Zealand. Internet access here is either very slow, very expensive, or both. Or it's not there at all.


no message given
=== added file 'posts/saving-instead-of-bookmarking.mdwn'
--- posts/saving-instead-of-bookmarking.mdwn    1970-01-01 00:00:00 +0000
+++ posts/saving-instead-of-bookmarking.mdwn    2010-02-21 06:32:44 +0000
@@ -0,0 +1,10 @@
+[[!meta title="Living limited Internet access: saving web pages instead of bookmarking them"]]
+[[!tag productivity note-to-self]]
+
+I'm currently touring New Zealand. Internet access here is either very slow, very expensive, or both. Or it's not there at all.
+
+I have long bookmarked pages I want to read, but don't have time to read at the moment I encounter them. For example, if I'm reading reddit, I open all the pages that seem interesting, and if they seem interesting after the first ten seconds, I bookmark them.
+
+This works quite well, when I have good Internet access.
+
+I've now switched to saving pages locally instead. Firefox's "File/Save as" works quite well, except when pages insist on doing things in complicated ways.


no message given
=== added file 'posts/gps-urkinta.mdwn'
--- posts/gps-urkinta.mdwn      1970-01-01 00:00:00 +0000
+++ posts/gps-urkinta.mdwn      2010-02-21 05:21:13 +0000
@@ -0,0 +1,32 @@
+[[!meta title="Autojen GPS-urkinta etenee"]]
+[[!tag in-finnish finnish-politics rant]]
+
+YLE uutisoi, että Sunnuntaisuomalainen uutisoi, että
+[Ajokilometreihin perustuva autovero altis huijaukselle](http://yle.fi/uutiset/kotimaa/2010/02/ajokilometreihin_perustuva_autovero_altis_huijaukselle_1466646.html?origin=rss):
+
+> Kilometreihin perustuva autovero ja Helsinkiin kaavailtu ruuhkamaksu ovat alttiita huijaukselle, kirjoittaa Väli-Suomen sanomalehtien Sunnuntaisuomalainen. Molemmat perustuvat autojen satelliittipaikannukseen, mutta internetistä saa tilattua laitteita, joilla paikannuksen voi estää. 
+
+Välineitä GPS-vastaanoton häiritsemiseen saa ostettua mistä tahansa rautakaupasta. Riittää, että antennin ympärille pistää metallipurkin.
+
+YLE kirjoittaa myös:
+
+> Kilometreihin perustuvasta autoverosta ei ole päätöstä, mutta liikenneministeri Anu Vehviläinen (kesk.) on ehdottanut sellaista.
+
+Pelkkien ajokilometrien seurantaan GPS on monimutkainen ja virheherkkä ratkaisu. Kaikissa autoissa on jo valmiiksi paljon yksinkertaisempi väline: kilometrimittari.
+
+Monimutkaisen, virheherkän ja kalliin valvontajärjestelmän rakentamisen sijaan olisi helppoa vaatia, että ajoneuvon vuosittaiset kilometrit rekisteröidään katsastuksen yhteydessä.
+
+Vielä helpompaa olisi nostaa polttoaineveroa. Se ei vaatisi minkään uusien järjestelmien rakentamista.
+
+Tätä ei kuitenkaan tulla tekemään, koska Suomen poliittiset päättäjät ovat joko teknologiayritysten nenästä vedettävissä tai ovat ymmärtäneet kirjan [1984](http://www.effi.org/julkaisut/tiedotteet/lehdistotiedote-2009-06-11.html)
+aivan väärin.
+
+Edelleen YLE:n uutisesta:
+
+> Öörni uskoo, että häirintälaitteiden kitkemiseksi joudutaan rakentamaan tekninen valvontajärjestelmä. Todennäköisin vaihtoehto on rekisterikilpiä kuvaavat liikuteltavat kamerat. 
+
+Totta kai on järkevää ensin rakentaa monimutkainen, virheherkkä, kallis GPS-valvontajärjestelmä ja sen jälkeen toinen monimutkainen, virheherkkä ja kallis järjestelmä valvomaan ensimmäisen toimivuutta. Tämä on järkevää nimenomaan siksi, että _kumpikin järjestelmä_ on omiaan ihmisten valvomiseen.
+
+Tämä on tärkeä pointti: kaikki nämä järjestelmät tähtäävät viime kädessä siihen, että autojen kaikkia liikkeitä valvotaan mahdollisimman tarkasti. Koska melkein kaikki autot ovat yhden tai kahden kuljettajan käytössä, tässä valvotaan siis ihmisten liikkumista.
+
+Jos hallituksessa olisi yhtään yksityisyydestä välittävää henkilöä, nämä hankkeet ja puheet loppuisivat lyhyeen tai ainakin niiden hyödyistä ja haitoista käytäisiin julkista keskustelua. Nyt pelkästään puhutaan siitä, miten mahdolliset järjestelmää huijaavat saadaan kiinni.


no message given
=== added file 'posts/obnam-feature-complete-for-now.mdwn'
--- posts/obnam-feature-complete-for-now.mdwn   1970-01-01 00:00:00 +0000
+++ posts/obnam-feature-complete-for-now.mdwn   2010-02-19 02:53:46 +0000
@@ -0,0 +1,12 @@
+[[!meta title="Obnam is feature complete (sort of)"]]
+[[!tag obnam]]
+
+I have recently implemented all Obnam features I think I want before I start using it for real, except encryption. The next step is to re-implement the backup store implementation. The current implementation is the simplest, most stupidest one I could get away with. I did not care at all about performance, so it is rather, er, slow.
+
+I said stupid, right? Yes I did.
+
+I may end up implementing the backup store in several ways, to be able to compare them in semi-real-life benchmarks.
+
+I was going to add support for ACLs and extended attributes, but I decided not to: I do not use them myself, and they're just non-obvious enough that I am going to need to find a collaborator to verify I do the right thing. (Ideally, someone who'll also write the code... I promise to show how.)
+
+In other news, B-trees are surprisingly interesting.


Added a comment: Heh
=== added file 'posts/tech-travel-cable-management/comment_2_72f5f3eacc4b98eb25319b6bd31328a3._comment'
--- posts/tech-travel-cable-management/comment_2_72f5f3eacc4b98eb25319b6bd31328a3._comment      1970-01-01 00:00:00 +0000
+++ posts/tech-travel-cable-management/comment_2_72f5f3eacc4b98eb25319b6bd31328a3._comment      2010-02-16 11:14:47 +0000
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="Heh"
+ date="2010-02-16T11:14:46Z"
+ content="""
+liwtopia is a weird place. You're welcome to visit. :)
+"""]]


Added a comment: "strangled to death"
=== added directory 'posts/tech-travel-cable-management'
=== added file 'posts/tech-travel-cable-management/comment_1_55b7cd32783dd0400602e0f7d5f15411._comment'
--- posts/tech-travel-cable-management/comment_1_55b7cd32783dd0400602e0f7d5f15411._comment      1970-01-01 00:00:00 +0000
+++ posts/tech-travel-cable-management/comment_1_55b7cd32783dd0400602e0f7d5f15411._comment      2010-02-16 10:08:01 +0000
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://wo.uter.be/"
+ subject="&quot;strangled to death&quot;"
+ date="2010-02-16T10:08:00Z"
+ content="""
+I think you'll find you can't be waking up if your cables have strangled you to death.
+
+But hey, I don't know what the laws of physics are in liwtopia. For all I know, you could.
+
+(yeah, I just want to be an asshole ;-P )
+"""]]


no message given
=== added file 'posts/tech-travel-cable-management.mdwn'
--- posts/tech-travel-cable-management.mdwn     1970-01-01 00:00:00 +0000
+++ posts/tech-travel-cable-management.mdwn     2010-02-05 06:45:12 +0000
@@ -0,0 +1,29 @@
+[[!meta title="Cable management while travelling"]]
+[[!tag travel idea]]
+
+We're travelling and we have several electronic devices
+with us. This means we have many cables. Cables are difficult
+enough at home, but especially so while travelling.
+
+My current best approach is to put each cable in a small
+clear plastic bag (zip lock bag, I think they're called). This
+prevents the cables from getting entangled, but there's so
+many of them that it's still hard to keep them in order.
+
+I wonder if it would be possible to develop a better solution?
+My best idea so far is a long piece of fabric with pieces of
+velcro sewn into it. The velcro would be located so that it
+would be possible to neatly put each cable in place and then
+roll the whole piece of fabric into a neat roll.
+
+When it would be time to get a cable, one would unroll the
+fabric, and then unfasten one or two pieces of velcro to
+get the cable.
+
+Perhaps pockets instead of velcro?
+
+Anyone have better ideas? Anyone have an actual solution?
+I live in mortal dread of waking up one morning and learning
+that my cables have started to breed, and have decided to
+overthrow their master, and have strangled me to death
+while I slept.


no message given
=== added file 'posts/computer-driving-license.mdwn'
--- posts/computer-driving-license.mdwn 1970-01-01 00:00:00 +0000
+++ posts/computer-driving-license.mdwn 2010-02-04 22:58:51 +0000
@@ -0,0 +1,15 @@
+[[!meta title="Computer driving licenses"]]
+[[!tag freedom politics rant]]
+
+
+Various countries have a training programme called the "computer
+driving license". The training aims to give basic computer using skills
+(word processing, spreadsheets, the web, etc). It's good for people
+unsure of their skills, but I object to the name.
+
+I think it's worrying that it's called a license of any kind, since that
+implies that there is an entity whose permission people
+need to use a computer. Licenses to own and operate copying machines or
+typewriters have existed, and it's always a sign of political
+oppression. It's just a word, but words have power, or at least they
+give leverage to those in power.


Added a comment: Deduping
=== added file 'posts/obnam-store-outline/comment_3_f83c66b1f46b14b62f96a34eb00bcae8._comment'
--- posts/obnam-store-outline/comment_3_f83c66b1f46b14b62f96a34eb00bcae8._comment       1970-01-01 00:00:00 +0000
+++ posts/obnam-store-outline/comment_3_f83c66b1f46b14b62f96a34eb00bcae8._comment       2010-02-02 03:57:18 +0000
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://rogerbinns.com/"
+ subject="Deduping"
+ date="2010-02-02T03:57:18Z"
+ content="""
+I've worked on deduping products (network based, not storage).  The way they work is to have a hash function which you apply over a range of data.  To catch shifts in data (insertions, deletions) you calculate hashes over multiple overlapping ranges.  You can also do it for multiple sizes (eg 16kb, 8kb, 1kb).  We went right down to 32 bytes!  The interesting part is that you discard most of the hashes calculated.  For example we discarded any that did not end in some number of trailing zeroes.  This makes storing the hashes smaller since you don't need to store the trailing zeroes while still having enough to provide useful deduping.
+
+There is a tradeoff between how many times you calculate a hash over a range of data and the resulting deduplication efficiency.  (Network has it somewhat easy as the largest chunk of data at once is the size of an ethernet frame, but then also has real time-ish requirements.)  If you design your hash function well you can have multiple output values as you roll through the data.  (Note that you do not need to use this hash in the storage system - a strong sha can be used - the point is to find potential duplicates quickly.)
+
+Somewhat surprisingly we also had the benefit of gzip style compression.  Data is effectively a list of intertwined hashes and literals and gzip on that output gave about another 50% compression much of the time.
+"""]]


Added a comment
=== added file 'posts/obnam-store-outline/comment_2_9d807f449a838d70db6df0e8aa0292f3._comment'
--- posts/obnam-store-outline/comment_2_9d807f449a838d70db6df0e8aa0292f3._comment       1970-01-01 00:00:00 +0000
+++ posts/obnam-store-outline/comment_2_9d807f449a838d70db6df0e8aa0292f3._comment       2010-02-01 05:31:29 +0000
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="comment 2"
+ date="2010-02-01T05:31:28Z"
+ content="""
+I've only looked at it a little, but it seems to me that git's object store isn't suitable for use in encrypted environments or when the bandwidth between the app and the store is very limited.
+"""]]


Added a comment: Sounds like the Git object store
=== added directory 'posts/obnam-store-outline'
=== added file 'posts/obnam-store-outline/comment_1_e89f9723e2fdec771b1ba5282eb61f3f._comment'
--- posts/obnam-store-outline/comment_1_e89f9723e2fdec771b1ba5282eb61f3f._comment       1970-01-01 00:00:00 +0000
+++ posts/obnam-store-outline/comment_1_e89f9723e2fdec771b1ba5282eb61f3f._comment       2010-02-01 05:00:27 +0000
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://madduck.net/"
+ subject="Sounds like the Git object store"
+ date="2010-02-01T05:00:27Z"
+ content="""
+It sounds like you are re-implementing the object store on which the [Git](http://git-scm.com/) version control system is built...
+
+PS: your ikiwiki does not allow Unicode in comments.
+"""]]


no message given
=== added file 'posts/obnam-store-outline.mdwn'
--- posts/obnam-store-outline.mdwn      1970-01-01 00:00:00 +0000
+++ posts/obnam-store-outline.mdwn      2010-02-01 03:56:40 +0000
@@ -0,0 +1,210 @@
+[[!meta title="Obnam storage API"]]
+[[!tag obnam]]
+
+The central data structure in Obnam is the way it stores backed up 
+data on disk.
+This is the area I have struggled with most in the four years I've been
+sporadically developing Obnam.
+
+My **initial attempt** was roughly this: everything was put in the backup
+store as a sort of object, which I'll call backup object. This included file 
+contents, deltas between
+versions of a file, file metadata, and filenames. While the representation
+was quite different, essentially each of these objects was a list of
+key-value pairs:
+
+    file:
+        id = 12765
+        basename = "/home/liw/foobar/foobar.c"
+        st_mtime = 32
+        contref = 42
+    
+    contents:
+        id = 42
+        data = "/* foobar.c -- a program to make foo do bar */\n..."
+    
+    generation:
+        id = 105
+        file = "/home/liw/foobar/foobar.c", 12765
+        file = "/home/liw/foobar/README", 32765
+        ...
+
+Each generation consists of a list of filenames and pointers to the
+object that represents the version of the file in that generation. If a
+file has not changed from generation to generation, the pointer (and
+thus the file contents) from the previous generation is reused.
+
+This was pretty simple, but it repeated the entire list of files, 
+with names for each generation. The filenames take a surprising amount 
+of space. Some statistics from my laptop:
+
+    Number of files: 401509
+    Basenames: 6 MiB
+    Pathnames: 27 MiB
+
+It is ridiculous to store the full list of files (whether basenames or
+pathnames) for each generation. Even just the basenames will use more
+than a typical delta between each backup run, for me. This is clearly not
+acceptable.
+
+After I realized this, I set to fix this by storing 
+**only changed filenames.** I got this to work, but for various reasons 
+it was very slow, and the complexity of the code made it hard to improve. 
+
+Instead of using a pathname as an index to a hashtable, as before, I was 
+now building a duplicate of the filesystem's directory tree in my backup 
+store. Each directory and file was represented by by a backup object,
+and the generation only held a list of root objects (essentially, the
+root directory).
+
+When making a new backup, I would carefully do an update from the bottom
+of the filesystem directory tree upwards, doing copy-on-write updates on
+any backup objects that had changed since the previous backup. While this
+is reasonably straightforward to do, it made the code unnecessarily
+complicated. The code to do backups had to worry about functional
+updates to trees, which really isn't its business.
+
+The fundamental cause for this misplaced complexity was that the backup
+store API was using object identifiers as keys, whereas backups (and
+restores and other operations) really want to handle filenames.
+
+My current approach in the second complete rewrite is to
+**return to pathname based indexing**, but keep the copy-on-write
+behavior. I do not yet know how I will implement this, but I do know
+I need to keep all the complexity inside the backup store implementation.
+Right now I am concentrating on finding the best API for the store so
+that the rest of the program will be easy to write.
+
+It's important that the API be non-tedious to use. There's a lot of
+room for exploration in backups for what to back up and when, and in
+which order. There's even further room for exploration in doing stuff
+with backed up data: verification, FUSE filesystems, etc. If the store
+API is tedious, it'll be harder to do all those nice things. If it is
+easy, they'll be that much easier to do.
+
+I have hacked up a first draft of the store API. Before I discuss it,
+I'll give outlines of how the backup is coded, in pseudo-Python:
+
+    def backup(directories):
+        for each directory:
+            backup_directory(directory)
+            
+    def backup_directory(dirname):
+        for each file directory:
+            backup_file(filename)
+        backup_metadata(dirname)
+        
+    def backup_file(filename):
+        if file has changed:
+            backup_file_contents(filename)
+            backup_metadata(filename)
+
+    def backup_file_contents(filename):
+        for each chunk in file:
+            if chunk exists in store already:
+                remember its id
+            else:
+                put chunk into store and remember new id
+        set chunk ids for filename
+    
+    def backup_metadata(pathname):
+        read metadata from filesystem
+        put metadata into store
+    
+That's about as straightforward as one can imagine. The store
+API is starting to emerge (semi-real-Python):
+
+    class Store:
+    
+        def create(self, pathname):
+        def set_metadata(self, pathname, metadata):
+        def set_file_chunks(self, pathname, chunkids):
+        def find_chunk(self, data):
+        def put_chunk(self, data):
+
+However, this is not quite ready yet. There is, for example, no
+concept of generations. After some playing around and discussions
+with Richard Braakman, I've ended up with the following approach.
+
+A new generation is initially created as a clone of the previous
+generation (or empty, if it is the first generation). The new clone
+can be modified, in a copy-on-write fashion, and when all changes
+are done, they can be committed into the store. After that, the
+generation is immutable, and cannot be changed anymore.
+
+This results in small changes to the main backup routine:
+
+    def backup(directories):
+        start new generation
+        for each directory:
+            backup_directory(directory)
+        commit started generation
+
+And a couple of new methods to the Store class:
+
+    def start_generation(self):
+    def commit_generation(self):
+
+Backups will now work reasonably efficiently, yet the code is simple.
+The complexity is all nicely hidden in the Store class.
+
+Restoring should also be easy:
+
+    def restore():
+        restore_directory(generation_id, '/')
+        
+    def restore_directory(genid, dirname):
+        create target directory on output filesystem
+        for each item in the directory in the generation in the store:
+            if it is a directory:
+                restore_directory(genid, sub-directory name)
+            else:
+                restore_file(genid, full pathname to file)
+        restore target directory metadata
+
+    def restore_file(genid, filename):
+        for each chunk in file:
+            read chunk
+            write to output file
+        restore file metadata
+
+The store API needs a couple of new things:
+
+    def listdir(self, genid, dirname):
+    def get_metadata(self, genid, pathname):
+    def get_file_chunks(self, genid, filename):
+    
+There's a little bit more to it to handle hardlinks, symlinks, and
+other special cases, but this is basically what the API will now
+look like.
+
+I have imlemented a proof-of-concept version of the API to allow
+me to play with it, and see what the rest of the code would look like.
+I am still assuming that using something like the funcational B-trees
+in btrfs will be a good way to implement it properly, but the API is
+not assuming that, I hope. (The code is slightly different from the
+above snippets. If you want to have look at the actual code,
+`bzr get http://code.liw.fi/obnam/bzr/rewrite4/` will get you a copy.)
+
+So far, I am happy with this. There's a whole bunch of questions 
+remaining that I will get to. Right now the thing that worries me
+most is finding chunks in the backup store: can I implement it
+efficiently enough that it will be useful. Some version of this
+will need to be done, so that I can de-duplicate data in the
+filesystem. For example, if I move a ISO file to a new place and
+make some small changes to it, it would be disastrous if I had to
+back it up completely, even though almost all data is already in

(Diff truncated)
no message given
=== modified file 'posts/lca2010-rest.mdwn'
--- posts/lca2010-rest.mdwn     2010-01-26 07:33:33 +0000
+++ posts/lca2010-rest.mdwn     2010-01-30 01:56:48 +0000
@@ -1,5 +1,5 @@
 [[!meta title="LCA, rest of the week"]]
-[[!tag lca2010]]
+[[!tag conference lca2010]]
 
 Tuesday: Gabriella Coleman's keynote about the origins and impact of
 the free software and hacker communities on the rest of the world


no message given
=== added file 'tag/conference.mdwn'
--- tag/conference.mdwn 1970-01-01 00:00:00 +0000
+++ tag/conference.mdwn 2010-01-30 01:52:33 +0000
@@ -0,0 +1,3 @@
+This tag is for blog posts that are about conferences.
+
+[[inline archive=yes pages="link(tag/conference)"]]


no message given
=== modified file 'posts/lca2010-rest.mdwn'
--- posts/lca2010-rest.mdwn     2010-01-26 07:31:00 +0000
+++ posts/lca2010-rest.mdwn     2010-01-26 07:33:33 +0000
@@ -37,7 +37,10 @@
 Penguin dinner in the evening was a disappointment from my point
 of view. Too many people, too much noise, I did not hear much and 
 was slightly miserable. I should learn some day that I do not thrive
-in noisy crowds.
+in noisy crowds. I did, however, draw a penguin on my phone
+while there.
+
+[[penguin.png]]
 
 Saturday: LCA Open Day, talked to a bunch of people from companies,
 handed out my business card. A company called Lucid is doing a


attachment upload
=== added file 'posts/lca2010-rest/penguin.png'
Binary files posts/lca2010-rest/penguin.png     1970-01-01 00:00:00 +0000 and posts/lca2010-rest/penguin.png    2010-01-26 07:33:00 +0000 differ

no message given
=== modified file 'posts/lca2010-rest.mdwn'
--- posts/lca2010-rest.mdwn     2010-01-26 07:30:10 +0000
+++ posts/lca2010-rest.mdwn     2010-01-26 07:31:00 +0000
@@ -46,5 +46,5 @@
 
 [[reprap.jpg]]
 
-Also, saw a RepRap. Stunningly cool. A glimpse of the
+Also, saw a [RepRap](http://en.wikipedia.org/wiki/RepRap). Stunningly cool. A glimpse of the
 future.


no message given
=== modified file 'posts/lca2010-rest.mdwn'
--- posts/lca2010-rest.mdwn     2010-01-26 07:24:40 +0000
+++ posts/lca2010-rest.mdwn     2010-01-26 07:30:10 +0000
@@ -46,4 +46,5 @@
 
 [[reprap.jpg]]
 
-Also, saw a RepRap. Stunningly cool.
+Also, saw a RepRap. Stunningly cool. A glimpse of the
+future.


attachment upload
=== added file 'posts/lca2010-rest/reprap.jpg'
Binary files posts/lca2010-rest/reprap.jpg      1970-01-01 00:00:00 +0000 and posts/lca2010-rest/reprap.jpg     2010-01-26 07:29:31 +0000 differ

attachment upload
=== added directory 'posts/lca2010-rest'
=== added file 'posts/lca2010-rest/fenwick.jpg'
Binary files posts/lca2010-rest/fenwick.jpg     1970-01-01 00:00:00 +0000 and posts/lca2010-rest/fenwick.jpg    2010-01-26 07:28:45 +0000 differ

no message given
=== added file 'posts/lca2010-rest.mdwn'
--- posts/lca2010-rest.mdwn     1970-01-01 00:00:00 +0000
+++ posts/lca2010-rest.mdwn     2010-01-26 07:24:40 +0000
@@ -0,0 +1,49 @@
+[[!meta title="LCA, rest of the week"]]
+[[!tag lca2010]]
+
+Tuesday: Gabriella Coleman's keynote about the origins and impact of
+the free software and hacker communities on the rest of the world
+was wonderful. Missed other
+talks, feeling very "shell shocked" and maybe culture
+shocked, and not really wanting to talk to people or hear
+people talk. Did see Blackheath's Haskell talk, which was a basic
+overview of Haskell features.
+
+Wednesday: Mako Hill's keynote was very inspiring. Concepts of
+autonomy and anti-features are good. Matthew Garrett's
+"Making yourself popular" talk was good, though perhpas a bit
+shallow. JobsBOF was a washout for me, nothing interesting there. 
+Roger Fenwick's "World's worst inventions" was funny.
+
+[[fenwick.jpg]]
+
+(The above photo is rather bad. Sorry. I did not feel like carrying
+around with a real camera so I made do with the phone's.)
+
+Thursday: Glyn Moody's keynote quite exceptionally good. He's one
+of my favorite two IT journalists. (The other one, Jon Corbet, was also
+at LCA, though I missed his talk and failed to talk to him.)
+Skipped the rest of the
+conference day, as Soile and I went and opened bank accounts
+and shopped for a car.
+
+Friday: Lighting talks were ok, it's a good concept. Photo management BOF not
+too exciting, but interesting to hear that most people think tagging
+is too much work to be practical. I might want to make Dimbola be
+really good at that. Martin Krafft was late for the
+DebianBOF so I chaired/secretaried it. Lots of discussions, I almost
+felt it was my crowd still.
+
+Penguin dinner in the evening was a disappointment from my point
+of view. Too many people, too much noise, I did not hear much and 
+was slightly miserable. I should learn some day that I do not thrive
+in noisy crowds.
+
+Saturday: LCA Open Day, talked to a bunch of people from companies,
+handed out my business card. A company called Lucid is doing a
+backup program called LBackup, free software, I might want to
+collaborate with them, given my continued interest in Obnam.
+
+[[reprap.jpg]]
+
+Also, saw a RepRap. Stunningly cool.


Added a comment
=== added file 'posts/obnam-cli/comment_2_e9d36089fbea10bdd6f90a32fbc22901._comment'
--- posts/obnam-cli/comment_2_e9d36089fbea10bdd6f90a32fbc22901._comment 1970-01-01 00:00:00 +0000
+++ posts/obnam-cli/comment_2_e9d36089fbea10bdd6f90a32fbc22901._comment 2010-01-19 03:22:31 +0000
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="comment 2"
+ date="2010-01-19T03:22:30Z"
+ content="""
+Verify: yeah, many ways of choosing what data to verify is going to be needed. My code already has plugin and hook systems, and I'll make it possible to extend the verification to pretty much anything, just in case my own ideas aren't universal.
+
+Permission problems: failure to back up or verify something because of permissions need to be treated as a failure.
+
+inotify/dnotify: certainly. I have no idea yet what is going to be the best way of using them, but they're certainly on the roadmap (or would be, if I had time to write the roadmap down).
+
+Deduping/redundancy in the backup store: I could be talked into making it configurable how much de-duping needs doing. For my own needs, I would rather solve it by having backups of backups. I'm also thinking of having a plugin that adds some error correcting codes to the backup store.
+
+
+"""]]


no message given
=== added file 'posts/lca2010-monday.mdwn'
--- posts/lca2010-monday.mdwn   1970-01-01 00:00:00 +0000
+++ posts/lca2010-monday.mdwn   2010-01-18 05:22:59 +0000
@@ -0,0 +1,56 @@
+[[!meta title="LCA2010 Monday"]]
+[[!tag conference lca2010]]
+
+I'm at the the [LCA2010](http://www.lca2010.org.nz/) 
+conference in Wellington.
+Today was the first day, with miniconfs.
+A few notes:
+
+* [Stephen Blackheath: Haskell, and all the wonderful things it doesn’t let you do](http://blogs.tucs.org.au/oplm/programme/#haskell). An overview talk of what Haskell is all about.
+  I really need to get back to reading the Real World Haskell book.
+* [Kate Stewart: Sharing Package Copyright and Licensing Data Effectively](https://fossbazaar.org/content/lca-devbiz-january-2010#stewart). An overview of the dilemma a distributor
+  of free software stuff faces: copyright and license info has no
+  markup language, and indeed is often out of date, which causes some
+  legal risk. Fossbazaar.org and others are trying to come up with a
+  format that everyone can use and that hopefully most people from
+  upstreams to Linux distros to others will adopt.
+  [DEP5]() was mentioned.
+* Lana Brindley: Creating Beautiful Documentation. The time slot had been shortened,
+  but good stuff anyway. While I haven't personally done much documentation
+  writing since leaving the Linux Documentation Project in 1997,
+  apart from a manual page every now and then, I agree with Brindley
+  that good documentation is an important factor in a successful
+  project. Tech writers and graphical artists are sorely needed,
+  as is shaping projects so that coders are no longer kings.
+* Scott James Remnant: Cutting down boot times. 
+  Missed this talk, but that's OK, Scott seems
+  to have missed it, too, due to travel.
+* [Carl Worth: Cairo Graphics - Intro and Future thoughts](http://libregraphicsday.org/proposal/79/cairo-graphics-intro-and-future-thoughts). Another overview talk. I know very little about Cairo,
+  but at least I now know where it stands in the stack. I should perhaps
+  look into using it for [Dimbola](http://dimbola.org). If only I knew
+  any graphics programming.
+  
+The conference venue works well, except for occasional wireless
+problems.
+
+Attempted to see how long my X200s battery actually lasts, and I managed
+to get through the day without charging. When I left the hotel, the
+battery was fully charged, and when I came back, there was an estimated
+15 minutes left. However, I didn't use the laptop all the time, and
+I can't figure out from the GNOME Power Manager how much battery time
+I've actually used up today. The history dialog is entirely
+incomprehensible to me.
+
+One thing that happens in conferences, including this LCA, is that
+people realize they've forgotten a cable or a charger or something,
+and someone else lends it to them. There's a bit of a shuffle for
+the lender and borrower to meet. I wonder if it would be too big a 
+hassle for the organizers to set up a "post office": the lender
+would bring the cable, or whatever, put it in a bag, put their own
+name and the borrower's name on the bag, and then give it to the
+reception people to keep. The borrower could then fetch if from the
+reception whenever is suitable. Maybe this would be too much work
+and responsibility for the organizers, who are overworked as it is.
+
+The weather is pretty nice. Some rain occasionally, but lots of
+sunshine, too. Pretty warm. People are very friendly.


Added a comment: Verify, notify and duping
=== added directory 'posts/obnam-cli'
=== added file 'posts/obnam-cli/comment_1._comment'
--- posts/obnam-cli/comment_1._comment  1970-01-01 00:00:00 +0000
+++ posts/obnam-cli/comment_1._comment  2010-01-18 04:21:49 +0000
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://rogerbinns.com/"
+ subject="Verify, notify and duping"
+ date="2010-01-18T04:21:48Z"
+ content="""
+For verify, I'd presume some sort of random choice by age grouping (ie covering older files, middle aged files and new ones) as well as by a variety of different directories would help.  Maybe you just tell the tool the maximum amount of time/data transfer to spend on verification and off it goes?  One gotcha I have seen with backups is permissions problems.  You run the backup as an ordinary user (its using your ssh keys etc) and don't notice that it failed to pickup some files maybe because it didn't complain or maybe because it does complain about many permissions problems so you don't see what you care about in the noise.  Then later you discover hat actually /etc/shadow or /var/lib/couchdb would have been nice to have been backed up.
+
+Have you considered a i/dnotify style listener?  Instead of remembering to schedule backups, you leave the tool running pointed at a set of directories you care about, it automatically picks up changed files and backs them up in the near future.  (You could obviously also do this with a separate unrelated monitor program repeated invoking the command line.  I have no idea which approach is better.)
+
+On the deduping side one problem is that some files are more important to me than others.  Not only do I want the contents backed up, but I want the backup to be able to survive some number of failures of the backup data for that file.  For example I'd want to ensure that there is deliberate duplication of the blocks making up some directories (tax returns, password lists, ssh/pgp stuff) so that a single bad sector on the backup server doesn't lose what is most important to me.
+"""]]


no message given
=== added file 'posts/collaborative-voted-storytelling.mdwn'
--- posts/collaborative-voted-storytelling.mdwn 1970-01-01 00:00:00 +0000
+++ posts/collaborative-voted-storytelling.mdwn 2010-01-17 22:24:49 +0000
@@ -0,0 +1,10 @@
+[[!meta title="Collaborative storytelling with audience voting"]]
+[[!tag idea]]
+
+As I'm reading [Cory Doctorow's](http://craphound.com/)
+[Makers](http://craphound.com/makers/) novel, I can't help
+wondering whether it might be possible to write a novel 
+collaboratively. Each participant would write a paragraph per
+day, and readers could vote paragraphs up and down. It might
+be interesting to see if a coherent story would eventually
+emerge.


no message given
=== added file 'posts/obnam-cli.mdwn'
--- posts/obnam-cli.mdwn        1970-01-01 00:00:00 +0000
+++ posts/obnam-cli.mdwn        2010-01-17 07:43:20 +0000
@@ -0,0 +1,39 @@
+[[!meta title="Obnam command line interface"]]
+[[!tag obnam]]
+
+I have some specific ideas for the command line interface I'm planning 
+for my backup program.
+I'll be writing a man page for obnam, but before I do that, here's
+a sketch.
+
+* `obnam backup --store sftp://example.com/~/backups/ $HOME`
+* `obnam ls --generation latest`
+* `obnam verify`
+* `obnam fsck`
+* `obnam restore --generation latest --to /var/tmp/liw.restore`
+* `òbnam forget --keep 1h:7d:5w:12m:99y`
+
+The **backup** command should be obvious. I'll make a configuration
+file so the location of the backup store can be specified there, rather
+than every time on the command line. Also other arguments, such as
+the directories to back up.
+
+The **ls** command lists the contents of a backup generation.
+
+The **verify** command compares what has been backed up with what is
+on the hard disk now, reporting differences. If you back up and then
+immediately verify, you can check that everything got backed up.
+Verify will also be able to do things like compare randomly selected
+files (rather than all of them). I am not yet sure exactly how the
+verification process should happen to make things trustable.
+
+**fsck** checks that the internal data structures in the backup store
+are OK.
+
+**restore** restores.
+
+**forget** removes old backup generations. It will be able to remove
+specific generations, or apply a policy such as "keep one hour, seven
+daily, five weekly, twelve monthly, and lots of yearly generations".
+It will be cheap to keep lots of generations, since obnam will do
+heavy de-duplication, at the block level.


Added a comment: bzr format docs?
=== added file 'posts/obnam-once-again/comment_4._comment'
--- posts/obnam-once-again/comment_4._comment   1970-01-01 00:00:00 +0000
+++ posts/obnam-once-again/comment_4._comment   2010-01-12 09:01:22 +0000
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ subject="bzr format docs?"
+ date="2010-01-12T09:01:22Z"
+ content="""
+@lifeless: is there high-level documentation for the 2a format? I've seen one presentation by you on it, and that was inspiring to me for a previous incarnation of obnam, but didn't seem like it would let me easily re-use chunks of data from any version of any file from any host using the same backup store. Also, I'd like to know if the bzr format would work well with encryption.
+"""]]


Added a comment: bzr's 2a format
=== added file 'posts/obnam-once-again/comment_3._comment'
--- posts/obnam-once-again/comment_3._comment   1970-01-01 00:00:00 +0000
+++ posts/obnam-once-again/comment_3._comment   2010-01-12 05:28:21 +0000
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~lifeless"
+ subject="bzr's 2a format"
+ date="2010-01-12T05:28:20Z"
+ content="""
+Has many of the internal properties you'd need. It has some extra data, so I wouldn't use it as-is.
+"""]]


Added a comment
=== added file 'posts/obnam-once-again/comment_2._comment'
--- posts/obnam-once-again/comment_2._comment   1970-01-01 00:00:00 +0000
+++ posts/obnam-once-again/comment_2._comment   2010-01-11 08:52:01 +0000
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://liw.fi/"
+ date="2010-01-11T08:52:01Z"
+ content="""
+I don't actually find it particularly relevant what the dependencies are for restoring data, but anyway, the dependencies will be the same as for backup: python, paramiko, gpg. The reason the dependencies are not that relevant is that if you can boot off a live-cd, dependencies are easy to fulfill, and I would not be stupid enough to require particular hardware (64-bit in your example).
+
+Validation falls under reliability.
+
+De-duplication falls under \"fast\". If a chunk of data has already been backed up, in another file or by another computer, then it obviously should not have to be uploaded again.
+
+Any number of computers will of course work.
+"""]]


Added a comment: Some more concerns
=== added directory 'posts/obnam-once-again'
=== added file 'posts/obnam-once-again/comment_1._comment'
--- posts/obnam-once-again/comment_1._comment   1970-01-01 00:00:00 +0000
+++ posts/obnam-once-again/comment_1._comment   2010-01-11 08:16:44 +0000
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://rogerbinns.com/"
+ subject="Some more concerns"
+ date="2010-01-11T08:16:43Z"
+ content="""
+You need to consider restoring and testing.  For example what are the dependencies of the restore program - will it run on any recent Linux LiveCD or do you have to have a bazillion libraries installed and only the latest 64bit Ubuntu?  Is there some sort of simple integration possible with Nautilus?
+
+For testing, at some point you want to validate your backups, probably by pointing to a backup and to a local machine and have the test tell you how they diverge.
+
+You also haven't mentioned what should be done about multiple machines (ie if you want to backup more than one).  Using block hashes (see recent postings about ZFS deduplication settings) it becomes a lot cheaper to backup multiple machines into the same space since they will have many blocks the same. And once you consider laptops, desktops, servers, virtual machines etc you soon find you have a lot of \"computers\" and it would be great to be able to back them all up conveniently.
+"""]]


no message given
=== added file 'posts/obnam-once-again.mdwn'
--- posts/obnam-once-again.mdwn 1970-01-01 00:00:00 +0000
+++ posts/obnam-once-again.mdwn 2010-01-11 05:05:23 +0000
@@ -0,0 +1,48 @@
+[[!meta title="Obnam, or once more a backup program"]]
+[[!tag obnam]]
+
+I've decided to resurrect development of my backup program,
+Obnam. This time I thought I'd babble about it in public as I
+develop it, rather than try to present the world with a finished
+product.
+
+I have not been happy with any backup solution I've tried. I have
+some fairly specific requirements:
+
+* Backups must be stored either on a local hard disk, or online.
+  I don't care at all about tapes, optical media, or anything else
+  that requires repetitive manual work.
+* Server end must be under my control as well. No Amazon S3 for me.
+* Both push and pull backups.
+* Backups must be encrypted at client end.
+* Backups must be incremental, but each generation must look like a full
+  snapshot.
+* Backups must use checkpoints: network connections break, and if they do,
+  the next backup must continue from most recent checkpoint.
+* Setup must be easy. Backups are important, but if they're at all any
+  kind of pain, I and most others will just postpone them to a future
+  day and one day it will be too late.
+* Fast. If I do some e-mail and write some code while drinking a smoothie
+  in a net cafe, by the time I finish the drink and put away the laptop
+  the backup must be finished.
+* Deals sensibly both with slow and fast networks. An incremental backup
+  should not download any data from server, and should only upload the
+  delta from the previous backup, plus minimal overhead.
+* Reliable. Backups should not require attention. I should just be allowed
+  to assume they work. This also requires unobtrusive feedback that they're
+  OK, and proper error reporting when something is wrong and does require
+  my attention.
+
+It's been a while since I did a proper survey, so things may have changed
+since, but so far, I've never found a system that I like. If you know of
+one, please don't tell me. I am now deep into thinking about the technical
+problems I will need to solve, and not that interested in finding an
+existing solution anymore.
+
+If "hubris" was spelled with an i, it would be my middle name.
+
+I have some code sketched out, but nothing that does anything useful
+yet. I've been playing with the internal architecture, and the interface
+and abstraction I will want for the "storage subsystem" that stores
+the backed up data. I have not decided yet how to implement the
+storage subsystem, but btrfs B-trees interest me a lot.


no message given
=== modified file 'sidebar.mdwn'
--- sidebar.mdwn        2008-05-06 20:37:04 +0000
+++ sidebar.mdwn        2010-01-08 15:29:19 +0000
@@ -16,3 +16,9 @@
 [The Simple Dollar](http://www.thesimpledollar.com/)
 [Taijamai](http://taijamai.blogspot.com/)
 [Unclutterer](http://unclutterer.com/)
+
+<hr />
+
+All content outside of comments is copyrighted by
+Lars Wirzenius, and licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0 Unported License</a>.
+Comments are copyrighted by their authors.


Remove !
=== modified file 'index.mdwn'
--- index.mdwn  2010-01-06 17:45:01 +0000
+++ index.mdwn  2010-01-06 17:48:47 +0000
@@ -8,5 +8,5 @@
 [[inline pages="posts/* and !posts/*/*"]]
 
 
-[[!edittemplate template="posttemplate" match="posts/* and !posts/*/*"
+[[edittemplate template="posttemplate" match="posts/* and !posts/*/*"
    silent=yes]]


Added a post template
=== added file 'posttemplate.mdwn'
--- posttemplate.mdwn   1970-01-01 00:00:00 +0000
+++ posttemplate.mdwn   2010-01-06 17:46:40 +0000
@@ -0,0 +1,2 @@
+[[!meta title=""]]
+[[!tag ]]


no message given
=== modified file 'index.mdwn'
--- index.mdwn  2009-08-11 08:45:38 +0000
+++ index.mdwn  2010-01-06 17:45:01 +0000
@@ -6,3 +6,7 @@
 also [identi.ca](http://identi.ca/liw).
 
 [[inline pages="posts/* and !posts/*/*"]]
+
+
+[[!edittemplate template="posttemplate" match="posts/* and !posts/*/*"
+   silent=yes]]


Added more space after ol list.
=== modified file 'style.css'
--- style.css   2010-01-06 17:39:00 +0000
+++ style.css   2010-01-06 17:42:24 +0000
@@ -148,7 +148,7 @@
     bottom: 0em;
 }
 
-#menu ul, #menu ol {
+#menu ul {
     list-style: none;
 }
 
@@ -193,7 +193,7 @@
     margin-left: 2em;
 }
 
-#main_inner ul {
+#main_inner ul, #main_inner ol {
     margin-bottom: 2.0em;
 }
 


Added more space after ol list.
=== modified file 'style.css'
--- style.css   2009-09-09 14:16:47 +0000
+++ style.css   2010-01-06 17:39:00 +0000
@@ -148,7 +148,7 @@
     bottom: 0em;
 }
 
-#menu ul {
+#menu ul, #menu ol {
     list-style: none;
 }