This last weeks, I've worked on implementing the Desktop Notification Specification into Emacs. It allows sending desktop notification in a very simple way.
(notifications-notify
:title "You've got mail!"
:body "There's 34 mails unread"
:app-icon "~/.emacs.d/icons/mail.png"
:urgency 'low)
It supports the protocol signals (NotificationClosed and ActionInvoked) and
the two main methods (Notify and CloseNotification).
The methods specification are implemented entirely (hints, replaces,
actions, icon, etc).
The signals are supported via callbacks function provided on the
notification creation.
It have been merged into Emacs trunk today.
2010-06-09 Julien Danjou <julien@danjou.info> * net/notifications.el: New file.This also allowed me to discover, raise and fix a bug in the D-Bus binding of Emacs, which will be probably fixed in trunk soon.
Early this morning I sent
Rcpp version 0.8.1
off to CRAN and
Debian. In the meantime,
Romain has already provided
a very nice blog post about
it.
There are a few fairly visible new things in this release. As we want to
focus the next few minor releases on completing the documentation, we started
by adding a total of four (!!) new vignettes:
0.8.1 2010-06-08
o This release adds Rcpp modules. An Rcpp module is a collection of
internal (C++) functions and classes that are exposed to R. This
functionality has been inspired by Boost.Python.
Modules are created internally using the RCPP_MODULE macro and
retrieved in the R side with the Module function. This is a preview
release of the module functionality, which will keep improving until
the Rcpp 0.9.0 release.
The new vignette "Rcpp-modules" documents the current feature set of
Rcpp modules.
o The new vignette "Rcpp-package" details the steps involved in making a
package that uses Rcpp.
o The new vignette "Rcpp-FAQ" collects a number of frequently asked
questions and answers about Rcpp.
o The new vignette "Rcpp-extending" documents how to extend Rcpp
with user defined types or types from third party libraries. Based on
our experience with RcppArmadillo
o Rcpp.package.skeleton has been improved to generate a package using
an Rcpp module, controlled by the "module" argument
o Evaluating a call inside an environment did not work properly
o cppfunction has been withdrawn since the introduction of the more
flexible cxxfunction in the inline package (0.3.5). Rcpp no longer
depends on inline since many uses of Rcpp do not require inline at
all. We still use inline for unit tests but this is now handled
locally in the unit tests loader runTests.R.
Users of the now-withdrawn function cppfunction can redefine it as:
cppfunction <- function(...) cxxfunction( ..., plugin = "Rcpp" )
o Support for std::complex was incomplete and has been enhanced.
o The methods XPtr<t>::getTag and XPtr<t>::getProtected are deprecated,
and will be removed in Rcpp 0.8.2. The methods tag() and prot() should
be used instead. tag() and prot() support both LHS and RHS use.
o END_RCPP now returns the R Nil values; new macro VOID_END_RCPP
replicates prior behabiour
As always, even fuller details are in
Rcpp Changelog page and the
Rcpp page which also
leads to the downloads, the
browseable
doxygen docs and zip files of doxygen output for the standard formats.
A local directory has
source and documentation too.
Questions, comments etc should go to the
rcpp-devel mailing list
off the R-Forge page
svn co svn://svn.valgrind.org/valgrind/trunk valgrind -r 11100cd valgrindwget -O - -q https://bug549749.bugzilla.mozilla.org/attachment.cgi?id=449748 patch -p0icegrind/ice_main.c, go on the last line of the track_mmap function and replace mmaps with dest_mmaps.mkdir icegrind/tests ; touch icegrind/tests/Makefile.amlibtoolize ; aclocal ; automake --add-missing ; autoreconf./configure; make
wget http://hg.mozilla.org/users/tglek_mozilla.com/startup/raw-file/6453ad2a7906/elflog.cppg++ -o elflog elflog.cpp -lelflibelf-dev package.make install ; install -m 755 elflog /usr/local/bin/usr/local.elflog --contents libxul.so > libxul.so.sectionsLD_LIBRARY_PATH=. valgrind --tool=icegrind ./firefox-bin -P my-profile -no-remote about:blank
DevOps
I first heard about DevOps from Lindsay Holmwood at linux.conf.au 2010. Since then, I ve been following the movement with interest. It seems to be about cross-functional involvement in software teams, specifically between software development and system administration (or operations). In many organizations, especially SaaS shops, these two groups are placed in opposition to each other: developers are driven to deliver new features to users, while system administrators are held accountable for the operation of the service. In the best case, they maintain a healthy balance by pushing in opposite directions, but more typically, they resent each other for getting in the way, as a result of this dichotomy:
| Development | Operations | |
|---|---|---|
| is responsible for | creating products | offering services |
| is measured on | delivery of new features | high reliability |
| optimizes by | increasing velocity | controlling change |
| and so is perceived as | reckless and irresponsible | obstructing progress |





















Apropos Matthew's
post...
I picked up a cheap netbook for Jo a couple of months ago, an Acer
Aspire One 751. She liked the look and feel of the machine, and it was
much smaller and more carryable than the massive old Dell "slab" she'd
been using previously. Got a very good deal on it
too, as it was the last one in stock at the local Comet store.
All went well until we got it home and I started playing with
it. That was when I found the painful truth: it was based on the
Poulsbo, using Intel's crippled GMA500 graphics chipset. Up until
then, I'd been very happy with buying Intel kit: for the last few
years it's been a sure sign that the hardware would work well with
Debian and Linux. Now they've come out with a crappy product that has
destroyed that goodwill. I spent many hours working through various
options to try and get this new netbook up and running properly using
Debian, but to no avail - the various binary blobs wanted newer
versions of code than was in Lenny and (by then) older stuff than was
available in Squeeze. In the end I gave up and installed an outdated
version of Ubuntu on the machine just so Jo could have it working for
her when we went on holiday together.
Since then, she's had to get used to the machine locking up once or
twice a day while she's using it (something I can only assume is
caused by the shitty drivers). She's happy enough in that
it's much better than her old Vista-infested Dell machine, but it's
really not a great experience for her compared to the Thinkpads she
sees others using reliably and flawlessly at home.
At some point I guess we'll simply ditch the machine altogether and
get something less nasty. Thanks for the good stuff you used to make,
Intel, but you've lost your way. I'll be damned careful next time to
avoid this trap.
The screenshot is featuring myself in Collabora's UK office
(top-left), Robert McQueen from a hotelroom in Taipei (top-right),
Will Thompson and Magical trevor also from the Collabora UK office
(bottom-left) and Mike Ruprecht from somewhere in Missouri. So we
were quite spread out over our little planet. Both audio and video
quality was quite good, even though the network in robs hotel was a
bit flaky from time to time.
In case you want to try it out have a look at the MujiDemoClient
page.
With sysvinit, these environment variables are set for the same script.DEFAULT_RUNLEVEL=2 previous=N PREVLEVEL= RUNLEVEL= runlevel=S UPSTART_EVENTS=startup UPSTART_INSTANCE= UPSTART_JOB=rc-sysinit
The RUNLEVEL and PREVLEVEL environment variables passed on from sysvinit are not set by upstart. Not sure if it is intentional or not to not be compatible with sysvinit in this regard. For scripts needing to behave differently when upstart is used, looking for the UPSTART_JOB environment variable seem to be a good choice.INIT_VERSION=sysvinit-2.88 previous=N PREVLEVEL=N RUNLEVEL=S runlevel=S
Today, I
launched a proposal for a string freeze in Debian Installer.
A string freeze is a formal agreement among developers to avoid
changing localizable material without concertation. This is a
commitment towards translators to guarantee them that, while they're
doing an effort to complete their work, this effort won't be broken by
a developer adding of modifying translatable material.
This can be seen as a first step towards the preparation of a release
of D-I. Indeed, the only release we did for Squeeze (D-I
alpha1 release) had no formal translation update round.
We currently have 45 languages that are considered to be "in good
shape" (even if not all complete) and very likely to remain activated
in Squeeze. However, 20 (TWENTY) languages are in danger of being
deactivated because of low activity.
To avoid this, I will once again take my superhero suit, add some
leather to it, take a whip and start nagging translators, doing noise
and, in short, annoying the entire world (including blogging too
often), in order to shake people enough so that we reduce this number
to zero. Be prepared.
Interesting links:
I was trying the last week to import data from one database into a Drupal database. Basically this worked fairly well. The needed fields from the old database are easy to get by simple SELECT statements. Because I don't know anything about PHP, I doing the export/import with a Python script directly into the database. After all this is about articles, comments and tags, that need to be imported into a Drupal database.
The articles will be stored into tables node_revisions, node and node_counter. The tags into tables term_data and term_node. Comments will go into table comments. Here are the INSERTs:
Articles:
"insert into node_revisions (uid, body, teaser, log, timestamp, format, nid, title) values ('3', '%s', '%s', '', '%s', '1', '%s', '%s')" % (body, body, timestamp, i, title)
"insert into node (vid, type, uid, status, created, changed, comment, promote, moderate, sticky, language, tnid, translate, title) values ('%s', 'blog', '3', '1', '%s', '%s', '2', '1', '0', '0', '', '0', '0', '%s')" % (vid, timestamp, timestamp, title)
"insert into node_counter (nid,totalcount,daycount,timestamp) values ('%s', '100', '0','%s')" % (nid, timestamp)
Tags:
"insert into term_data (vid, name) values ('3', '%s')" % tag
"insert into term_node (nid, vid, tid) values ('%s', '%s', '%s')" % (nid, vid, tagtid)
Comments:
"insert into comments (pid, nid, uid, subject, comment, hostname, timestamp, status, format, thread, name, mail, homepage) values ('%s', '%s', '0', '%s', '%s', '%s', '%s', '0', '1', '01', '%s', '%s', '%s')" % (parentid, nid, ctitle, cbody, cip, ctimestamp, cauthor, cemail, curl)
sql="insert into term_node (nid, vid, tid) values ('%s', '%s', '%s')" % (nid, vid, tid)
The import is successful as there are comments and tags attached to each article or node. But there are still some problems. When accessing Recent Posts there are no entries listed. Yet, Drupal still thinks there are so many articles that it lists more than 30 pages:
Something similar happens to the tags. The tags are actually assigned to and are displayed as well with the nodes. But when accessign taxonomys vocabular and trying to list the terms, the resulting page is empty:
If my understanding of the Drupal6 database (on PostgreSQL this is) is correct, everything should be fine and properly stored into the database. But apparently there's something missing. But what? As already mentioned I have no clue about PHP, so using node_api or any other API calls by Drupal/PHP is no option for me. Except when the calls can be placed via Pythons system() call.
If anyone has some tips or hints for me, I would appreciate when you write a comment.
When there's interest I can provide the entire Python import script. I'm going to make it public anyway, when the last problems are solved.
I was trying the last week to import data from one database into a Drupal database. Basically this worked fairly well. The needed fields from the old database are easy to get by simple SELECT statements. Because I don't know anything about PHP, I doing the export/import with a Python script directly into the database. After all this is about articles, comments and tags, that need to be imported into a Drupal database.
The articles will be stored into tables node_revisions, node and node_counter. The tags into tables term_data and term_node. Comments will go into table comments. Here are the INSERTs:
Articles:
"insert into node_revisions (uid, body, teaser, log, timestamp, format, nid, title) values ('3', '%s', '%s', '', '%s', '1', '%s', '%s')" % (body, body, timestamp, i, title)
"insert into node (vid, type, uid, status, created, changed, comment, promote, moderate, sticky, language, tnid, translate, title) values ('%s', 'blog', '3', '1', '%s', '%s', '2', '1', '0', '0', '', '0', '0', '%s')" % (vid, timestamp, timestamp, title)
"insert into node_counter (nid,totalcount,daycount,timestamp) values ('%s', '100', '0','%s')" % (nid, timestamp)
Tags:
"insert into term_data (vid, name) values ('3', '%s')" % tag
"insert into term_node (nid, vid, tid) values ('%s', '%s', '%s')" % (nid, vid, tagtid)
Comments:
"insert into comments (pid, nid, uid, subject, comment, hostname, timestamp, status, format, thread, name, mail, homepage) values ('%s', '%s', '0', '%s', '%s', '%s', '%s', '0', '1', '01', '%s', '%s', '%s')" % (parentid, nid, ctitle, cbody, cip, ctimestamp, cauthor, cemail, curl)
sql="insert into term_node (nid, vid, tid) values ('%s', '%s', '%s')" % (nid, vid, tid)
The import is successful as there are comments and tags attached to each article or node. But there are still some problems. When accessing Recent Posts there are no entries listed. Yet, Drupal still thinks there are so many articles that it lists more than 30 pages:
Something similar happens to the tags. The tags are actually assigned to and are displayed as well with the nodes. But when accessign taxonomys vocabular and trying to list the terms, the resulting page is empty:
If my understanding of the Drupal6 database (on PostgreSQL this is) is correct, everything should be fine and properly stored into the database. But apparently there's something missing. But what? As already mentioned I have no clue about PHP, so using node_api or any other API calls by Drupal/PHP is no option for me. Except when the calls can be placed via Pythons system() call.
If anyone has some tips or hints for me, I would appreciate when you write a comment.
When there's interest I can provide the entire Python import script. I'm going to make it public anyway, when the last problems are solved.
UPDATE:
Killes on IRC hinted me that node_comment_statistics and term_hierarchy needs to be filled as well. Thanks for the hint!


