Search Results: "xam"

3 May 2011

Josselin Mouette: Rolling release

Since this has been a major request from users for a long time, I can only cool with the idea of seeing the Debian project support a rolling release. However I m not pleased with the proposed ideas, since they don t actually include any serious plan to make this happen. Sorry guys, but a big GR that says We want a pony rolling release to happen doesn t achieve anything. Let me elaborate. First of all, discussions have focused a lot on what to do when we re in a freeze phase. Numerous cool ideas have been proposed, including PPAs (which again, won t happen until someone implements them). This is all good, but this is only the tip of the iceberg. Above all, before wondering what can happen in a freeze that lasts 20% of the time, let s wonder what can happen for the 80% remaining time. Once you have something that works in the regular development phase, you can tune it to make it happen, even if in a less optimal way, when the distribution is frozen. So let s not put the cart before the horse. There are three options if you want to make a rolling release happen.
  1. Make unstable usable. to make it happen, you have to prevent the disasters that rarely but unavoidably happen here. You don t want to make all rolling systems unusable because someone broke grub or uploaded a new version of udev that doesn t work with the kernel.
  2. Make testing usable. This sounds easy since RC-buggy packages are already prevented from migrating, but actually it is not. A large number of RC bugs are discovered at the time of testing migration, when some packages migrate and others don t. Worst of all, they require several days to be fixed, and it is very often that they require several months, when one of the packages gets entangled in a transition.
  3. Create a new suite for rolling usage.
The proponents of the CUT project obviously believe in option 2. Unfortunately, I haven t seen many things that could make it happen. A possible way to fix the situation would be to run large-scale regression testing on several upgrade paths. I don t know if there are volunteers for this, but that won t be me. That would also imply to make a lot of important bugs RC, since they could have a major effect on usability, but the release team will not be keen to make it happen. Because of the testing situation, when someone asks me for a rolling release, I point her to unstable with apt-listbugs. As of today, this is the closest thing we have to a rolling release, so we should probably examine more deeply option 1. Is it that complicated to write a tool to prevent upgrades to broken packages? A 2-day delay in mirror propagation and a simple list of broken packages/versions (like the #debian-devel topic, would be enough. Add an overlay archive, that works like experimental, and you can now handle freezes smoothly. Wait isn t that aptosid? We would probably gain a lot of insight from the people who invented this, instead of trying to reinvent the wheel. Finally, option 3 could open new horizons. There s a risk that it might drive users away from the testing and unstable suites, and this makes us wonder how we could have proper testing for our packages. Still, build a process that would (and that s really only an example) freeze unstable every month, give people 10 days to fix the most blatant issues, add a way to make security updates flow in from unstable, and you have a really nice rolling distribution. So overall, it only requires people to make things happen. You want option 2 to happen? Instead of working on GR drafts, start working with maintainers and release managers on ways to avoid breakage in testing. You want option 3 to happen? Start it as a new .debian.net service and see how it works. Personally, I d be in favor of offering aptosid developers to become DDs and offer their solution as a Debian service. It would bring in new people rather than driving away existing developers from working on our releases.

2 May 2011

Lucas Nussbaum: Debian rolling discussion on -devel@

Here is my attempt at a summary of the rolling discussion currently happening on debian-devel@. It might not be complete, it s probably a bit biased, but I hope that it s still better than nothing. It was also posted on debian-devel@. If you are involved in Debian development, please discuss it on debian-devel@, rather than in the comments of this blog. If you want to provide feedback about the Debian rolling idea, use this Doodle poll and/or the comments of this blog.
Update : Someone had the good idea to vandalize the poll, and remove all the votes from people in favor of rolling. Before the vadalism (log), the results were:
37 votes: I am a Debian user, I use testing or unstable, and I would like rolling to happen.
6 votes: I am a Debian user, I use testing or unstable, and I DON T want rolling to happen.
17 votes: I am a Debian user, I use stable, and I would like rolling to happen.
3 votes: I am a Debian user, I use stable, and I DON T want rolling to happen.
7 votes: I am NOT a Debian user, but I would probably use it if rolling happened.
1 vote: I am NOT a Debian user, and I don t care about rolling. Motivations There s some user demand for rolling releases. For evidence, one can look at the usage of Debian testing or unstable which clearly goes further than the Debian development community. Or at the quickly growing market share of ArchLinux. Or at the interest in LinuxMint and Aptosid. Or at the DPL s report of his interactions with the press. Debian s only official product is its stable releases. While it s a clearly great and useful product, many users and developers don t recognize themselves in it: it contains software that is too old for their needs. The success of Ubuntu is related to this problem: Ubuntu proposes a different compromise between stability and up-to-date-ness. While concurrencing Ubuntu with more frequent stable releases (released every 6-months, for example) doesn t look like the right thing to do, Debian is in a perfect position to provide a rolling release with marginal additional work, since Debian already has testing (and unstable) to build on. The rolling discussion investigates how we could endorse the concept of a rolling release, provided as a product in addition to stable releases. This rolling release would be based on the current testing branch. Benefits for Debian: Current proposed plan for rolling (Disclaimer: this is mostly my view. It is shared by others, but some details might not be) rolling is mostly about (external) communication. It is not expected to change our development processes fundamentally.
It would be a statement by the project (through a GR, for example). A very preliminary draft was proposed by Raphael Hertzog:
Title: Debian endorses usage of testing by end-users, and renames it to rolling The Debian project recognizes that the Debian testing distribution initially created to make it easier to prepare and test the next stable release has become a useful product of its own. It satisfies the needs of users who are looking for the latest stable versions of software and who can cope (or even appreciate) a system that s constantly evolving. The Debian project decides to endorse this usage and will strive to provide a good experience to users of testing . To better communicate this policy change to our users, testing will be renamed rolling .
Yes, it s mostly PR bullshit , and I don t expect it to significantly change Debian development processes. However, communication is necessary if we want to attract new users. What would change is more attention from developers to what happens in testing/rolling, which is a good thing since a better testing/rolling makes it easier to create stable releases from it. Open questions Most of the discussion is about the influence of the introduction of rolling on Debian development processes, and in particular, on the painful process resulting in stable releases. Many fear that, with rolling , it will be harder to get stable releases out. The root question is: if we do rolling, what do we do during freezes? Several options have been mentioned in the thread:
  1. We could decide not to do anything special: just freeze rolling for ~6 months, as we used to freeze testing. That might bore people who like the constant flux of new upstream releases, but if we decide that it s the only way to ensure high-quality stable releases, so be it.
  2. We could decide to fork a frozen branch when we freeze, and continue to manage rolling using migrations from unstable.
  3. We could mix both solutions: freeze rolling for 3 months, so that most of the stabilization work occurs with a single active branch, and then, for the final release preparation, fork frozen off rolling, and unfreeze rolling.
Two kinds of objections have been raised: Other things that were discussed: Tentative personal conclusion I have the impression that advertising testing as a rolling release usable by end-users is generally considered a good thing.
The renaming of testing to rolling is not as consensual, but most opponents have a whatever ; if you want position. How we deal with freezes is the hard point in this discussion. I m personnally in favor of the freeze rolling for 3 months, then fork frozen and unfreeze rolling plan, though it has some problems too (it is not clear whether the required manpower really decreases at the end of freezes). Where do we go from there? After another round of discussion, we might postpone the how to deal with freezes question to later, and proceed with a GR to measure the support for the testing for end-users + s/testing/rolling/ proposal.

30 April 2011

Thomas Girard: ACE+TAO Debian packaging moved to git

We recently converted Debian ACE+TAO package repository from Subversion to git. This was a long and interesting process; I learned a lot on git in the course. I had been using git for a while for other packages: BOUML, dwarves and GNU Smalltalk. But I did not really get it. A preliminary study led by Pau[1] showed that out of the following three tools: the last one was giving results that look better.
The conversion svn-all-fast-export requires physical access to the repo, so the Alioth SVN repo was copied on my machine svn-pkg-ace/ before running the tool:
svn-all-fast-export --identity-map authors.txt --rules pkg-ace.rules svn-pkg-ace
Here's the content of the pkg-ace.rules configuration file that was used:
create repository pkg-ace
end repository
match /trunk/
  repository pkg-ace
  branch master
end match
match /(branches tags)/([^/]+)/
  repository pkg-ace
  branch \2
end match
The author mapping file authors.txt being:
markos = Konstantinos Margaritis <email-hidden>
mbrudka-guest = Marek Brudka <email-hidden>
pgquiles-guest = Pau Garcia i Quiles <email-hidden>
tgg = Thomas Girard <email-hidden>
tgg-guest = Thomas Girard <email-hidden>
The tool sample configuration file merged-branches-tags.rules recommends to post-process tags, which are just a branch in SVN. That's why the configuration file above treats branches as tags. The conversion was indeed fast: less than 1 minute.
Post-conversion observations Invoking gitk --all in the converted repo revealed different kind of issues:
  • svn tags as branches: http://thomas.g.girard.free.fr/ACE/tags-as-branches.png Branches are marked with green rectangles, and tags with yellow arrows. What we have here (expected given our configuration of the tool) are branches (e.g. 5.4.7-5) corresponding to tags, and tags matching the SVN tagging commit (e.g. backups/5.4.7-5@224). We'll review and fix this.

  • merged code that did not appear as such: http://thomas.g.girard.free.fr/ACE/missing-merge-metadata.png Branches that were not merged using svn merge look like they were not merged at all.

  • commits with wrong author: http://thomas.g.girard.free.fr/ACE/wrong-author.png Before being in SVN, the repository was stored in CVS. When it was imported into SVN, no special attention was given to the commit author. Hence I got credited for changes I did not write.

  • obsolete branches: http://thomas.g.girard.free.fr/ACE/obsolete-branches.png The tool leaves all branches, including removed ones (with tag on their end) so that you can decide what to do with them.

  • missing merges: http://thomas.g.girard.free.fr/ACE/missing-merge.png The branch 5.4.7-12 was never merged into the trunk!

Learning git Based on observations above, I realized my limited knowledge won't do to complete the conversion and clean the repository. There are tons of documentation on git out there, and you can find a lot of links from the git documentation page. Here's the one I've used:
The Git Object Model It's described with pictures here. You really need to understand this if you haven't already. Once you do, you understand that git is built bottom-up: the plumbing then the porcelain. If you can't find the tool you need, it's easy to write it.
git fast-import The Migrating to Git chapter explains how you can use the git fast-import tool to manually import anything into git. I've used it to create tags with dates in the past, slightly changing the Custom Importer example in the book:
#!/usr/bin/env ruby
#
# retag.rb
#
# Small script to create an annotated tag, specifying commiter as well as
# date, and tag comment.
#
# Based on Scott Chacon "Custom Importer" example.
#
# Arguments:
#  $1 -- tag name
#  $2 -- sha-1 revision to tag
#  $3 -- committer in the form First Last <email>
#  $4 -- date to use in the form YYYY/MM/DD_HH:MM:SS

def help
  puts "Usage: retag <tag> <sha1sum> <committer> <date> <comment>"
  puts "Creates a annotated tag with name <tag> for commit <sha1sum>, using "
  puts "given <committer>, <date> and <comment>"
  puts "The output should be piped to git fast-import"
end
def to_date(datetime)
  (date, time) = datetime.split('_')
  (year, month, day) = date.split('/')
  (hour, minute, second) = time.split(':')
  return Time.local(year, month, day, hour, minute, second).to_i
end
def generate_tag(tag, sha1hash, committer, date, message)
  puts "tag # tag "
  puts "from # sha1hash "
  puts "tagger # committer  # date  +0000"
  print "data # message.size \n# message "
end
if ARGV.length != 5
  help
  exit 1
else
  (tag, sha1sum, committer, date, message) = ARGV
  generate_tag(tag, sha1sum, committer, to_date(date), message)
end
graft points (graft means greffe in French) Because of missing svn:mergeinfo some changes appear unmerged. To fix this there are graft points: they override git idea of parents of a commit. To create a graft point, assuming 6a6d48814d0746fa4c9f6869bd8d5c3bc3af8242 is the commit you want to change, currently with a single parent 898ad49b61d4d8d5dc4072351037e2c8ade1ab68, but containing changes from commit 11cf74d4aa996ffed7c07157fe0780ec2224c73e:
me@mymachine$ echo 6a6d48814d0746fa4c9f6869bd8d5c3bc3af8242 11cf74d4aa996ffed7c07157fe0780ec2224c73e 898ad49b61d4d8d5dc4072351037e2c8ade1ab68 >> .git/info/grafts
git filter-branch git filter-branch allows you to completely rewrite history of a git branch, changing or dropping commits while traversing the branch. As an additional benefit, this tool use graft points and make them permanent. In other words: after running git filter-branch you can remove .git/info/grafts file. I've used it to rewrite author of a given set of commits, using a hack on top of Chris Johnsen script:
#!/bin/sh

br="HEAD"
TARG_NAME="Raphael Bossek"
TARG_EMAIL="hidden"
export TARG_NAME TARG_EMAIL
filt='
    if test "$GIT_COMMIT" = 546db1966133737930350a098057c4d563b1acdf -o \
            "$GIT_COMMIT" = 23419dde50662852cfbd2edde9468beb29a9ddcc; then
        if test -n "$TARG_EMAIL"; then
            GIT_AUTHOR_EMAIL="$TARG_EMAIL"
            export GIT_AUTHOR_EMAIL
        else
            unset GIT_AUTHOR_EMAIL
        fi
        if test -n "$TARG_NAME"; then
            GIT_AUTHOR_NAME="$TARG_NAME"
            export GIT_AUTHOR_NAME
        else
            unset GIT_AUTHOR_NAME
        fi
    fi
'
git filter-branch $force --tag-name-filter cat --env-filter "$filt" -- $br
(Script edited here; there were much more commits written by Raphael.)

Important

It's important to realize that the whole selected branch history is rewritten, so all objects id will change. You should not do this if you already published your repository.

The --tag-name-filter cat argument ensures our tags are copied during the traversal; otherwise they would be untouched, and hence not available in the new history.

Hint

Once git filter-branch completes you get a new history, as well as a new original ref to ease comparison. It is highly recommended to check the result of the rewrite before removing original. To shrink the repo after this, git clone the rewritten repo with file:// syntax -- git-filter-branch says it all.

Cleaning up the repo To recap, here's how the ACE+TAO git repo was changed after conversion:
  1. Add graft points where needed.

  2. Clean tags and branches. Using git tag -d, git branch -d and the Ruby script above it was possible to recreate tags. During this I was also able to add missing tags, and remove some SVN errors I did -- like committing in a branch created under tags/.

  3. Remove obsolete branches.

  4. Merge missing pieces. There were just two missing debian/changelog entries. I did this before git filter-branch because I did not find a way to use the tool correctly with multiple heads.

  5. Fix commit author where needed. Using the shell script above Raphael is now correctly credited for his work.

That's it. The ACE+TAO git repository for Debian packages is alive at http://git.debian.org/?p=pkg-ace/pkg-ace.git;a=summary.
[1]http://lists.alioth.debian.org/pipermail/pkg-ace-devel/2011-March/002421.html
[2]available in Debian as svn-all-fast-export

29 April 2011

Ian Wienand: Toolchains, libc and interesting interactions

When building a user space binary, the -lc that gcc inserts into the final link seems pretty straight forward link the C library. As with all things system-library related there is more to investigate. If you look at /usr/lib/libc.so; the "library" that gets linked when you specify -lc, it is not a library as such, but a link script which specifies the libraries to link, which also includes the dynamic linker itself:
$ cat /usr/lib/libc.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-x86-64.so.2 ) )
On very old glibc's the AS_NEEDED didn't appear; so every binary really did have a DT_NEEDED entry for the dynamic linker itself. This can be somewhat confusing if you're ever doing forensics on an old binary which seems to have these entries for not apparent reason. However, we can see that that /lib/libc.so itself does actually require symbols from the dynamic linker:
$ readelf --dynamic /lib/libc.so.6   grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
Although you're unlikely to encounter it, a broken toolchain can cause havoc if it gets the link order wrong here, because the glibc dynamic linker defines minimal versions of malloc and friends -- you've got a chicken-and-egg problem using libc's malloc before you've loaded it! You can simulate this havoc with something like:
$ cat foo.c
#include <stdio.h>
#include <syslog.h>
int main(void)
 
   syslog(LOG_DEBUG, "hello, world!");
   return 0;
 