Above are three partial screen captures of Chrome, the first is when maximised and the second is when the window isn t maximised. Notice the extra vertical space above the tab in the title bar in the second picture. The third picture shows the right side of the titlebar and you can see a space below the three buttons where you can drag the window around no matter how many tabs you open that space below the three buttons is reserved. If the Chrome developers had removed the extra vertical space in the titlebar and reserved slightly more horizontal space then you would be able to drag the window around. While an anonymous commentator made a good point that the extra vertical space can be used to drag the window around when the maximum number of tabs are open, it seems that there are other ways of achieving that goal without wasting ~18 vertical pixels. Doing so would be a lot less ugly than what they did with finding text in the page.
When I visit a web site that uses cookies from an Incognito Window (which means that cookies etc aren t stored) there is no option to say allow all cookies . This is really annoying when you get to a web site such as the IBM one which stores 5 cookies when you first load the page and then at least one new cookie write for every page you visit. Given that cookie data will be discarded as soon as the window is closed it seems like a good idea to have an option to allow all cookies for Incognito Windows even if all cookies aren t allowed for regular windows. Blocking all cookies would be OK too, anything but having to click on Block or Allow multiple times for each page load.
The J and K keys don t work in a view of Venus version 0~bzr95-2+lenny1 (the latest version in Debian/Lenny).
I once had a situation where I entered a . at the end of a domain name (which is quite legal there is always an implied dot) and Chrome then wouldn t take note of my request to accept all cookies from the domain. I haven t been able to reproduce that bug, but I have noticed that it stores the settings for whether cookies should be stored separately for domains that end in . , so www.cnn.com. is different from www.cnn.com . Iceweasel seems to just quietly strip the trailing dot. Of course this is better than Konqueror which won t even load a URL with a dot at the end.
Chrome can be relied on to restore all windows rapidly after a crash, unlike Iceweasel which restores them at it s normal load speed (slow) and Konqueror which doesn t tend to restore windows. This is good as it does seem to crash regularly. In a response to my post about Chrome and SE Linux [1] Ben Hutchings pointed out that the --no-sandbox option to chrome disables the creation of a PID namespace and therefore makes debugging a lot easier, if I get a lot of spare time I ll try and track down some of the Chrome SEGVs.
The JavaScript compiler is either buggy or it s not buggy in situations where people expect IE bugs. When using the Dell Australia web site I can t always order all options. When trying to order a Dell R300 1RU server with hot-plug disks in a hardware RAID array it seems impossible to get all the necessary jumpers which is a precondition to completing the order fortunately I only wanted to blog about how cheap Dell servers are so I don t actually need to complete an order. Dell s web site is also difficult in Iceweasel on occasion, so it s obviously more demanding than most sites. It might be a good test site for people who work on browsers as it s both demanding and important.
When I select a URL to be opened in a new window (or when JavaScript does this) then the new tab is opened with about:blank listed as the URL. If the URL is for a PDF file (or something else that is to be downloaded) then the URL entry field is never updated to give the real URL. I believe that this is wrong, either the new tab shouldn t be opened or it should have the correct URL on display there is no benefit with a tab open to show nothing but about:blank in the URL entry field. Also if a URL takes some time to load then it may keep about:blank in the URL entry field for some time. This means that if you use the middle mouse button to rapidly open a few new tabs you won t be able to see what is to be loaded in each one. Sometimes I have several tabs loading and I m happy to close some unimportant ones if they are slow but some are worth waiting for.
Overall that s not too bad. I can use Dell s site in Iceweasel, so the only critical bug is the cookies issue in Incognito Windows which makes the Incognito feature almost unusable for some sites.
My project.
I m publishing my report earlier this week, because there was a lot to talk about. This week I started to make changes in the code going in the direction of what I want to do. I haven t started a final implementation, but I m studying about how what I want to do will affect the rest of the Garbage Collection (GC). I noticed the code in rts/sm/Sweep.c was simple and similar to what I m planning to do, so I started changing how it works.
Sweep in the Glasgow Haskell Compiler (GHC) is done by a bitmap, which contains a bit for each word in a memory block, and is set to 1 when there s an object starting in the mapped area and 0 otherwise. When there s a block with no objects starting at it, that is, all bits of the bitmap are set to 0, the block is freed.
if (resid == 0)
freed++;
gen->n_old_blocks--;
if (prev == NULL)
gen->old_blocks = next;
else
prev->link = next;
freeGroup(bd);
The bits are analyzed in a group of BITS_IN(W_), where BITS_IN(W_) is the number of bits in a word.
for (i = 0; i < BLOCK_SIZE_W / BITS_IN(W_); i++)
if (bd->u.bitmap[i] != 0) resid++;
If more than of the groups are completely set to 0, the block is considered fragmented.
if (resid < (BLOCK_SIZE_W * 3) / (BITS_IN(W_) * 4))
fragd++;
bd->flags = BF_FRAGMENTED;
Immix, the GC algorithm I plan to implement in GHC, divides the blocks of memory in lines. My initial plan was to identify free lines. I decided to consider a the size of a line fixed in BITS_IN(W_) words, because it will map to a word in the bitmap, and the code was already analyzing in groups of BITS_IN(W_) words. This was very easy with the current code.
if (bd->u.bitmap[i] != 0) resid++;
else printf("DEBUG: line_found(%p)\n", bd->start + BITS_IN(W_) * i);
This worked, and showed some free lines. I m sure there are other ways of logging in GHC, but printf was the simplest way I could thought of. I measured the occurrence of free lines using the bernouilli program from the NoFib benchmark suite, calling it with 500 +RTS -w, to make it uses sweep. In 782 calls to GarbageCollect(), sweep() was called 171 times, for 41704 blocks to be swept and found 230461 free lines. This gives us about 5.5 free lines per block, from the 8 lines in each block (on 64 bits systems).
The problem is that the bitmap is marked only in the start of the objects allocated, so even in a line that all bits are marked with 0 we can t assume that it s completely free, because there may be an object that starts in the previous line that is using the space of the line. Checking only for the previous line doesn t work either, because a big object can span several lines. What we can do here is a variation of conservative marking, as proposed in the Immix paper, checking only the previous line and working only with objects smaller than a line.
To make sure I was working only with objects smaller than a line, I had to mark the blocks that contains medium objects and avoid them when seeking free lines. The block flags are defined in includes/rts/storage/Block.h, so I included another flag in this file, BF_MEDIUM.
/* Block contains objects evacuated during this GC */ #define BF_EVACUATED 1 /* Block is a large object */ #define BF_LARGE 2 /* Block is pinned */ #define BF_PINNED 4 /* Block is to be marked, not copied */ #define BF_MARKED 8 /* Block is free, and on the free list (TODO: is this used?) */ #define BF_FREE 16 /* Block is executable */ #define BF_EXEC 32 /* Block contains only a small amount of live data */ #define BF_FRAGMENTED 64 /* we know about this block (for finding leaks) */ #define BF_KNOWN 128 /* Block contains objects larger than a line */ #define BF_MEDIUM 256The GHC GC is generational, there is, objects are allocated in a generation and, after a time, the ones that are still being used are moved the next generation. This idea assumes the death probability of younger objects is higher, so few objects are moved to the next generation. Sweep and Immix work only in the last generation so, to mark blocks with medium objects we have to check the size of the objects that are moved to the next generation. This is done in the copy_tag function of rts/sm/Evac.c. I inserted a code that checks for the object size and marks the block when it s bigger than BITS_IN(W_).
STATIC_INLINE GNUC_ATTR_HOT void
copy_tag(StgClosure **p, const StgInfoTable *info,
StgClosure *src, nat size, generation *gen, StgWord tag)
StgPtr to, from;
nat i;
to = alloc_for_copy(size,gen);
if(size > 8)
Bdescr(to)->flags = BF_MEDIUM;
So I updated the code in rts/sm/Sweep.c to only inspect for free lines in blocks without BF_MEDIUM mark.
if (bd->u.bitmap[i] != 0) resid++;
else if(!(bd->flags & BF_MEDIUM))
printf("DEBUG: line_found(%p)\n", bd->start + BITS_IN(W_) * i);
This also worked. Now, in the 32012 blocks there were 189015 free lines, found in the same number of GCs, making about 5.9 free lines per block. We considered only blocks with small objects, but we didn t ignore the first line of each group of free lines. This can be achieved by checking if the previous line was also free.
if (bd->u.bitmap[i] != 0) resid++;
else if(!(bd->flags & BF_MEDIUM) && i > 0 && bd->u.bitmap[i] == 0)
printf("DEBUG: line_found(%p)\n", bd->start + BITS_IN(W_) * i);
Now, from the 32239 blocks, 165547 free lines were found, giving 5.1 free lines per block. But there are more things to improve. If the whole block is free, we want to free it, instead of marking it s lines as free. So it s better to mark the lines after we know that the blocks are not completely free. So I left the code that checks the bitmap as it was, and included a line check only for blocks that are not completely free. At this point, I also associated the fragmentation test with blocks with medium objects, because in blocks of small objects we plan to allocate in free lines, so fragmentation is not a (big) issue.
if (resid < (BLOCK_SIZE_W * 3) / (BITS_IN(W_) * 4) &&
(bd->flags & BF_MEDIUM))
fragd++;
printf("DEBUG: BF_FRAGMENTED\n");
bd->flags = BF_FRAGMENTED;
else if(!(bd->flags & BF_MEDIUM))
for(i = 1; i < BLOCK_SIZE_W / BITS_IN(W_); i++)
if(bd->u.bitmap[i] == 0 && bd->u.bitmap[i - 1] == 0)
printf("DEBUG: line_found(%p)\n", bd->start + BITS_IN(W_) * i);
The total ammount of blocks increased dramatically: the blocks that become fragmented and were not called again in sweep made a huge difference. From the 345143 blocks, 1633268 free lines were found, or about 4.7 free lines per block. 9434 blocks were free, so, from the remaining blocks, we have about 4.9 free lines per block.
Something we ll need then is a way to access these lines latter. The simplest way I thought to achieve it is constructing a list of lines, in each the first word of each free line is a pointer to the next free line, and the first word of the last free line is 0. It s useful to keep reporting the lines to stdout, so that we can then follow the list and check if we went to the same lines.
if(bd->u.bitmap[i] == 0 && bd->u.bitmap[i - 1] == 0)
StgPtr start = bd->start + BITS_IN(W_) * i;
printf("DEBUG: line_found(%p)\n", start);
if(line_first == NULL)
line_first = start;
if(line_last != NULL)
*line_last = (StgWord) start;
line_last = start;
*line_last = 0;
for(line_last = line_first; line_last; line_last = (StgPtr) *line_last)
fprintf(stderr, "DEBUG: line_found(%p)\n", line_last);
I printed the inclusion of the lines on the list to stdout, and the walking on the list in stderr, so that it d be easy to diff. There was no difference between the lists.
There re another improvements that can be made, like using a list of groups of free lines, but I think it ll be better to think about this after studying how the allocation in the free lines will be done. That s where I m going to now.
Various people observed in a long thread on debian-devel that the grub2 package was in a bit of a mess in terms of its release-critical bug count, and Jordi and Stefano both got in touch with me directly to gently point out that I probably ought to be doing something about it as one of the co-maintainers.
Actually, I don't think grub2 was in quite as bad a state as its 18 RC bugs suggested. Of course every boot loader failure is critical to the person affected by it, not to mention that GRUB 2 offers more complex functionality than any other boot loader (e.g. LVM and RAID), and so it tends to accumulate RC bugs at rather a high rate. That said, we'd been neglecting its bug list for some time; Robert and Felix have both been taking some time off, Jordi mostly only cared about PowerPC and can't do that any more due to hardware failure, and I hadn't been able to pick up the slack.
Most of my projects at work for the next while involve GRUB in one way or another, so I decided it was a perfectly reasonable use of work time to do something about this; I was going to need fully up-to-date snapshots anyway, and practically all the Debian grub2 bugs affect Ubuntu too. Thus, with the exception of some other little things like releasing the first Maverick alpha, I've spent pretty much the last week and a half solidly trying to get the grub2 package back into shape, with four uploads so far.
The RC issues that remain are:
upgrade-from-grub-legacy problems (#547944, #550477):upgrade-from-grub-legacy, and I should be able to unpick the bugs this way.
mdadm switched its default from the old 0.90 format which GRUB understood. Felix put together a branch implementing the hard parts of this a while back, and I've been trying to finish it off. The hard bit is dealing with device naming, especially as the new-format and rather more useful names under /dev/md/ don't show up during d-i after creating RAID volumes; I think this is because we always create them as /dev/md0 etc. It's looking tractable, though.
grub-install not being properly run (#557425 and many other sub-RC bugs):device.map files (#575076 and other sub-RC bugs):device.map in general. It was fine in the 1990s but it's hopeless now. Unfortunately there are still a small number of problems with running entirely without one, and one of my patches to help is controversial upstream, so we probably won't get to that for squeeze. In the meantime we'll probably just need some extra sanity-checking and robustness in the event that there's an incorrect or out-of-date device.map lying around, which we may just be able to do in the maintainer scripts or something if necessary.
grub-emu on sparc as a workaround.
grub-mkconfig a bit more robust in the event that the root filesystem isn't one that GRUB understands (#561855, #562672), and I'd quite like to write some more documentation.
On the upside, progress has been good. We have multiple terminal support thanks to a new upstream snapshot (#506707), update-grub runs much faster (#508834, #574088), we have DM-RAID support with a following wind (#579919), the new scheme with symlinks under /dev/mapper/ works (#550704), we have basic support for btrfs / as long as you have something GRUB understands properly on /boot (#540786), we have full info documentation covering all the user-adjustable settings in /etc/default/grub, and a host of other smaller fixes. I'm hoping we can keep this up.
If you'd like to help, contact me, especially if there's something particular that isn't being handled that you think you could work on. GRUB 2 is actually quite a pleasant codebase to work on once you get used to its layout; it's certainly much easier to fix bugs in than GRUB Legacy ever was, as far as I'm concerned. Thanks to tools like grub-probe and grub-fstest, it's very often possible to fix problems without needing to reboot for anything other than a final sanity check (although KVM certainly helps), and you can often debug very substantial bits of the boot loader - the bits that actually go wrong - using standard tools such as strace and gdb. Upstream is helpful and I've been able to get many of the problems above fixed directly there. If you have a sound knowledge of C and a decent level of understanding of the environment a boot loader needs to operate in - or for that matter specialist knowledge of interesting device types - then you should be able to find something to do.
Probably it's just a question of me not paying enough attention to the news... So: pointers welcome.
There are quie a few shiny new filesystems for local storage, like btrfs or HAMMER (and nilfs, Tux3, ext4, Reiser4...)
It seems the distributed storage side is covered as well, with ceph being merged recently. There are other systems (like, for example, Lustre), but they haven't appeared much in the news channels I tend to read. What I'd be curious is if any of these support hierarchical storage architectures like pushing out rarely used data to tape libraries. (But this is just idle speculation, I don't need this anywhere.)
But what I would really need is a replacement for NFS (v3): a classical client-server filesystem. I'm not sure NFSv4 is the right solution (where I'd use it, I currently can't because we rely too much on POSIX ACLs there, making the transition to NFSv4 quite a chore.) I think POHMELFS might be a solution in the long term, or CRFS, but I'm not sure how much progress there is on these; apt-cache search is silent, not a good sign. There's Samba 4 I guess I'll have to look at it, since it's supposed to be much cleaner and nicer to use than its predecessors and might be a good solution even if no Microsoft systems are involved. Is this what small environments (a fileserver and 100 clients or so) will want to use? Comments are very welcome.
RMS will be visiting Kosovo today to speak at the national library. There is no entrance fee, however the number of seats is limited to 250, so please register by writing to register@flossk.org.
Less illustriously, MJR will be visiting Plymouth to run a social media surgery as part of Doing business the co-operative way on Friday 25 June (tickets 25 or 75 email now). I ve a few good ideas for what to cover if people are interested but don t have specific questions (and I ll post a few of them here later), but what tip would you give to a new social media user?
Next.