$ cat libbroken.so
GROUP ( /lib/ld-linux-x86-64.so.2 )
$ gcc -o -Wall -Wl,-rpath=. -L. -lbroken -g -o foo foo.c
$ ./foo
Inconsistency detected by ld.so: dl-minimal.c: 138: realloc: Assertion  ptr == alloc_last_block' failed!
Depending on various versions of things, you might see that assert or possibly just strange, corrupt output in your logs as syslog calls the wrong malloc. You could debug something like this by asking the dynamic linker to show you its bindings as it resolves them:
$ LD_DEBUG_OUTPUT=foo.txt LD_DEBUG=bindings ./foo
Inconsistency detected by ld.so: dl-minimal.c: 138: realloc: Assertion  ptr == alloc_last_block' failed!
$ cat foo.txt.11360   grep "\ malloc'"
     11360:	binding file /lib/libc.so.6 [0] to /lib64/ld-linux-x86-64.so.2 [0]: normal symbol  malloc' [GLIBC_2.2.5]
     11360:	binding file /lib64/ld-linux-x86-64.so.2 [0] to /lib64/ld-linux-x86-64.so.2 [0]: normal symbol  malloc' [GLIBC_2.2.5]
     11360:	binding file /lib/libc.so.6 [0] to /lib64/ld-linux-x86-64.so.2 [0]: normal symbol  malloc' [GLIBC_2.2.5]
Above, because the dynamic loader comes first in the link order, libc.so.6's malloc has bound to the minimal implementation it provides, rather the full-featured one it provides internally. As an aside, AFAICT, there is really only one reason why a normal library will link against the dynamic loader -- for the thread-local storage support function __tls_get_addr. You can try this yourself:
$ cat tls.c
char __thread *foo;
char* moo(void)  
	return foo;
 
$ gcc -fPIC -o libtls.so -shared tls.c
$ readelf -d ./libtls.so    grep NEED
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld-linux.so.2]
 0x6ffffffe (VERNEED)                    0x314
 0x6fffffff (VERNEEDNUM)                 2
Thread-local storage is worthy of a book of its own, but the gist is that this support function says "hey, give me an address of foo in libtls.so", the magic being that if the current thread has never accessed foo then it may not actually have any storage for foo yet, so the dynamic linker can allocate some memory for it lazily and then return the right thing. Otherwise, every thread that started would need to reserve room for foo "just in case", even if it never cares about moo. But looking a little closer at the symbols of libc.so is also interesting. libc.so doesn't actually have many functions you can override. You can see what it is possible to override by checking the relocations against the procdure-lookup table (PLT).
Relocation section '.rela.plt' at offset 0x1e770 contains 8 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000035b000  084600000007 R_X86_64_JUMP_SLO 00000000000a2100 sysconf + 0
00000035b008  02e000000007 R_X86_64_JUMP_SLO 0000000000075e50 calloc + 0
00000035b010  01dd00000007 R_X86_64_JUMP_SLO 0000000000077910 realloc + 0
00000035b018  029300000007 R_X86_64_JUMP_SLO 00000000000661c0 feof + 0
00000035b020  046f00000007 R_X86_64_JUMP_SLO 00000000000768c0 malloc + 0
00000035b028  000400000007 R_X86_64_JUMP_SLO 0000000000000000 __tls_get_addr + 0
00000035b030  01b400000007 R_X86_64_JUMP_SLO 0000000000076dd0 memalign + 0
00000035b038  086000000007 R_X86_64_JUMP_SLO 00000000000767e0 free + 0
i.e. instead of jumping directly to the malloc defined in the libc code section, any internal calls will jump to this stub which, the first time, asks the dynamic linker to go out and find the address of malloc (it then saves it, so the second time the stub just jumps to the saved location). This is an interesting list, seemingly without much order. feof, for example, stands out as worth checking out a bit closer why would that be there when fopen isn't, say? We can track down where it comes from with a bit of detective work; knowing that the value of the symbol feof will be placed into 0x35b018 we can disassemble libc.so to see that this address is used by the feof PLT stub at 0x1e870 (luckily, objdump has done the math to offest from the rip for us; i.e. 0x1e876 + 0x33c7a2 = 0x35b018)
000000000001e870 <feof@plt>:
   1e870:       ff 25 a2 c7 33 00       jmpq   *0x33c7a2(%rip)        # 35b018 <_IO_file_jumps+0xb18>
   1e876:       68 03 00 00 00          pushq  $0x3
   1e87b:       e9 b0 ff ff ff          jmpq   1e830 <h_errno+0x1e7dc>
From there we can search for anyone jumping to that address, and find out the caller:
$ objdump --disassemble-all /lib/libc.so.6   grep 1e870
000000000001e870 <feof@plt>:
   1e870:	ff 25 a2 c7 33 00    	jmpq   *0x33c7a2(%rip)        # 35b018 <_IO_file_jumps+0xb18>
   f19f7:	e8 74 ce f2 ff       	callq  1e870 <feof@plt>
$ addr2line -e /lib/libc.so.6 f19f7
/home/aurel32/eglibc/eglibc-2.11.2/sunrpc/bindrsvprt.c:70
Which turns out to be part of a local patch which probably gets things a little wrong, as described below. The sysconf relocation is from a similar add-on patch (being used to find the page size, it seems). libc, like all sensible libraries, uses the hidden attribute on symbols to restrict what is exported by the library. The benefit of this is that when the linker knows you are referencing a hidden symbol it knows that the value can never be overridden, and thus does not need to emit extra code to do indirection just in case you ever wish to redirect the symbols. In the above, it appears that feof has never been marked as hidden, probably because no internal glibc functions used it until that add-on patch, and since it is not considered an internal function the linker must allow for the possibility that it will be overridden at run time and provide a PLT slot for it. There are consequences; if this was on a fast-path then the extra jumps required to go via the PLT may matter for performance and it may also cause strange behaviour if somebody had preloaded something that took over feof. Note, this is different from saying that your library can override symbols provided by libc.so; such as when you LD_PRELOAD a library to wrap an open call. What you can not override is the open call that say, the internal libc.so function getusershell does to read /etc/shells. Having the malloc related calls as preemptable seems intentional and sane; although I can not find a comment to the effect of "we deliberately leave these like this so that users may use alternative malloc implementations", it makes sense so that libc.so is internally using the same malloc as everything else if you choose to use something such as tc-malloc. tl;dr? Digging into your system libraries is always interesting. Be careful with your link order when creating toolchains, and be careful about symbol visibility when you're working with libraries.

Dirk Eddelbuettel: Slides from Rcpp workshop / master class yesterday

Romain and I just posted our slides from yesterday's Rcpp workshop and class (preceding the now-ongoing R/Finance conference). You can access the slides via my presentation page, or directly from here as Part 1 (Introduction), Part 2 (Details), Part 3 (Advanced) and Part 4 (Applications). The page also contains a link to the examples as a tar.gz and zip file.

Update: One link corrected.

Petter Reinholdtsen: Initial notes on adding Open311 server API on FixMyStreet

The last few days I have spent some time trying to add support for the Open311 API in the Norwegian FixMyStreet service. Earlier I believed Open311 would be a useful API to use to submit reports to the municipalities, but when I noticed that the New Zealand version of FixMyStreet had implemented Open311 on the server side, it occurred to me that this was a nice way to allow the public, press and municipalities to do data mining directly in the FixMyStreet service. Thus I went to work implementing the Open311 specification for FixMyStreet. The implementation is not yet ready, but I am starting to get a draft limping along. In the process, I have discovered a few issues with the Open311 specification. One obvious missing feature is the lack of natural language handling in the specification. The specification seem to assume all reports will be written in English, and do not provide a way for the receiving end to specify which languages are understood there. To be able to use the same client and submit to several Open311 receivers, it would be useful to know which language to use when writing reports. I believe the specification should be extended to allow the receivers of problem reports to specify which language they accept, and the submitter to specify which language the report is written in. Language of a text can also be automatically guessed using statistical methods, but for multi-lingual persons like myself, it is useful to know which language to use when writing a problem report. I suspect some lang=nb,nn kind of attribute would solve it. A key part of the Open311 API is the list of services provided, which is similar to the categories used by FixMyStreet. One issue I run into is the need to specify both name and unique identifier for each category. The specification do not state that the identifier should be numeric, but all example implementations have used numbers here. In FixMyStreet, there is no number associated with each category. As the specification do not forbid it, I will use the name as the unique identifier for now and see how open311 clients handle it. The report format in open311 and the report format in FixMyStreet differ in a key part. FixMyStreet have a title and a description, while Open311 only have a description and lack the title. I'm not quite sure how to best handle this yet. When asking for a FixMyStreet report in Open311 format, I just merge title an description into the open311 description, but this is not going to work if the open311 API should be used for submitting new reports to FixMyStreet. The search feature in Open311 is missing a way to ask for problems near a geographic location. I believe this is important if one is to use Open311 as the query language for mobile units. The specification should be extended to handle this, probably using some new lat=, lon= and range= options. The final challenge I see is that the FixMyStreet code handle several administrations in one interface, while the Open311 API seem to assume only one administration. For FixMyStreet, this mean a report can be sent to several administrations, and the categories available depend on the location of the problem. Not quite sure how to best handle this. I've noticed SeeClickFix added latitude and longitude options to the services request, but it do not solve the problem of what to return when no location is specified. Will have to investigate this a bit more. My distaste for web forums have kept me from bringing these issues up with the open311 developer group. I really wish they had a email list available via Gmane to use for discussions instead of only a forum. Oh, well. That will probably resolve itself, one way or another. I've also tried visiting the IRC channel #open311 on FreeNode, but no-one seem to reply to my questions there. This make me wonder if I just fail to understand how the open311 community work. It sure do not work like the free software project communities I am used to.

28 April 2011

Russell Coker: What is Valid SE Linux Policy?

Guido Trentalancia started an interesting discussion on the SE Linux policy development list about how to manage the evolution of the policy [1]. The Problem The SE Linux policy is the set of rules that determine what access is granted. It assigns types to files and domains to processes and has a set of rules that specify all the permitted interactions between processes and files (among many other things). The policy evolves over time to match the requirements of programs (applications and daemons). As a program evolves the things that it does will change and the SE Linux policy will tend to evolve to permit the set of all operations that were requested by all versions because people only complain when things stop working not when excessive privilege is granted. So we need to periodically remove old allow rules from the policy. One difficulty in this regard is the fact that multiple versions of programs are often available for use at the same time. Debian in particular has a good history of providing separate packages for the old and new versions of programs such as Apache to meet the needs of users who want the tried and tested version and of users who want the newer version with better performance, more features, better documentation, or something else good. There is also a demand to have the same policy work with multiple versions of a distribution without excessive effort. Finally all the distributions that have SE Linux support have different people deciding when the new version of a daemon is ready for inclusion and therefore there is a need to support multiple versions for multiple distributions. So support for older versions of daemons can t be removed easily. One of the things I do to make these things a little easier to manage is to put ifdef( distro_debian', before any Debian specific bits of policy. When policy is conditional and only used in Debian I can freely remove it at any future time if Debian works well without it. Also it doesn t matter if such Debian specific policy allows access that is not needed or desired in other distributions, the only down-side to this is that sometimes other distributions need to repeat work that I did, they determine what access is needed for their configuration and discover that it was already enabled for Debian. What is Valid Policy? We went to only have Valid Policy (as described by Christopher J. PeBenito), so the challenge is determining what is Valid Policy. It seems to me that there are three type of access granted by valid policy (it is debatable whether type #3 is valid):
  1. Access that is needed for an application to perform it s minimal designed task.
  2. Access that is needed for the application to perform all the optional configurations, EG an ftpd running from inetd or as a daemon, and daemons like http server being granted access to ssl keys or not.
  3. Access that is needed to perform all the operations the application requests, but which the application doesn t require or shouldn t require if it worked correctly.
Some common operations that aren t required include opening utmp for write, searching /root, and many other relatively innocuous access attempts which don t affect the program operation if they are denied. There are also many things such as writing temporary files to /root that don t seem unusual if the application developer is not considering SE Linux (but which are often considered bad practice anyway). Some of these things (like using /root for stuff that belongs in /var/lib) have the potential to break things (for the daemon or for other system processes) even if you don t consider SE Linux. How to deal with those types:
  1. In most cases this can be determined without too much effort. For example a web server needs to listen on port 80 and read files and directories that relate to data. When writing policy I can write a lot of the allow rules without even testing the application because I know from the design what it will do. A large part of the other access is obvious in a I can t believe I didn t realise it would need this sense.
  2. The main question here is whether we have booleans (settings which can be tuned at run-time by the sysadmin which determine how the policy works) to specify which optional tasks or whether we allow all access for optional configurations by default. The secondary question is when certain unusual corner cases should be not supported at all such that the people who do such unusual corner cases need to use audit2allow to generate local policy to allow their operations.
  3. Sometimes we have to allow things that we really don t like. Even when we write policy to allow a daemon to do unusual things (such as using /root instead of /var/lib) it s still a lot better than running without SE Linux. Also SE Linux policy to allow such obviously broken things stands out and is a constant reminder that the daemon needs fixing, this is better than allowing symptoms of broken design to be forgotten.
How to Improve the Situation We could have comments in the policy source for everything that is in category 3. If the comments had a fixed format so that a recursive grep could find them all then it would allow us to more easily remove the gross things from the policy at a later date. But it seems to me that the main problem is a lack of people working on this. I am not aware of any people actively testing Debian policy for excessive privilege in regard to such issues.

Meike Reichle: What it's like to do Debian Press Work

A few days ago I did an interview for the People Behind Debian series that, among other things, covered my Debian press work and asked what it's like to do that kind of work for Debian. Here's a little addendum: Sometimes Debian Press Work is great: All these people do all this amazing stuff and it's a pure pleasure to talk about it. Our last release was such an experience for example. I was clamped to my laptop for almost 20 hours straight and I had a great time! There was this great common feeling of community, achievement and pride in our work and I was proud and happy to be a part of it. And then there are times like the last few days, where Alex and I went South for 4.5 precious and long-awaited days of vacation and ended up spending the first two of them working on an obituary for a dear and much valued member of our community and once this was done spent the remaining days of our holidays nervously watching the net and drafting and re-drafting press announcements because some <bleep> thought it might be oh-so-hilarous to send out faked cease and desist orders to a Debian user, ostensibly as a funny prank but along the way causing a huge amount of completely unsubstantiated FUD that we'll probably spend weeks clearing up. Somewhere in between these events is what Debian press work is like.

Patrick Schoenfeld: On Debian discussions

In my article "Last time I've used network-manager" I made a claim for which I've been criticized by some people, including Stefano, our current (and just re-elected) DPL. I said that a certain pattern, which showed up in a certain thread, were a prototype for discussions in the Debian surroundings.

Actually I have to commit, that this was a very generalizing statement, making my own point against the discussion point back directly at myself.
Because as Stefano said correctly there has been some progress in the Debian discussion cult.
Indeed, there are examples of threads, were discussions followed another scheme.
But to my own advocacy I have to say that such changes are like little plants (in the botanical sense). They take their time to grow and as long as they are so very new, they are very vulnerable to all small interruptions. Regardless of how tiny those interruptions may seem.

I've been following Debian discussions for 6 or 7 years. That scheme I was describing was that which had the most visibility of all Debian discussions. Almost every discussion which were important for a broader audience followed that scheme. It has a reason that Debian is famous for flamewars.
In a way its quiet similar to the network-manager perception, some people have. Negative impressions manifest themselves. Especially if they have years of time.
Positive impressions does not have a chance to manifest themselves as long as the progress is not visible enough to survive small interruptions.

I hope that I didn't cause to much damage with my comment, which got cited (context-less) on other sites. Hopefully the Debian discussion cult will improve further to a point where there is no difference between the examples of very good, constructive discussions we already have in some parts of the project and the project-wide decision-making-discussions which affect a broad audience and often led to flamewars.

Russell Coker: Australia Needs it s own Monarch

Tomorrow Prince William will marry Kate Middleton. If we don t change anything he will probably become the King of Australia at some future time, so I think that now is the time to start discussing the options. Walter Block makes some interesting points in favor of longer terms for politicians and for having a monarch to get a long-term view of the national interest [1], he s not the only person to make such points, but he makes them in a better way than most. Of course the problem with this is the long history of kings not doing what s best for their country part of the ownership rights to property is the right to destroy it, so a monarch who owns a country therefore can be considered to have the right to cause the wholesale death of their subjects. There are some examples of President for Life political leaders demonstrating this at the moment. Even with a monarch who is generally a nice person and who has controls to prevent the worst abuses there is the possibility of Control Fraud. In the Constitutional Monarchy system that doesn t happen because a constitutional monarch has little power (no official position of power). But there is still the issue of whether the monarchy is any good. Charles Stross wrote an interesting post about the apparent human need to have a leadership figure [2]. So getting rid of a monarch tends to result in a president getting the trappings of a king, and if things go wrong (as they often do) then they get absolute power until the next revolution. It seems that having one person who is the head of government and the head of state (as done in the US for example) is a bad idea, they can start to think that it s all about them. I don t think that the US is at risk of getting a president for life in the near future and I don t think that Australia will do so if we become a republic, but that doesn t mean that the republican system works well. I think that the Australian system is working better than the US system and I will generally vote against any changes that make Australia more like the US. As long as the House of Windsor provides monarchs who are as sensible as Queen Elizabeth 2 I will vote in favor of the continued rule of the House of Windsor in preference to an Australian republic (if Prince Charles ever becomes king I may support a republic). A Way of Improving Things I want to have an Australian monarch. Someone who will live in Australia for most of the time (as opposed to a distant monarch who visits once a decade if we are lucky). Protocol should dictate that the Prime Minister and cabinet ministers are forced to show ritual respect to the monarch, bowing etc, and no touching. A separation between the person who performs most of the ceremonial functions and the person who actually makes the political decisions should help constrain political egos. When a Prime Minister feels the need to suck up to someone more powerful it would be better to have that person be an Australian monarch than the US president. Tradition has it that monarchs have to be descended from other monarchs (although there are cases of elected monarchs as happened in Danish history). An election for a monarch probably wouldn t work well in a modern political environment, so we need someone with royal ancestry. One possibility is to have a spare descendant of our current Queen become the monarch of Australia, I think it s quite likely that given a choice between remaining a UK prince or princess for the rest of their life and becoming the monarch of Australia there would be someone who would take the latter option and I expect that the Queen would consent to that arrangement if asked (she would have to prefer it to a Republic). Another possibility is the fact that Mary the Crown Princess of Denmark has more children than the Danish monarchy requires [3]. As she was born in Australia it seems likely that her children will have more interest in Australia than most royals and a skim read of some tabloid magazines indicates that her family is quite popular. I expect that if a Danish prince or princess was invited to become the monarch of Australia then this would be acceptable to the Queen of Denmark. In an ideal world there would not be such a thing as a monarchy. But as we don t get to have ideal voters and therefore our politicians are far from ideal it seems to me that the constitutional monarchy is the least bad system of government. Don t think that I am in favor of a monarchy, I just dislike it less than the other options. Finally the Queen is the Supreme Governor of the Church of England. I think that it would be good to have a separation between church and state and therefore anyone who is in a leadership position of any religious organisation should be considered unsuitable to be the monarch.

Daniel Kahn Gillmor: USAA Deposit@Home: bad engineering and terrible UX

I use USAA for some of my finances. They specialize in remote banking (i've never been in a physical branch). Sadly, they can still be pretty clueless about how to use the web properly. My latest frustration with them was trying to use their Deposit@Home service, where you scan your checks and upload them. No problem, right? I've got a scanner and a web browser and i know how to use them both. Ha ha. Upon first connecting, i'm rejected, and i find the absurd System Requirements -- only Windows and Mac, and only certain versions of certain browsers. You also need Sun's Java plugin, apparently. Deliberately na ve, i call their helpdesk and ask them if they could just give me a link to let me upload my scanned checks. They tell me that they want 200dpi images, and then give an absurd runaround that includes references to the Gramm-Leach-Bliley Act as the reason they need to limit the system to Windows or Mac, and that security is the reason they need to control the scanner directly (apparently your browser can control your local scanner on Windows? yikes). But they let slip that Mac users don't have the scanner controlled directly, and can just upload images (apparently the federal law doesn't cover them or something). Preposterous silliness. The Workaround Of course, it turns out you can get it working on Debian GNU/Linux, mainly by telling them what they want to hear ("yes sir, i'm running Mac OS"), but you'll also have to run Sun's Java (non-free software) to do it, since their Java uploader fails with nasty errors when using icedtea6-plugin. I set up a dedicated system user for this goofiness, since i'm going to be running apparently untrustworthy applets on top of non-free software. I run a separate instance of iceweasel as that user; all configuration described is for that user's homedir. If you do this yourself, You'll need to decide if you want the same level of isolation for yourself. So i have the choice of installing sun-java6-plugin from non-free and having the plugin installed for all web browsers, or just doing a per-user install of java for my dedicated user (and avoiding the plugin for my normal user). I opted for the latter. As the dedicated user, I fetched the self-extracting variant from java.com, unpacked it, and added it to the iceweasel plugins:
chmod a+x ~/Download/jre-6u25-linux-i586.bin
mkdir -p ~/lib ~/.mozilla/plugins
cd ~/lib
~/Download/jre-6u25-linux-i586.bin
ln -s ~/lib/jre*/lib/*/libnpjp2.so ~/.mozilla/plugins/
Then i closed iceweasel and restarted it. In the relaunched iceweasel sesson, I told Iceweasel 4 to pretend that it was actually Firefox 3.6 on a Mac. I did this by going to about:config (checking the box that says i know what i'm doing), right-clicking, and choosing "new >> string". The new variable name is general.useragent.override and i found that setting it to the following (insane, false) value worked for me:
Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.9.2.3) Gecko/20060426 Firefox/3.5.18
Note that this configuration might make hotmail think that you are a mobile device. :P If you try to use this browser profile for anything other than visiting USAA, you might want to remove this setting, or install xul-ext-useragentswitcher to be able to set it more easily than using about:config. Once these changes were made, I was able to log into USAA, use the Deposit@Home service to upload my 200dpi grayscale scans. I guess they think i'm a Mac user now. The Followup After completing the upload, I wrote them this review (i doubt they'll post it):
The Deposit@Home service has great potential. Unfortunately, it currently appears to be overengineered and unnecessarily restrictive. The service requires two scans (front and back) of the deposited check, at 200dpi, in grayscale or black-and-white, in jpeg format, reasonably-cropped. The simplest way to do this would be to show some examples of good scans and bad scans, and provide two file upload forms. Once the user uploaded their images, the web site could run its own verification, and display them back for the user to confirm, optionally using a simple javascript-based image-cropper if any image seems wrong-sized. This would work fine with any reasonable browser on any OS. Instead, Deposit@Home requires the user to present a User-Agent header claiming to be from specific versions of Mac or Windows, running certain (older) versions of certain browsers, and requires the use of Sun's Java plugin. Entirely unnecessary system requirements to do a simple task. Disappointing. :(
Acknowledgements I found good background for this approach on the ubuntu forums. The Takeaway I continue to be frustrated and annoyed by organizations that haven't yet embraced the benefits of the open web. Clearly, USAA has spent a lot of money engineering what they think is a certain experience for their users. However, they didn't design with standard web browsers in mind, so they appear to have boxed themselves into a corner where they think they have to test and approve of the entire software stack running on the end-user's machine. This is not only foolish -- it's impossible. When you're designing a web-based application, just design it for the web. Keep it simple. If you want to offer some snazzy java-hooked-into-your-scanner insanity, i will only have a mild objection: it seems like a waste of time and engineering effort. My objection is much stronger if your snazzy/incompatible absurdity is the only way to use your service. A simple, web-based, browser-agnostic interface should be available to all your clients. Even more aggravating is the claim that they don't think they should engineer for everyone. I was told during the runaround that they would only support Linux if 4% of their users were using Linux (which they don't think is the case at the moment -- if you are a USAA customer, and you use something other than Mac and Windows, please tell them so). I tried to tell them that I wasn't asking for Linux support; i was asking for everyone support. If you just use generic engineering in the first place, there's no extra expense for special-casing other users. But they couldn't understand. And now, since i'll need to lie to them in my User Agent string every time i want to deposit a check online, those visits won't even show up in their logs to be counted. "Our web site deliberately disables itself for $foo users; we haven't written it for them; but that's OK, we don't have any $foo users anyway" is a nasty self-fulfilling prophecy. Why would you do that?

27 April 2011

Kees Cook: non-executable kernel memory progress

The Linux kernel attempts to protect portions of its memory from unexpected modification (through potential future exploits) by setting areas read-only where the compiler has allowed it (CONFIG_DEBUG_RODATA). This, combined with marking function pointer tables const , reduces the number of easily writable kernel memory targets for attackers. However, modules (which are almost the bulk of kernel code) were not handled, and remained read-write, regardless of compiler markings. In 2.6.38, thanks to the efforts of many people (especially Siarhei Liakh and Matthieu Castet), CONFIG_DEBUG_SET_MODULE_RONX was created (and CONFIG_DEBUG_RODATA expanded). To visualize the effects, I patched Arjan van de Ven s arch/x86/mm/dump_pagetables.c to be a loadable module so I could look at /sys/kernel/debug/kernel_page_tables without needing to rebuild my kernel with CONFIG_X86_PTDUMP. Comparing Lucid (2.6.32), Maverick (2.6.35), and Natty (2.6.38), it s clear to see the effects of the RO/NX improvements, especially in the Modules section which has no NX markings at all before 2.6.38:
lucid-amd64# awk '/Modules/,/End Modules/' /sys/kernel/debug/kernel_page_tables   grep NX   wc -l
0
maverick-amd64# awk '/Modules/,/End Modules/' /sys/kernel/debug/kernel_page_tables   grep NX   wc -l
0
natty-amd64# awk '/Modules/,/End Modules/' /sys/kernel/debug/kernel_page_tables   grep NX   wc -l
76
2.6.38 s memory region is much more granular, since each module has been chopped up for the various segment permissions:
lucid-amd64# awk '/Modules/,/End Modules/' /sys/kernel/debug/kernel_page_tables   wc -l
53
maverick-amd64# awk '/Modules/,/End Modules/' /sys/kernel/debug/kernel_page_tables   wc -l
67
natty-amd64# awk '/Modules/,/End Modules/' /sys/kernel/debug/kernel_page_tables   wc -l
155
For example, here s the large sunrpc module. RW is read-write, ro is read-only, x is executable, and NX is non-executable:
maverick-amd64# awk '/^'$(awk '/^sunrpc/  print $NF ' /proc/modules)'/','!/GLB/' /sys/kernel/debug/kernel_page_tables
0xffffffffa005d000-0xffffffffa0096000         228K     RW             GLB x  pte
0xffffffffa0096000-0xffffffffa0098000           8K                           pte
natty-amd64# awk '/^'$(awk '/^sunrpc/  print $NF ' /proc/modules)'/','!/GLB/' /sys/kernel/debug/kernel_page_tables
0xffffffffa005d000-0xffffffffa007a000         116K     ro             GLB x  pte
0xffffffffa007a000-0xffffffffa0083000          36K     ro             GLB NX pte
0xffffffffa0083000-0xffffffffa0097000          80K     RW             GLB NX pte
0xffffffffa0097000-0xffffffffa0099000           8K                           pte
The latter looks a whole lot more like a proper ELF (text segment is read-only and executable, rodata segment is read-only and non-executable, and data segment is read-write and non-executable). Just another reason to make sure you re using your CPU s NX bit (via 64bit or 32bit-PAE kernels)! (And no, PAE is not slower in any meaningful way.)

Daniel Kahn Gillmor: The bleeding edge: systemd

Curious about these shiny new things i keep hearing about, i set up a test desktop system using using systemd as the init system (yes, that means using systemd-sysv in place of sysvinit -- so i had to remove an essential package for this to work). A system-crippling bug was naturally the result of living on the bleeding edge, but fortunately it was resolved with a trivial patch. In all, i'm pretty happy with some of the things that systemd seems to get right. For example, native supervision of daemon processes, clean process states, elimination of initscript copy-paste-isms, and socket-based service initiation are all obvious, marked improvements over the existing sysvinit legacy cruft. But i'm a bit concerned about other parts. For example, all the above-mentioned features fit really well within a tightly-tuned, well-managed server. But systemd also appears to rely heavily on complex userland systems like dbus and policykit that would be much more at home on a typical desktop machine. I've never seen a well-managed server installation that warranted either policykit or dbus. Also, given the bug i ran into -- when PID 1 aborts due to a silly assertion, your system is well-and-truly horked. Shouldn't a lot more attention to detail be happening? I'd think that a "recover gracefully from failed assertions" approach would be the first thing to target for a would-be PID 1. I'm also concerned about the Linux-centricism of systemd. I understand that features like cgroups and reliance on the spiffiness of inotify are part of the appeal, but i also really don't want to see us stuck with only One Single Kernel as an option. The kFreeBSD folks (and the HURD folks) have done a lot of work to get us close to having some level of choice at this critical layer of infrastructure. It'd be good to see that possibility realized, to help us avoid the creeping monoculture. I worry that systemd's over-reliance on Linux-specific features is heading in the wrong direction. So my question is: why is this all being presented as a package deal? I'd be pretty happy if i could get just the "server-side" features without incurring the dbus/policykit/etc bloat. I already run servers with runit as pid 1 -- they're lean and quite nice, but runit doesn't have systemd's socket-based initiation (or the level of heavyweight backing that systemd seems to have picked up, for that matter). I understand that Lennart is resistant to UNIX's traditional "do one thing; do it well" philosophy. I can understand some of his reasoning, but i think he might be doing his work and his tools a disservice by taking it this far. Wouldn't systemd be better if it was clearer how to take advantage of parts of it without having to subscribe to the entire thing? Of course, i might be missing some nice ways that systemd can be effectively tuned and pared down. But i've read his blog posts about systemd and i haven't seen how to get some of the nice features without the parts i don't want. I'd love to be pointed to some explanations that show me how i'm wrong :)Tags: systemd

26 April 2011

Julien Danjou: Why not Lua

Since my latest announcement of the Lua workshop, I received a couple of emails asking why I discourage the use of Lua. Actually, I already wrote out many of the things I dislike about Lua. I won't come back on this technical issues here, but since Lua 5.2 is not yet released (it's still at alpha stage), they are still relevant nowadays. Stack based API is harder

The ease of integration of Lua into a C program is one of the point of Lua. They claim it's very easy to integrate Lua into your C application, because it does not use pointer, nor reference counting, nor anything that requires a minimum amount of skills to be used. It uses a virtual stack based approach. You push or pop things on a stack, and refers to them using a relative or absolute index. In order to people who never wrote Lua code to understand, here's a quick example on how this work. The L pointer is a Lua environment.

/* Create a table on the stack: index 1 */
lua_newtable(L);
/* Push a string on the stack: index 2 */
lua_pushstring(L, "hello");
/* Push a number on the stack: index 3 */
lua_pushnumber(L, 123);
/* Set newtable["hello"] = 123 */
lua_settable(L, -3);
You first push a table (in Lua, a table is almost equivalent to what you'd call a hash table in other language), then push the key, the value, and do the assignment operation. In the settable, we use -3 as index, meaning the "3rd item on the stack counting from top". We could also have written lua_settable(L, 1), since the table is also the first item on the stack from the bottom. So far, so good. Problems arise when you do more complicated stuff. My previous example is what you would typically find in a tutorial, but of course, real life is different, and usually more complex. If you cut the things in different parts, it can start to be more complicated. Let's take a look at the following:
/* Create a table on the stack: index 1 */
lua_newtable(L);
/* Push a string on the stack: index 2 */
lua_pushstring(L, "hello");
/* Push a number on the stack: index 3 */
lua_pushnumbe(L, mycomputingfunction());
/* Set newtable["hello"] = 123 */
lua_settable(L, -3);
Here, we do exactly the same thing, but we do not push 123 directly: we compute it. And here's the trick: if your computing function is also using the Lua stack, things can become very messy. As long as your computing function use the stack cleanly by pushing and poping all its item, and returning the stack in the same state it was before, you're safe. The problem is that in a complex program, you also write bugs. You do not chose to, but you do. And sometimes, you forget to pop one of the item you fetched from a table. Imagine that mycomputingfunction is:
int
mycomputingfunctiong(void)
 
  /* Just push the table we want to fetch
     the number from on the stack */
  pushatableonstack(L);
  lua_pushstring(L, "mykey");
  lua_gettable(L, -2);
  return lua_tonumber(L, -1);
 
This function works perfectly. It pushes a table, then a key ("mykey"), then fetches mytable["mykey"] and pops the key (lua_gettable does push value/pop key itself), and then returns the numeric value of the last item (the fetched one) of the stack. However, this function has a bug: it does not pop the table! This does not prevent the function to work. It does not raise a segmentation fault. It does not show any problem under gdb. It does not show any leak under Valgrind. It does now show any problem under any standard C debugging tool. But when you'll start using it, your program will start to do weird things, and you'll have to spend a huge amount of time debugging it manually, dumping the stack content at each step of your program to watch out what's wrong. Another bad thing, that can happen, is some code poping accidentally an item from the stack, or worst, from an empty stack. This does not raise any error on the Lua side, but will break your program in very unfunny way. Even if I've been very meticulous writing awesome, but we hit that problem regularly. The easiest workaround is to use lua_settop(L, 0) to reset the stack to 0 element. Doing this regularly (like after each program event or treatment) can remove left-over items and avoid the never ending stack grow you may experience if your left-over items continue to pile up. Did I tell you I dislike work-around? You could also use lua_call(), which would avoid such an error, but this would require a huge amount of indirection, and would make write more (useless) code. This kind of problem does not exists with pointer based API. If you screw things up, the problem will cause a segmentation fault or leak memory, or cause things you can (easily) debug with standard tools like gdb or Valgrind. No reference counting is a pain in the ass

Userdata objects are variable Lua size objects embedding a C struct you define. It's the equivalent of an object in object oriented language. Lua does not provide any reference counting for the userdata objects. That means you can push this objects on the stack, use them, but they cannot directly reference each others. If you have a "car" userdata and a "wheel" one, the car cannot hold directly a reference to the wheel. This is not possible because userdata are allocated and garbage collected by Lua, and there's no way to increase the reference counting yourself. So the common hack is to store the wheel into a table as a value, and store the table index as an integer into the car data structure. This obviously makes memory leaks tracking harder, add huge level of reference indirection in usage (still more code), and does not make the whole process less error prone (at least in my opinion). No paradigm makes you lose time

Lua is proud to come with no paradigm and to provide metatables. I already showed 3 years ago that it has big flaws. To me, this ain't no good. Lua is not functional, nor it is object oriented. Most people, including me, want one of this paradigm, or any else. Plain old imperative is not enough. So you'll start to build more, or to use something like LOOP, which implements an object model. You'll implement your paradigm. I say life is too short to (re)write a paradigm. In awesome we wanted to have an object oriented approach (this is kind of typical in such a graphical application context), so we tried to build one. To me, this started to be a show stopper when I realized that I've ended writing Python object model into Lua while developing awesome (which aims to be a window manager, not a language). This is one of the reason I stopped hacking on Lua things. I liked Python object model and wanted to have it in Lua, and spending time rewriting Python is just not worth it. I probably should have chose Python, not Lua. YMMV. Embedding may not be a good choice

This is not Lua related, but I want to mention it. Googling for "embedding vs extending" will probably tell you more about why you should double check that you really need to embed Lua rather than to extend it. Being small is not an excuse

One common argument to choose Lua is that it has a small footprint. Yeah, that's true, but that's useless. Bummer! When I program, I don't have any resource usage pressure. People who have such pressure are either paranoids or playing in the world of embedded computers. This is also a no more existing conception since quad core processors equiped phones are coming into the market. I'm rather confident that what we used to call embedded devices are just dead and are now plain computers. But as usual, YMMV. So start to forget about it, run in your underpants and yelling "yay we killed that shit!", and then use real computers stuff. :-) Even if benchmarks show how Lua is damn fast, remember what a benchmark proves: that you can do useless things very fast. Too few extension modules

This is not directly Lua's fault, but there's too few extension modules for Lua. The community is quite small compared to other big languages' ones. So think twice

before you choose Lua (or any other language). My recommendations these days would be not to embed, but to extend. If you really have no choice and need to embed a language into your application, GNU Guile is probably worth considering, because it's a Scheme and therefore a functional language :-), and because it can provides also different languages. Including Lua. Flattr this

Lars Wirzenius: I'm a digital luddite, me

I'd like to buy most of my books as e-books, particularly novels. I'd like buy to all of my movies and TV shows as downloads. I'd like to buy maps for my Garmin GPS device as a download. I can do none of these things, unless I consent to restrict my freedoms in essential ways. For example, I can buy books, but only if I read them on a Kindle or Nook or similar restricted device. I can buy TV shows on iTunes, but I can't watch them on my Linux laptop. I can buy the maps, but only if I get a Windows (or maybe Mac) computer so I can run Garmin's proprietary software to download the maps and put them on the device. There are ways to circumvent these restrictions. Doing that is illegal in various countries I would like to live in. If I'm going to be breaking the law, the easier route would be to copy thing illegally. I can choose to succumb to corporate enslavement, where they get to decide what I watch, and how. Even when I try do this, I fail: I installed Amazon's Kindle software for the Android, but it would still not let me buy anthing, saying that each title is not available in my country. It said this even for stuff long past copyright, while giving pointers to the same thing in Project Gutenberg. Alternatively, I can choose to reject doing things digitally, and relying on paper for books and maps, and rental DVDs for video stuff. I've heard rumors that there is a lot of good stuff legally downloadable for free. Maybe I should go find some more. I have a short list already, but finding the stuff that actually interests me is not easy.

Anand Kumria: The SciFiRomCom.

In the last few weeks I've seen both The Adjustment Bureau and Limitless. And I've realised they are really both in a new (new to me, that is) category. If you have the chance, they are both worth seeing. They are not particular spectacular and neither will really make you think. But what is this new category about? Basically you have a Romantic Comedy but the trigger is Science Fiction. For example; in the Adjustment Bureau, a man loses an election. He meets an amazing girl who lifts his spirits and inspires him. To not only give a great consilation speech but to not give up. However, he never meets her again. Or he does but "outside forces" (the titular Adjustment Bureau) conspire to keep them apart. The remainder of the story is about him trying to overcome those obsticles. In Limitless, a man reaches rock bottom when his girlfriend leaves him. Whilst bumbling around he gets a 'magic' pill that helps him get into a state of flow and solve problems. Along the way, he arranges to do things that enhance his social proof; like learning (multiple) languages, earning lots of money, etc. Whilst the remainder of the story is about him trying to overcome the obsticles that life with the pill throws up, a significant sub-plot is the relationship with the ex.; and how he tries to win her back. Thus the SciFiRomCom, there are, no doubt many examples of this genre. But the earliest that I can recall seeing is Groundhog Day (which is a classic and MUST be seen). What other classic SciFiRomCom's are out there?

25 April 2011

Dirk Eddelbuettel: RInside 0.2.4

After several months, it was time for a new release 0.2.4 of RInside which is now on CRAN. RInside is a set of convenience classes which facilitate embedding of R inside of C++ applications and programs, using the classes and functions provided by the Rcpp R and C++ integration package. This new release contains a few small internal changes to the initialization code, as well as a number of slightly improved examples employing more of the simplifications which Rcpp offers. Also included is a brand new example embedding R inside of the Qt framework; an earlier blog post had already discussed this example. Two more examples were added to the standard/examples directory which now contains fourteen plus two tests. We also added a NEWS file, the entry for this release is below.
0.2.4   2011-04-24
   o    Minor code cleanups in initialization code 
   o    New example embedding R inside a Qt application, along with pro file
        for Qt's qmake providing a complete simple C++ GUI application
   o    New examples rinside_sample 10,11  based on questions on the
        r-help and r-devel mailing list
   o    Some improvements and simplifications throughout examples/standard 
        as well as examples/mpi/
   o    Added this NEWS files -- with entries below summarised from ChangeLog
        and the corresponding blog posts
And courtesy of CRANberries, here are the changes from the previous release.
RInside-0.2.3/RInside/inst/ChangeLog only RInside-0.2.3/RInside/libRInside.a only RInside-0.2.4/RInside/ChangeLog only RInside-0.2.4/RInside/DESCRIPTION 24 ++++-- RInside-0.2.4/RInside/R/RInsidePaths.R 4 - RInside-0.2.4/RInside/doxyfile 8 +- RInside-0.2.4/RInside/inst/NEWS only RInside-0.2.4/RInside/inst/THANKS 1 RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample0.cpp 10 +- RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample1.cpp 11 +-- RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample2.cpp 10 +- RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample3.cpp 9 -- RInside-0.2.4/RInside/inst/examples/qt only RInside-0.2.4/RInside/inst/examples/standard/rinside_sample1.cpp 30 ++++---- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample10.cpp only RInside-0.2.4/RInside/inst/examples/standard/rinside_sample11.cpp only RInside-0.2.4/RInside/inst/examples/standard/rinside_sample2.cpp 15 +--- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample3.cpp 6 - RInside-0.2.4/RInside/inst/examples/standard/rinside_sample5.cpp 10 +- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample6.cpp 12 +-- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample7.cpp 9 -- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample9.cpp 2 RInside-0.2.4/RInside/inst/include/RInsideAutoloads.h 35 ++++++++-- RInside-0.2.4/RInside/inst/include/RInsideEnvVars.h 13 +-- RInside-0.2.4/RInside/src/Makevars 2 RInside-0.2.4/RInside/src/RInside.cpp 21 +++--- 26 files changed, 121 insertions(+), 111 deletions(-)
More information is on the RInside page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.

23 April 2011

Lars Wirzenius: python-tracing 0.3

I've just made my first upload to PyPI, the Python Package Index, which is the closest thing to CPAN that Python has. I chose tracing as my first package, since it is small and simple and has no dependencies outside the standard library. tracing provides a couple of functions for logging debug messages, and allows the user to enable or disable logging for particular code modules. It is sometimes practical to add a lot of debugging log messages to a program, but having them enabled all the time results in very large log files. Also, logging that much takes quite a bit of time. This module provides a way to turn such debugging or tracing messages on and off, based on the filename they occur in. The logging can that be left in the code, and only enabled when it is needed, for example with a command line option. The actual logging happens via logging.debug.

Ben Hutchings: Recent changes in Debian Linux packages

Linux 2.6.38 and 2.6.39 As you've probably seen, the testing suite finally got a new upstream kernel version (Linux 2.6.38) and is currently synchronised with unstable. I'm just about to upload a new version of linux-2.6 based on upstream stable update 2.6.38.4. Linux 2.6.39 is well on its way to release, so 2.6.39-rc4 should soon be in experimental. The Debian source package will add support for the new armhf (ARM with hardware floating-point) architecture. Splitting linux-2.6 The linux-base package, introduced to handle transitions and other support functions for 'image' packages, is now built from a separate source package. It won't be changed very often, so you will no longer need to upgrade linux-base every time you upgrade an 'image' package. (This doesn't apply within 'squeeze', but I may have a way to work around that.) The firmware-linux-free package, containing a few firmware and configuration blobs from Linux that are DFSG-compliant, is also now built from a separate source package. These blobs have not changed for a very long time, so again you will no longer be recommended to upgrade this package every time you upgrade an 'image' package. Secondly, this allows us to remove the entire 'firmware' directory from the upstream source rather than carefully removing and patching to leave just the DFSG-compliant bits. Wireless regulations The '2.4 GHz' and '5 GHz' ISM bands used for wifi are not defined identically around the world. The exact frequency ranges and maximum permitted power levels vary between countries. Radio equipment manufacturers have a legal responsibility to ensure their equipment operates within these regulations. Since it is expensive to implement such regulations in hardware (including many different variants for different regions), these restrictions are usually implemented in the driver using a country code retrieved from the hardware's EEPROM or flash. So this is now our responsibility. We need to be able to look up regulations by country codes, and we also need to support the case where a device sold in one country is used in another country with tighter regulations. For some time, the wifi configuration library (cfg80211) included regulatory information for a small number of countries and regions. However, the default since Linux 2.6.34 has been to build-in only the 'world' domain (intersection of all the restrictions) and to request information from user-space. In Debian, we didn't have anything to provide this information, so for example channels 12-13 became unavailable for users in Europe. The regulatory information should be provided by the Central Regulatory Domain Agent (CRDA) from a current database. These are now packaged as crda and wireless-regdb respectively. Drivers that do not use cfg80211 (mostly those from the 'staging' area) will not be affected, and may or may not implement correct regulations. When you travel to another country or use an imported wifi device with an incorrect country code (I hear 'CN' is common), you can use iw reg set to ensure that your wifi devices operate within the regulations of the country you are in. Set the REGDOMAIN variable in /etc/default/crda to make this persistent. These will be intersected with the regulations specified by the hardware.

Dirk Eddelbuettel: Another nice Rcpp example

While preparing my slides for the Rcpp workshop this Thursday, I had wondered about more nice examples motivating Rcpp. So I posed a quick question on the rcpp-devel list. And I received a few friendly answers. My favourite, so far, was a suggestion by Lance Bachmeier who sent me a short script which used both R and C++ (via Rcpp) to simulate a first-order vector autoregressive process (and he ensured me that it worked well enough on his graduate students). It is indeed a great example as it involves (simple) matrix multiplication in an iterative fashion. Which makes it a great example not only for Rcpp but also for our RcppArmadillo package (which wraps Conrad Sanderson's wonderful Armadillo C++ templated library for linear algebra and more). And at the same time, we can also add another look at the new and shiny R compiler I also blogged about recently. So Lance and I iterated over this a little more over email, and I now added this as a new (and initial) example file in the RcppArmadillo SVN repo. (As an aside: The newest version 0.2.19 of RcppArmadillo has been sitting in incoming at CRAN since earlier in the week while the archive maintainer takes a well-deserved vacation. It should hit the public archive within a few days, and is otherwise available too from my site.) So let's walk through the example:
R> ## parameter and error terms used throughout
R> a <- matrix(c(0.5,0.1,0.1,0.5),nrow=2)
R> e <- matrix(rnorm(10000),ncol=2)
R> ## Let's start with the R version
R> rSim <- function(coeff, errors)  
+   simdata <- matrix(0, nrow(errors), ncol(errors))
+   for (row in 2:nrow(errors))  
+     simdata[row,] = coeff %*% simdata[(row-1),] + errors[row,]
+    
+   return(simdata)
+  
R> rData <- rSim(a, e)                     # generated by R
This starts with a simple enough loop. After skipping the first row, each iteration multiplies the previous row with the parameters and adds error terms. We can then turn to the R compiler:
R> ## Now let's load the R compiler (requires R 2.13 or later)
R> suppressMessages(require(compiler))
R> compRsim <- cmpfun(rSim)
R> compRData <- compRsim(a,e)              # generated by R 'compiled'
R> stopifnot(all.equal(rData, compRData))  # checking results
Nice and easy: We load the compiler package, create a compiled function and use it. We check the results and surely enough find them to be identical. With that, time to turn to C++ using Armadillo via RcppArmadillo:
R> ## Now load 'inline' to compile C++ code on the fly
R> suppressMessages(require(inline))
R> code <- '
+   arma::mat coeff = Rcpp::as<arma::mat>(a);
+   arma::mat errors = Rcpp::as<arma::mat>(e);
+   int m = errors.n_rows; int n = errors.n_cols;
+   arma::mat simdata(m,n);
+   simdata.row(0) = arma::zeros<arma::mat>(1,n);
+   for (int row=1; row<m; row++)  
+     simdata.row(row) = simdata.row(row-1)*trans(coeff)+errors.row(row);
+    
+   return Rcpp::wrap(simdata);
+ '
R> ## create the compiled function
R> rcppSim <- cxxfunction(signature(a="numeric",e="numeric"),
+                        code,plugin="RcppArmadillo")
R> rcppData <- rcppSim(a,e)                # generated by C++ code
R> stopifnot(all.equal(rData, rcppData))   # checking results
Here we load the inline package to compile, link and load C++ snippets. We define a short C++ function in the code variable, declare a signature taking a and e as before and ask cxxfunction() to deploy the plugin for RcppArmadillo so that it and Rcpp are found during build. With that, we have a compiled function to generate data, and we once again check the result. The C++ code is pretty straightforward as well. We can instatiate Armadillo matrices directly from the R objects we pass down; we then run a similar loop building the result row by row. Now, with all the build-up, here is the final timing comparison, using the rbenchmark package:
R> ## now load the rbenchmark package and compare all three
R> suppressMessages(library(rbenchmark))
R> res <- benchmark(rcppSim(a,e),
+                  rSim(a,e),
+                  compRsim(a,e),
+                  columns=c("test", "replications", "elapsed",
+                            "relative", "user.self", "sys.self"),
+                  order="relative")
R> print(res)
            test replications elapsed relative user.self sys.self
1  rcppSim(a, e)          100   0.038   1.0000      0.04        0
3 compRsim(a, e)          100   2.011  52.9211      2.01        0
2     rSim(a, e)          100   4.148 109.1579      4.14        0
So in a real-world example involving looping and some algebra (which is of course already done by BLAS and LAPACK libraries), the new R compiler improves by more than a factor of two, cutting time from 4.14 seconds down to about 2 seconds. Yet, this still leaves the C++ solution, clocking in at a mere 38 milliseconds, ahead by a factor of over fifty relative to the new R compiler And compared to just R itself, the simple solution involving Rcpp and RcppArmadillo is almost 110 times faster. As I mentioned, I quite like this example ;-).

Next.

Previous.