Search Results: "xam"

16 October 2007

Alastair McKinstry: The Curse of Oil

Jaldhar Vyas points to the rogues gallery of oil producing states and argues that Neoconservatism is good, well at least it gets rid of the dictators such as Saddam Hussein while it grabs the oil. As he ightly points out, we are researching new alternative energy sources, and just as importantly (or even more importantly) energy conservation. But we have been doing this for decades. Sooner or later we have to realize that the "Oil Crisis" isn't due to a shortage of energy sources: its due to deliberate politics to make us dependent on oil. Peak Oil is "only" a crisis for us consumers, dependent on oil to drive our cars, heat our houses, and supply our food. For oil companies, it means (1) they are shipping oil at a greater rate than ever before, (2) at higher demand than ever before, and (3) in circumstances where pesky politics like OPEC can't interfere and try and moderate the price down (I'm not arguing OPEC or cartels are good; its just that its long-term 'maximize the benefit for the oil producing nations' strategy interferes with oil companies shorter-term profit maximization). For the Oil Companies, its a good thing. In this context we have to see our current dependence on oil as the result of deliberate policy by the oil companies. The small filip that USanian governments have done towards alternative energy, such as funding Hydrogen fuel-cell research, nuclear power, etc. are so long-term, and so small in scale, that they have to be seen as deliberately not solving the problem. Thinking that research into alternative sources is good is gpoing to save us (disclaimer: as a scientist I think research is a good thing :-)) is missing the real problem. Its politics: the oil companies have simply been better at politics than the strugging alternatives; we need to recognize this, and fight for alternatives. When oil prices reach $100/barrel, and we struggle to pay rising food and energy bills, its because other have deliberately caused the crisis. Oil has often been called a Curse because of the effects 'Oil Wealth' have caused so many countries. They are not co-incidentally dictatorships; Saddam Hussein remained in power in Iraq for so long because it benefitted the West (see the weapons supplies to Iraq in the so-called "Iran-Contra" affair, for example). Ditto Saudi Arabia, remaining 'friends' of the USA despite its ties to 911. Overthrowing Saddam Hussein was about consolidating even more power in the Gulf than America had previously, not democracy. What was planned for Iraq was democracy in name only: all real power was already neutralised, with decisions to US benefit cemented in place before the parliament met: non-negotiable contracts already signed giving US companies control. This is straight imperialism, and cannot be considered democracy or a good thing. Tags , ,

Simon Richter: Componentisation heads-up

I have not forgotten about the componentisation tutorial. I'm just trying to find an ObjectAdapter that sucks less. The mighty PortableObjectAdapter (POA) is just that: portable. Hence, it does not require the C++ compiler to support RTTI, so it cannot determine whether an object that is passed as a reference is a proxy or the implementation itself. That makes automatic "activation" of objects difficult, because without that information, you cannot create shortcuts in call chains if two objects that live on the same host have been introduced to each other by a third on another host. So I'm looking for an implementation that uses RTTI to that effect, in order to have a non-overwhelming first example.

Raphael Geissert: sudo + apt-get + package upgrade + modified config files = root shell

I just got amazed by the fact that when the perfect condition is met, a user which can sudo apt-get has root shell access (since one could expect only installing/removing/purging/upgrading packages is allowed).

Whether expected or not, this is the HOW TO:


$ sudo apt-get upgrade
[...]
Configuration file /etc/foo.conf'
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer's version
N or O : keep your currently-installed version
D : show the differences between the versions
Z : background this process to examine the situation
The default action is to keep your current version.
*** foo.conf (Y/I/N/O/D/Z) [default=N] ? z
Type exit' when you're done.
root@nova:/# whoami
root


I don't believe it's a bug, but I find it interesting.

15 October 2007

Steve Kemp: She couldn't quite explain it

Previously I wrote about two "bugs" with GNU Screen. Now I discover, via a customer, that one of the servers I setup had allowed shell access when it should have been prohibited. A potentially serious security hole in this context. Here is an example, with this small .screenrc file:
#
#  Normally "ctrl-a c" would open a new "window".
#
#  We wish to prohibit that
#
bind c
Start GNU screen. Press "Ctrl-a c" nothing happens. All looks well, you've denied a new window! If you'd setup a shell in /etc/passwd to point to a wrapper which invoked GNU Screen with this configuration file you'd be fine, right? Actually not. Try pressing "Ctrl-a" and whilst those two keys are held down press and release "c". Joy. New window created. Even though it shouldn't be. Update - Turns out I'm stupid "ctrl-a c" is the same as "ctrl-a ctrl-c" by default. I didn't add "bind ^c" appropriately. My bad. For reference if you want to stop shell creation and you invoke screen as a login shell as a wrapper for other things then you must unbind a lot of builtins. eg. "bind :". You should then set:
shell /bin/false
Only then will you be secure. Probably. Thankfully this doesn't affect the Xen shell.

14 October 2007

Dirk Eddelbuettel: Tunes

Following Adam's suggestion about Pandora, I spent a the rest of the afternoon, evening and this morning listening to music old and new. Pandora's suggestions around Madeleine Peyroux were particularly nice as they lead for example to Sam Philipps which was new to me. I can already see this leading to increased spending on new cds... Recommended.

Martin F. Krafft: Converting a package to Git

Previously, I demonstrated a Debian packaging workflow using Git and I mentioned the possibility of a follow-up post; well, here it is: you want to use my workflow (or one that's related) for a package that is currently maintained with Subversion on svn.debian.org and you'd like to keep the history during the conversion. Make sure to read the previous post before this one. I am again using the example of mdadm since its Git packaging repository is in a state of shambles and I want to restart to get it right and import the history from the previous Subversion repository. What better way than to write a blog post as I do so? Well, plenty actually. This kind of post isn't really made for a blog, and I have started work on setting up ikiwiki on madduck.net, but it's not yet ready, so I'll stick with the blog for now. I will make sure that links don't break as I move content over, so feel free to bookmark this
Importing the package into Git Thanks to git-svn, the initial step of getting your package imported into Git is a breeze:
$ git-svn clone --stdlayout --no-metadata \
    svn+ssh://svn.debian.org/svn/pkg-mdadm/mdadm mdadm
Sit back and enjoy. If that command exits prematurely with an error such as the following:
Malformed network data: Malformed network data at /usr/local/bin/git-svn line 1029
then you should upgrade to a newer Git version, or have a look here. If your Git does not know --stdlayout then upgrade as well (or use -T trunk -t tags -b branches instead). Sam Vilain notes that it is important to "get the attribution right with the final SVN import - getting the authors map right. I didn't do that. If you look at the repository resulting from the above command, you'll notice strange commit authors, such as madduck@some-unique-uuid-from-svn . git-svn allows you to map these to real names with real email addresses, which ensures that the attributions are good for the whole world to see. When done, switch to the repository and run git-branch -r. As you'll see, git-svn imported all SVN branches and tags as remote branches. You need those if you want to bidirectionally track the Subversion repository, but we are converting, as you may have guessed by the --no-metadata switch above. Therefore, we resort to the Dinosaur method of converting branches to tags, which I'll simplify for mdadm. We also just delete all remote branches after tagging, since mdadm never used branches in the SVN repository. Your mileage may vary.
git branch -r   sed -rne 's, *tags/([^@]+)$,\1,p'   while read tag; do
  echo "git tag debian/$tag tags/$ tag ^; git branch -r -d tags/$tag"
done
git branch -r   while read tag; do
  echo "git branch -r -d $tag"
done
If that seems to work alright, then you can execute the commands. Sam Vilain (again) hints me at git-pack-refs and then to edit .git/packed-refs with an editor. This certainly leaves more room for errors but might be significantly faster.
Cleaning up the SVN references Even though we passed --no-metadata to git-svn, it did leave some traces in .git/, which we can now safely remove:
$ git config --remove-section svn-remote.svn
$ rm -r .git/svn
Setting things straight You can skip this section unless you want to know a bit about how to fix up stuff with Git. There was actually some nasty tagging errors leading up to the 2.5.6-9 release for etch and I could never be bothered to fix those in SVN, but now I can (I love Git!):
$ git tag -d debian/2.5.6-10            # never existed
$ git tag -f debian/2.5.6-8 2.5.6-8~2   # mistagged
$ git checkout -b maint/etch 2.5.6-8    # this is when we diverged
$ git apply < /tmp/mdadm-2.5.6-8..2.5.6-9.diff
$ git add debian/po/gl.po debian/po/pt.po debian/changelog
$ git commit -s
$ git tag debian/2.5.6-9
Now that that's fixed, there is one other thing to worry about, namely the very last commit to SVN, which obsoletes the repository and points to the Git repository. But that's not all of it. I was also silly enough to include a fix in the same commit. Let's see what Git can do. Since the process of obsoletion involves all but adding a file, we can simply --amend the last commit and provide a new log message:
$ git checkout master
$ git rm OBSOLETE debian/OBSOLETE
$ git commit --amend
Now the repository is in an acceptable state.
Making ends meet The pkg-mdadm effort on svn.debian.org only maintained the ./debian/ directory, separate from the upstream code, and boy was that a bad idea. Just to give one example: think about what's involved in preparing a Debian-specific patch against the upstream code this has to end, and we can make it end right here; let's import upstream's code (again not using his ADSL line, but the upstream branch of the pkg-mdadm Git repository; see the previous post for details):
$ git remote add upstream-repo git://git.debian.org/git/pkg-mdadm/mdadm
$ git config remote.upstream-repo.fetch \
    +refs/heads/upstream:refs/remotes/upstream-repo/upstream
$ git fetch upstream-repo
$ git checkout -b upstream upstream-repo/master
Now we have two unconnected ancestries in our repository, and it's time to join them together. The most logical way seems to be to use the last upstream tag for which we have a Debian tag: 2.6.2. For this, we branch off the corresponding Debian tag (2.6.2-1) and merge upstream's 2.6.2 tag into the new branch. This will be a temporary branch Then, we rebase (remember, nothing has been published yet) the master branch on top of this temporary branch, before we end that branch's short life. The Debian tag stays where it is since it describes the state of the repository at time of the release of 2.6.2-1.
$ git checkout -b tmp/join debian/2.6.2-1
$ git merge mdadm-2.6.2
$ git rebase tmp/join master
$ git branch -d tmp/join
It just so happens that the head of the SVN repository, which is identical to the tip of our master branch, corresponds to Debian release 2.6.2-2, so we tag it:
$ git tag debian/2.6.2-2
We are now also "born" in the sense that maintenance in Git has started. Let's mark that point in history. There is no real reason I can foresee for this yet, but nonetheless:
$ git tag -s git-birth
Turning dpatch files into feature branches We want to turn dpatch files into feature branches and we somehow make it "proper". We could branch, apply the patch, delete the patch file, checkout master and delete the patch file there as well, but that appears "improper" to me at least; so instead, we'll cherry-pick:
$ git checkout -b deb/conffile-location
$ debian/patches/01-mdadm.conf-location.dpatch -apply
$ git rm debian/patches/01-mdadm.conf-location.dpatch
$ git commit -s
$ git commit -s $(git ls-files --others --modified)
I should quickly intervene to make sure you are following. I am making use of Git's index here. Applying the patch makes the changes in the working tree, but we did not tell Git that we want those to be part of the commit just yet. Instead, we delete the dpatch with git-rm, which automatically registers the deletion with the index. Thus, the first git-commit creates a commit which deletes the dpatch, while the second git-commit creates a commit with all the changes from the dpatch, using git-ls-files to identify new and modified files. But for now, let's move on. We have two commits in the deb/conffile-location branch, and one of those is relevant to the master branch, we cherry-pick it:
$ git cherry-pick deb/conffile-location^
If you're confused, let me explain: our goal is to have a number of feature branches, of which master is the one in which most of ./debian/ is maintained. All the branches later come together in the long-living build branch, so deb/conffile-location will never be merged back into master. However, once we applied the dpatch to the feature branch, we can delete it from there and the master branch. By cherry-picking, we "import" the deletion to the master branch. I repeat the same procedure for deb/docs, merging all the documentation-related dpatches, but I'll spare you the details.
and then Git let me down In the next step, I found I had misunderstood Git merging: I thought Git was smart, but Linus had his reasons for calling Git the "stupid content tracker" (more on that later). Read on as I am obsoleting dpatch files that upstream had merged: 99-*-FIX.dpatch. For consistency, I wanted to cherry-pick each of the appropriate upstream commits into the master branch along with deleting the corresponding dpatch file. Here is one example: 99-monitor-6+10-FIX.dpatch was obsoleted by upstream's commit 66f8bbb; the -x records the original commit ID in the log:
$ git cherry-pick -x 66f8bbb
$ git rm debian/patches/99-monitor-6+10-FIX.dpatch
$ git commit -s -m"remove dpatch obsoleted by $(git rev-parse --short HEAD)"
I repeated the procedure for the other dpatch files, removed the dpatch infrastructure, and then went on to merge it all into build to build the package. The build branch is a long-living branch off upstream, but which upstream? I'll fast-forward you past a segfault problem with mdadm, which upstream (thought to have) resolved with commit 23dc1ae after 2.6.3, but he had not yet released 2.6.4. Looking at the commits between 23dc1ae and upstream's HEAD at the time, I decided to include them all and snapshot 4450e59:
$ git fetch upstream-repo
$ git checkout upstream
$ git merge upstream-repo
$ git tag mdadm-2.6.3+200709292116+4450e59 4450e59
$ git checkout master
$ git merge --no-commit mdadm-2.6.3+200709292116+4450e59
$ dch -v mdadm-2.6.3+200709292116+4450e59-1
$ git add debian/changelog
$ git commit -s
And then I called poor-mans-gitbuild, which merges master and then deb/* into build. Here is when stuff blew up. I'll make a long story short (read my description of the problem and Linus' answer if you want to know more): I thought Git was smart to identify merges common to both branches and do the right thing, but it turn out that Git does not care at all about commits, it only worries about content and the end result. In our case, unfortunately (or fortunately), the outcome meant a conflict because the upstream branch introduced a simple change (last hunk) in the lines surrounding the patch we cherry-picked, and Git can't handle it. The solution is not to cherry-pick, to cherry-pick all commits touching the context of the dpatch, or to simply merge upstream into all out feature branches. In our case, the first is the easiest solution and since importing dpatch files is a one-time thing (thank $DEITY), I'll leave it at that. Almost. I have spent two days thinking about this more than I should have. And it was this point Linus made which made me appreciate Git even more:
Conflicts aren't bad - they're good. Trying to aggressively resolve them automatically when two branches have done slightly different things in the same area is stupid and just results in more problems. Instead, git tries to do what I don't think anybody else has done: make the conflicts easy to resolve, by allowing you to work with them in your normal working tree, and still giving you a lot of tools to help you see what's going on.
The end This concludes today's report. Importing the changes from the old Git repo, tagging and merging the branches is all covered in my previous post, or at least you'll find enough information there to complete the exercise. I would like to specifically thank Sam Vilain and Linus Torvalds for their help in preparing this post, as well as the #git/freenode inhabitants, as always. If you are interested in the topic of using version control for distro packaging, I invite you to join the vcs-pkg mailing list and/or the #vcs-pkg/irc.oftc.net IRC channel. Also, if you are interested in Git in general, you can find a list of blog posts on the Git wiki. NP: The Police: Zenyatta Mondatta

13 October 2007

Daniel Burrows: Monad.Reader

The Reader monad is a simple and easy-to-use structure from the Haskell library that solves a common problem.

Very often, it's the case that you have a lot of functions that all need to use the same values. For instance, you might be laying out some text on a page, and you need to keep the details of the page size around in all your layout algorithms. Typically, you handle this situation by adding a new parameter to all your functions which represents the state. So,


layoutPage :: Text -> Page


becomes


layoutPage :: PageLayoutParams -> Text -> Page


This works just fine, but it can get really ugly. Every single function gets a new parameter, which must be threaded through to every related function that it ever calls. This causes visual clutter, particularly for functions that don't actually use the parameter themselves but just pass it on.

A function written in the Reader monad is augmented with a hidden parameter. For the hypothetical example above, we would write:


import Control.Monad.Reader
type LayoutFunc = Reader PageLayoutParams

layoutPage :: Text -> LayoutFunc Page


Note that the Reader monad is partially applied here. The result, LayoutFunc, is a new monad that adds a parameter of type PageLayoutParams to any code that runs inside it.

So, now that we have this monad, how do we use it? The "ask" operation retrieves the parameter that's hidden in the monad:


ask :: Reader a a


or, specialized to LayoutFunc:


ask :: LayoutFunc PageLayoutParams


In order to remain close to the example in question, I will provide specialized type signatures for the rest of the library functions. You can find the generic type signatures in the Haskell library documentation for Control.Monad.Reader.

Suppose that layoutPage started out like this before it was moved into the monad:


layoutPage st txt =
let width = pageWidth st
...


In the Reader monad, this becomes:


layoutPage txt =
do st - ask
let width = pageWidth st
...


As you can see, we've gone from one line of code to two. As this is clearly unacceptable for a clutter-reducing device, the Reader module provides a convenience function encapsulating the above pattern:


asks :: (PageLayoutParams -> a) -> PageLayoutFunc a


This allows us to simplify the monadic implementation to:


layoutPage txt =
do width - asks pageWidth
...


It's quite common, when multiple functions share context information, to invoke a function in an altered context. For instance, we might have a layoutSubPage routine that changes the page width:


layoutSubPage st newWidth txt =
doLayout (st pageWidth = newWidth txt)


The Reader equivalent of this idiom is the function "local":


local :: (PageLayoutParams -> PageLayoutParams) -> LayoutFunc a -> LayoutFunc a


local executes an operation in a context modified by its first parameter. For instance,


layoutSubPage newWidth txt =
local (\st -> st pageWidth = newWidth ) txt


Finally, to actually invoke a computation in the Reader monad, use runReader:


runReader :: LayoutFunc a -> PageLayoutParams -> a

main = showPage (runReader defaultPageParams someText)


For much more information on the Reader monad, see All About Monads, or the Haskell library documentation.

Biella Coleman: Decoding Liberation: The Promise of FOSS (and Web 2.0)

Last week I helped Samir Chopra and Scott Dexter kick off their book release party in New York City. The book Decoding Liberation: The Promise of Free and Open Source Software is the first academic book length piece on free software proper that among other things examines the repercussions of such elements as language use (free software vs open source) and licensing (such as non-copyleft licensing). Here are my opening remarks, which don’t give justice to the book but give a small taste of what is in there. Samir and Scott are computer scientists, philosophers, and political thinkers and bring these positions and perspectives to bear in their work. While I tend to avoid the discussion on the differences and divergences between free and open source software and licensing (just because I ask a set of questions that tend not to go into that territory), they spend a hefty about of time on this sort of engagement And what is so useful about their approach is that it is technically detailed and carefully analyzed, clarifying the stakes involved in choosing a certain set of licensing over others, or the political implications of language use. Along with this focus, there are many other threads they unpack and one of my favorites is on the aesthetics of code, which I discuss with some detail in my opening remarks with the help of one of my favorite literary writers, Susan Sontag. The conversation that followed was lively, in part because there were a number of people in the audience who are also very familiar with FOSS (Somewhat unbelievably, there were 3 anthropologists there who study free software, myself, Jelena Karanovic, and Anita Chan). And I think one of the most interesting questions was launched by Anita who asked the authors what they meant more precisely by the promise of FOSS as well as liberation. The conversation that followed was too rich to recount here, but something that I raised and I do think is important is the relationship between the buzz word of the last few years, Web 2.0 and FOSS. Web 2.0 is related to FOSS in so far as Web 2.0 refers to a suite of technologies that allow for the creation of user-generated content and collaboration. FOSS refers to a development methodology that is based on promiscuous sharing of code and collaboration. The similarities, however, end there because much of the Web 2.0 infrastructure is proprietary. FOSS by definition is non-proprietary. But I think that soon we are going to see more Web 2.0-like companies open up their infrastructure entirely or at least important components. One example of a new technology that is Web 2.0-like and is entirely free software is a activist networking tool crabgrass that is pretty impressive (I have used it to coordinate my move and am using it now to coordinate a collaborative grant). It is still under development but once released, it will be a great boon to any group that needs to collaborate and organize and coordinate:
Crabgrass also provides a public advocacy centric view of content so that people can learn more about issues and organizations through social relationships. Blog tools, voter guides, petitions, event organizing tools, and action alerts are being added to the functionality of the platform. Crabgrass integrates wikis, asset repositories, task lists, calendars, polls, and meeting schedulers into one tool which allows groups to manage their internal organizing.
The other technology that I am excited about and that I have already written about is Kaltura. As I mentioned, Kaltura is important because it lowers the bar for collaboration, providing tools to facilitate video editing. But what I find as interesting and as significant is that they are perhaps the first large-scale Web 2.0 company that is actively seeking to enter the territory of FOSS and in this respect, once they do so, they will lead the field, not simply for technical reasons, but because they choose to make and engage with open source technologies. Bringing Web 2.0 within the orbit of FOSS and brining FOSS within the orbit of Web 2.0 can only work to bolster each other, and this is where I think, at least part of the promise of FOSS lies.

Joey Hess: more mr fun

I've hacked a lot of handy features into mr. Some more examples follow. I've ommitted noisy output from the various revision control systems. Registering existing repos:
joey@kodama:~/tmp/scratch> git clone git://git.kitenet.net/mr
joey@kodama:~/tmp/scratch> svn co svn://svn.kitenet.net/joey/trunk/src/packages/alien
joey@kodama:~/tmp/scratch> mr register mr
Registering git url: git://git.kitenet.net/mr
joey@kodama:~/tmp/scratch> mr register alien
Registering svn url: svn://svn.kitenet.net/joey/trunk/src/packages/alien
joey@kodama:~/tmp/scratch> mr up
mr update: /home/joey/tmp/scratch/alien
At revision 13492.
mr update: /home/joey/tmp/scratch/mr
Already up-to-date.
mr update: finished (2 successful)
Command-line modification of the ~/.mrconfig file, and the ability to skip a repo based on an arbitrary shell test:
joey@kodama:~/tmp/scratch> mr config tmp/scratch/alien skip='[ $(hostname) != foo]'
joey@kodama:~/tmp/scratch> mr up
mr update: /home/joey/tmp/scratch/mr
Already up-to-date.
mr update: finished (1 successful; 1 skipped)
Tracking and warning about deleted repositories. Useful if, like me, you have dozens of repos checked out on dozens of machines:
joey@kodama:~/tmp/scratch> mr config tmp/scratch/mr deleted=true 
joey@kodama:~/tmp/scratch> mr up
mr error: /home/joey/tmp/scratch/mr/ should be deleted yet still exists
mr update: finished (1 failed; 1 skipped)
joey@kodama:~/tmp/scratch> rm -rf mr
joey@kodama:~/tmp/scratch> mr up
mr update: finished (1 skipped)
(Tracking of repo moving is still TODO.) Running mr from inside a repo operates on only that repo. Useful when you can't be bothered to remember what revision control system a particular repo uses. ;-)
joey@kodama:~/src/mr/debian> mr commit -m "bugfixes developed while writing blog post"
mr commit: /home/joey/src/mr (in subdir /home/joey/src/mr/debian)
Created commit 2f861a4: bugfixes developed while writing blog post
It also supports cvs and bzr now.

12 October 2007

Eddy Petri&#537;or: SELinux: unusable from a newbie perspective

Thanks Russell for the explanations on the execmem bits.

Now I am trying to go further and set up my system to really work with SELinux enabled because, although the promise of the targeted policy is to allow you to do your job mostly as you did before, that "mostly" has a really wide meaning, more than you'd think you bargained for.

Examples from my laptop: hald does not start by default (various denials), resolvconf is denied some getattr operations on tmpfs, hald-addon-dell-backlight is denied access to some character device I just know it should have access to, etc. Of course, this means that automatic mounting does not work anymore and there is a decrease in usability just because of the "mostly" part.

I am sure that some of the denials are correct (see the execstack stuff or the memexec), but there are cases where this "mostly" is stretched way too much. IMHO, desktop installs should suffer no restrictions when using the targeted policy (and I mean "no restrictions that would make my system less than it was before enabling and enforcing SELinux").


But let me tell a reason why SELinux sucks without any help from others:

The interface sucks big time.

Probably there is are good reasons, but if you need to create and use a new policy based on the denials found in the logs, you need to use no less than 4 (four) different tools with the right incantation (although you can use just 2, if you don't want to customize the rules[1]):
In the end, you still hit the bad interface:

bounty:~# semodule -i local.pp
libsepol.check_assertion_helper: assertion on line 0 violated by allow hald_t memory_device_t:chr_file read ;
libsepol.check_assertions: 1 assertion violations occured
libsemanage.semanage_expand_sandbox: Expand module failed
semodule: Failed!

Now what? That error message doesn't tell me much, except that some assertion failed. But where does the assertion come from? Why is it an assertion? What is bad about that line?
To me that really looks like an internal error or an inconsistency in what the SELinux tools generate.


[1] still, why advertise the longer path as the Fedora FAQ does? I would have done it the other way around.

Rapha&#235;l Hertzog: The DSA dilemma

For once, Clint blogged on something that I can understand. :-) I don’t buy everything he says, but in the case of DSA, the part where he says “you cannot have a functional and respectable subgroup if it maintains autonomy like that” is a real problem. The leadership problem I mentioned is real. And it can theoretically be solved by undelegating one of the problematic side of this DSA-internal dispute. But which one? Given the unwillingness of Joey to discuss the problems, he makes an easy target… which would leave DSA up to Ryan, James and Phil. But is that a desirable thing? If DSA is perceived as being an “autonomous” group which is not involved in Debian’s main discussions and which is somewhat disconnected from Debian’s day-to-day life, it’s largely due to the behavior of James and Ryan. E-mail communication with them is very difficult as they’ll respond only if they really care about something. And despite the setup of the request tracker, they have barely been able to make proper usage of it… the idea was to use RT tickets to track everything that DSA does but they don’t use it as such. For example, James setup a “wikiadm” group and he never reported anything to the related ticket (#194) (I did it myself once I found out). Also there’s an internal ticket about the replacement of ftp.debian.org (that I created because ftp.d.o ran out of space regularly) and AFAIK Jeroen has been in touch with James to setup that replacement, but nothing got reported to the tracker. Ryan promised me once to put his DSA TODO list in the tracker so that other people can jump in and help out. He never did. So while Joey is definitely a pain for DSA, at least he’s a visible participant of the team and he interacts with the community. James and Ryan are not, they interact only through private channels and do not share their opinions or their vision of Debian.
I believe this is a real problem. On the other hand, most of the interesting changes in the last months are the results of James’s work. But he’s also implicitly blocking addition of new members as long as the leadership problem is not solved. I tried to fill the communication void of the DSA team by various means. I follow everything as closely as I can so that I can report changes on other channels, mailing lists when needed. I made efforts to document stuff on the wiki page, etc. But this is not a long term solution, the communication issue must be fixed within the team. The path ouf of this mess is still not very clear, but something is going to change soon. Not quite sure what though. What would you suggest? And if you were DPL, what would you do? Since private discussions and negotiations lead nowhere, it’s tempting to bring the issue in the public area. In theory, they have no way to escape discussions and they’ll have to communicate their grudges against the other side if they want to have some fair judgment between both parties. Unfortunately, given the habits of James and Ryan, they probably won’t participate in any public discussion and either resign or stay where they are waiting for any decision… Comments welcome. Partagez cet article / Share This

11 October 2007

Lars Wirzenius: Random hacks: Unperish 2.0

I've just released a new, completely re-written version of Unperish, my program to automate the mechanical steps of releasing a free software project. It is now completely based on plugins, so it should be easy to adapt to other people's needs than mine. For example, although it currently only supports Bazaar as a version control system, it should be quite easy to write a plugin for any other one. After that is done, the rest of the existing plugins will still work, and can take care of things like building a Debian package with pbuilder, checking it with lintian, linda, and piuparts, and putting the results in an apt repository. Git, for example, should be especially easy. I haven't written a git plugin yet myself, since I don't use git. The README has instructions for writing plugins, and if anything is unclear, please ask me. I'd be more than happy to include any such plugins, or changes to plugins, that other people want to make.

Russell Coker: Getting People into IT

Pia writes about the difficulty in getting young women and young people in general into the computer industry [1]. While I agree that having more women in the computer industry would be a good thing, I have difficulty believing some of the claims that Pia makes. For example the claim that “[girls] are more career focused earlier in their school life“. I chose my career when I was about 11 years old [2] and several of my friends made similar decisions at similar ages. I would be interested to read anecdotal evidence from women in the computer industry about how old they were when they decided on their career and if their friends did the same, a reference to any research on this topic would also be useful. I tend to believe that boys are more career focussed at all stages of their life but have little evidence to support this idea. One fact that seems obvious is that the idea that “if you don’t succeed in your career then you can always marry someone who does” is almost non-existent among boys. It seems likely that such ideas have a statistically relevant affect on the focus on career of boys vs girls. Also the Australian Bureau of Statistics reports that the MEDIAN income for women is significantly lower than for men [4], I find it difficult to imagine that girls could be more career focussed from a younger age and yet get significantly lower pay (note the fact that it’s median not mean income is very significant as it removes the “glass ceiling” effect). Phillip Greenspun writes about why there are so few women doing scientific research [6] and makes some good points about why scientific research is generally not well paid and therefore a university student would choose a career in some other area and suggests that it’s a macho thing that guys enter such competitive fields for relatively low wages. Maybe some women correctly assess the costs and benefits of a career in scientific research and then make the mistake of equating Computer Science to other branches of science. But the median income suggests that although there may be some valid reasons for avoiding science that would only cover a small portion of the problem (the difference in median income can not be explained by misplaced attempts to maximise income). One problem that is significant is the quality of school education for girls. Not only is there the issue that boys may crowd-out girls for some subjects that are supposedly traditionally for boys (such as all science) but even girls schools aren’t as good as they should be. Some time ago I was talking to a teacher at an all-girls school, the school was moderately expensive and parents were paying the extra money presumably to give their daughters educational opportunities that they might miss in a co-ed school. However the school did not teach hard maths (”Maths B” was the official name at the time) and only taught the easy maths (official name “Maths A” and unofficial name “Vegie Maths“) because they didn’t have many girls demanding it (which is probably difficult to measure if you don’t offer it as a reasonable option) and the girls who wanted to study it could always move to a different school. So the choice facing girls at the exclusive school in question was “skip the subject that is most useful for further studies in most science subjects” or “go to a different school and miss most of your friends“, this sort of decision would surely discourage some potential female computer programemers. Also I think that the difference between boys and girls in regard to studying computer science has a lot to do with the fact that given a choice between missing most of their friends and missing out on something related to computers would be a no-brainer for most boys. Paul Graham’s article about Nerds has some interesting points to make in this regard - maybe the problem is that girls aren’t Nerdish enough [5]. Pia also writes about parents and teachers advising children not do study IT because of a perceived lack of jobs. I think that the problem here is not just bad advice, but also a bad tendency to take advice. Someone who wants to study in an established field which changes little over time (law and accounting spring to mind) probably should take careful note of the advice that they are given - things haven’t changed much in the last few decades. But someone who wants to study in a field that changes rapidly and where every year has new and significant developments (of which the best example is the computer industry) should probably be quite skeptical of all advice - most advice about the computer industry concerns how things used to be not how things are. Finally when considering whether to accept advice you should consider who is offering it. For example advice from a hiring manager should be carefully noted (as the manager will tell you precisely what factors influence their own decisions on hiring). Advice from people who are successful in the industry should also be noted. Advice from a school career advisor who gets paid about 1/3 what any 25yo can earn in the computer industry should be entirely ignored. I wonder whether being hesitant to ignore advice is a problem for girls in this regard. When I was in year 11 I had to take a subject related to career planning. It covered some things that were of minor use (such as writing CVs) and had an assignment of writing a fictional CV for yourself a few years after leaving university. I received bad marks for preparing a CV that involved changing jobs as companies went bankrupt or projects failed due to bad management, I was told that if your employer fails in the market it makes you look bad! However my fictional CV did bear some resemblance to what really happened… In terms of what industries have jobs available, the best advice I can give students is to actively do some research of their own. It’s not difficult to get the jobs sections of some newspapers and do a quick scan to see how many positions are open in a field, and it’s even easier to do some searches on online jobs sites (which usually tell you how many positions posted in the last X days match your criteria). For example I just visited jobserve.com.au and found 1724 Engineering jobs and 5622 IT jobs advertised. If you compare this to the university intake (I visited the Swinburne university courses list [3] and found 25 IT courses vs 29 Engineering course) it seems that the ratio of Engineering graduates to jobs is not likely to be as good as that for CS graduates. Of course it may be that all the other universities have hardly any Engineering courses and balance the ratio out (but I doubt it). In any case this would be a good way of injecting some facts into a discussion of the relative merits of different career choices and avoiding it being an issue of parents/teachers not liking computers vs children liking them. Determining the relative pay rates of different industries is a lot more difficult (and requires a significant amount of work), some recruiting agencies publish statistics - but those stats only apply to the positions that they fill (which is a sub-set of the actual positions). Finally as a piece of advice for children, try and find a job that you enjoy. If you earn $30K doing something you enjoy then you’ll probably be happier than if you earn $100K doing something you hate. Also if you enjoy your work then you will probably be able to take the extra steps needed to become successful - often it’s not a choice between having fun or making good money but a choice between fun and good money or the absence of both. If someone tells you to avoid doing what you love and instead do something boring for some unsubstantiated belief that there would be more money in it then be a nerd and tell them that their opinion is not relevant (it does tend to make teachers angry though).

Joey Hess: introducing mr

Mr. Who? No.. mr is a Multiple Repository management tool. With lots of people using svn with no real reason to switch, and some people using git because it's the cool thing of the day, I need a way to be able to checkout and update from multiple repositories, in multiple revison control systems. There are probably many scripts already written to do this; mr(1) is my attempt, and since it's very configurable and has a very short name, perhaps it will be useful to others in this situation. An example is probably worth 1347 words (according to wc -w mr). One thing not shown here is that it can look for .mrconfig files not just in the home directory, but inside the repositories it checks out.
joey@kodama:~/src> mr update
mr update: in /home/joey/src/dpkg
Already up-to-date.
Already up-to-date.
mr update: in /home/joey/src/linux-2.6
Already up-to-date.
mr update: in /home/joey/src/mr
Already up-to-date.
mr update: finished (3 sucessful; 1 skipped)
Here's my current ~/.mrconfig file.
[src/mr]
checkout = git clone ssh://git.kitenet.net/srv/git/kitenet.net/mr
[src/linux-2.6]
checkout = git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
# I only check this out on kodama, otherwise skip it.
skip = test $(hostname) != kodama
[src/dpkg]
# A merge of the upstream dpkg git repo and my own personal branch.
checkout = git clone git://git.debian.org/git/dpkg/dpkg.git && \
        cd dpkg && \
        git remote add kite ssh://kitenet.net/srv/git/kitenet.net/dpkg && \
        git fetch kite && \
        git checkout -b sourcev3 kite/sourcev3
update = git pull origin master && git pull kite sourcev3
commit = git push kite
# My home directory, which I keep in svn.
[]
checkout = svn co svn+ssh://svn.kitenet.net/srv/svn/joey/trunk/home-$(hostname) joey
# run svnfix after each update
update = svn update && svnfix
PS, what should "mr clean" do?

10 October 2007

Martin F. Krafft: Packaging with Git

Introduction I gave a joint presentation with Manoj at Debconf7 about using distributed version control for Debian packaging, and I volunteered to do an on-line workshop about using Git for the task, so it's about time that I should know how to use Git for Debian packaging, but it turns out that I don't. Or well, didn't. After I made a pretty good mess out of the mdadm packaging repository (which is not a big problem as it's just ugly history up to the point when I start to get it right), I decided to get down with the topic and figure it out once and for all. I am writing this post as I put the pieces together. It's been cooking for a week, simply so I could gather enough feedback. I am aware that Git is not exactly a showcase of usability, so I took some extra care to not add to the confusion. It may be the first post in a series, because this time, I am just covering the case of mdadm, for which upstream also uses Git and where I am the only maintainer, and I shall pretend that I am importing mdadm to version control for the first time, so there won't be any history juggling. Future posts could well include tracking Subversion repositories with git-svn, and importing packages previously tracked therewith, but this ain't no promise! (well, that last post is already being drafted, but far from finished; you have been warned!) I realise that git-buildpackage exists, but imposes a rather strict branch layout and tagging scheme, which I don't want to adhere to. And gitpkg (Romain blogged about it recently), deserves another look since, according to its author, it does not impose anything on its user. But in any case, before using such tools (and possibly extending them to allow for other layouts), I'd really rather have done it by hand a couple of times to get the hang of it and find out where the culprits lie. Now, enough of the talking, just one last thing: I expect this blog post to change quite a bit as I get feedback. Changes shall be highlighted in bold typeface.
Setting up the infrastructure First, we prepare a shared repository on git.debian.org for later use (using collab-maint for illustration purposes), download the Debian source package we want to import (version 2.6.3+200709292116+4450e59-3 at time of writing, but I pretend it's -2 because we shall create -3 further down ), set up a local repository, and link it to the remote repository. Note that there are other ways to set up the infrastructure, but this happens to be the one I prefer, even though it's slightly more complicated:
$ ssh alioth
$ cd /git/collab-maint
$ ./setup-repository pkg-mdadm mdadm Debian packaging
$ exit
$ apt-get source --download-only mdadm
$ mkdir mdadm && cd mdadm
$ git init
$ git remote add origin ssh://git.debian.org/git/collab-maint/pkg-mdadm
$ git config branch.master.merge refs/heads/master
Now we can use git-pull and git-push, except the remote repository is empty and we can't pull from there yet. We'll save that for later. Instead, we tell the repository about upstream's Git repository. I am giving you the git.debian.org URL though, simply because I don't want upstream repository (which lives on an ADSL line) hammered in response to this blog post:
$ git remote add upstream-repo git://git.debian.org/git/pkg-mdadm/mdadm
Since we're using the upstream branch of the pkg-mdadm repository as source (and don't want all the other mess I created in that repository), we'll first limit the set of branches to be fetched (I could have used the -t option in the above git-remote command, but I prefer to make it explicit that we're doing things slightly differently to protect upstream's ADSL line).
$ git config remote.upstream-repo.fetch \
    +refs/heads/upstream:refs/remotes/upstream-repo/upstream
And now we can pull down upstream's history and create a local branch off it. The "no common commits" warning can be safely ignored since we don't have any commits at all at that point (so there can't be any in common between the local and remote repository), but we know what we're doing, even to the point that we can forcefully give birth to a branch, which is because we do not have a HEAD commit yet (our repository is still empty):
$ git fetch upstream-repo
warning: no common commits
[ ]
  # in the real world, we'd be branching off upstream-repo/master
$ git checkout -b upstream upstream-repo/upstream
warning: You appear to be on a branch yet to be born.
warning: Forcing checkout of upstream-repo/upstream.
Branch upstream set up to track remote branch
  refs/remotes/upstream-repo/upstream.
$ git branch
* upstream
$ ls   wc -l
77
Importing the Debian package Now it's time to import Debian's diff.gz remember how I pretend to use version control for package maintenance for the first time. Oh, and sorry about the messy file names, but I decided it's best to stick with real data in case you are playing along: Since we're applying the diff against version 2.6.3+200709292116+4450e59, we ought to make sure to have the repository at the same state. Upstream never "released" that version, but I encoded the commit ID of the tip when I snapshotted it: 4450e59, so we branch off there. Since we are actually tracking the git.debian.org pkg-mdadm repository instead of upstream, you can use the tag I made. Otherwise you could consider tagging yourself:
$ #git tag -s mdadm-2.6.3+200709292116+4450e59 4450e59
$ git checkout -b master mdadm-2.6.3+200709292116+4450e59
$ zcat ../mdadm_2.6.3+200709292116+4450e59-2.diff.gz   git apply
The local tree is now "debianised", but Git does not know about the new and changed files, which you can verify with git-status. We will split the changes made by Debian's diff.gz across several branches.
The idea of feature branches We could just create a debian branch, commit all changes made by the diff.gz there, and be done with it. However, we might want to keep certain aspects of Debianisation separate, and the way to do that is with feature branches (also known as "topic" branches). For the sake of this demonstration, let's create the following four branches in addition to the master branch, which holds the standard Debian files, such as debian/changelog, debian/control, and debian/rules:
  • upstream-patches will includes patches against the upstream code, which I submit for upstream inclusion.
  • deb/conffile-location makes /etc/mdadm/mdadm.conf the default over /etc/mdadm.conf and is Debian-specific (thus the deb/ prefix).
  • deb/initramfs includes the initramfs hook and script, which I want to treat separately but not submit upstream.
  • deb/docs similarly includes Debian-only documentation I add to the package as a service to Debian users.
If you're importing a Debian package using dpatch, you might want to convert every dpatch into a single branch, or at least collect logical units into separate branches. Up to you. For now, our simple example suffices. Keep in mind that it's easy to merge two branch and less trivial to split one into two. Why? Well, good question. As you will see further down, the separation between master and deb/initramfs actually makes things more complicated when you are working on an issue spanning across both. However, feature branches also bring a whole lot of flexibility. For instance, with the above separation, I could easily create mdadm packages without initramfs integration (see #434934), a disk-space-conscious distribution like grml might prefer to leave out the extra documentation, and maybe another derivative doesn't like the fact that the configuration file is in a different place from upstream. With feature branches, all these issues could be easily addressed by leaving out unwanted branches from the merge into the integration/build branch (see further down). Whether you use feature branches, and how many, or whether you'd like to only separate upstream and Debian stuff is entirely up to you. For the purpose of demonstration, I'll go the more complicated way.
Setting up feature branches So let's commit the individual files to the branches. The output of the git-checkout command shows modified files that have not been committed yet (which I trim after the first example); Git keeps these across checkouts/branch changes. Note that the ./debian/ directory does not show up as Git does not know about it yet (git-status will tell you that it's untracked, or rather: contains untracked files since Git does not track directories at all):
$ git checkout -b upstream-patches mdadm-2.6.3+200709292116+4450e59
M Makefile
M ReadMe.c
M mdadm.8
M mdadm.conf.5
M mdassemble.8
M super1.c
$ git add super1.c     #444682
$ git commit -s
  # i now branch off master, but that's the same as 4450e59 actually
  # i just do it so i can make this point 
$ git checkout -b deb/conffile-location master
$ git add Makefile ReadMe.c mdadm.8 mdadm.conf.5 mdassemble.8
$ git commit -s
$ git checkout -b deb/initramfs master
$ git add debian/initramfs/*
$ git commit -s
$ git checkout -b deb/docs master
$ git add RAID5_versus_RAID10.txt md.txt rootraiddoc.97.html
$ git commit -s
  # and finally, the ./debian/ directory:
$ git checkout master
$ chmod +x debian/rules
$ git add debian
$ git commit -s
$ git branch
  deb/conffile-location
  deb/docs
* master
  upstream
  upstream-patches
At this time, we push our work so it won't get lost if, at this moment, aliens land on the house, or any other completely plausible event of apocalypse descends upon you. We'll push our work to git.debian.org (the origin, which is the default destination and thus needs not be specified) by using git-push --all, which conveniently pushes all local branches, thus including the upstream code; you may not want to push the upstream code, but I prefer it since it makes it easier to work with the repository, and since most of the objects are needed for the other branches anyway after all, we branched off the upstream branch. Specifying --tags instead of --all pushes tags instead of heads (branches); you couldn't have guessed that! See this thread if you (rightfully) think that one should be able to do this in a single command (which is not git push refs/heads/* refs/tags/*)
$ git push --all
$ git push --tags
Done. Well, almost
Building the package (theory) Let's build the package. There seem to be two (sensible) ways we could do this, considering that we have to integrate (merge) the branches we just created, before we fire off the building scripts:
  1. by using a temporary (or "throw-away") branch off upstream, where we integrate all the branches we have just created, build the package, tag our master branch (it contains debian/changelog), and remove the temporary branch. When a new package needs to be built, we repeat the process.
  2. by using a long-living integration branch off upstream, into which we merge all our branches, tag the branch, and build the package off the tag. When a new package comes around, we re-merge our branches, tag, and build.
Both approaches have a certain appeal to me, but I settled for the second, for two reasons, the first of which leads to the second:
  1. When I upload a package to the Debian archive, I want to create a tag which captures the exact state of the tree from which the package was built, for posterity (I will return to this point later). Since the throw-away branches are not designed to persist and are not uploaded to the archive, tagging the merging commit makes no sense. Thus, the only way to properly identify a source tree across all involved branches would be to run git-tag $branch/$tagname $branch for each branch, which is purely semantic and will get messy sooner or later.
  2. As a result of the above: when Debian makes a new stable release, I would like to create a branch corresponding to the package in the stable archive at the time, for security and other proposed updates. I could rename my throw-away branch, if it still existed, or I could create a new branch and merge all other branches, using the (semantic) tags, but that seems rather unfavourable.
So instead, I use a long-living integration branch, notoriously tag the merge commits which produced the tree from which I built the package I uploaded, and when a certain version ends up in a stable Debian release, I create a maintenance branch off the one, single tag which corresponds to the very version of the package distributed as part of the Debian release. So much for the theory. Let's build, already!
Building the package (practise) So we need a long-living integration branch, and that's easier done than said:
$ git checkout -b build mdadm-2.6.3+200709292116+4450e59
Now we're ready to build, and the following procedure should really be automated. I thus write it like a script, called poor-mans-gitbuild, which takes as optional argument the name of the (upstream) tag to use, defaulting to upstream (the tip):
#!/bin/sh
set -eu
git checkout master
debver=$(dpkg-parsechangelog   sed -ne 's,Version: ,,p')
git checkout build
git merge $ 1:-upstream 
git merge upstream-patches
git merge master
for b in $(git for-each-ref --format='%(refname)' refs/heads/deb/*); do
  git merge -- $b
done
git tag -s debian/$debver
debuild   # will ignore .git automatically
git checkout master
Note how we are merging each branch in turn, instead of using the octopus merge strategy (which would create a commit with more than two parents) for reasons outlined in this post. An octopus-merge would actually work in our situation, but it will not always work, so better safe than sorry (although you could still achieve the same result). If you discover during the build that you forgot something, or the build script failed to run, just remove the tag, undo the merges, checkout the branch to which you need to commit to fix the issue, and then repeat the above build process:
$ git tag -d debian/$debver
$ git checkout build
$ git reset --hard upstream
$ git checkout master
$ editor debian/rules    # or whatever
$ git add debian/rules
$ git commit -s
$ poor-mans-gitbuild
Before you upload, it's a good idea to invoke gitk --all and verify that all goes according to plan:
screenshot of gitk after the above steps
When you're done and the package has been uploaded, push your work to git.debian.org, as before. Instead of using --all and --tags, I now specify exactly which refs to push. This is probably a good habit to get into to prevent publishing unwanted refs:
$ git push origin build tag debian/2.6.3+200709292116+4450e59-3
Now take your dog for a walk, or play outside, or do something else not involving a computer or entertainment device.
Uploading a new Debian version If you are as lucky as I am, the package you uploaded still has a bug in the upstream code and someone else fixes it before upstream releases a new version, then you might be in the position to release a new Debian version. Or maybe you just need to make some Debian-specific changes against the same upstream version. I'll let the commands speak for themselves:
$ git checkout upstream-patches
$ git-apply < patch-from-lunar.diff   #444682 again
$ git commit --author 'J r my Bobbio <lunar@debian.org>' -s
  # this should also be automated, see below
$ git checkout master
$ dch -i
$ dpkg-parsechangelog   sed -ne 's,Version: ,,p'
2.6.3+200709292116+4450e59-3
$ git commit -s debian/changelog
$ poor-mans-gitbuild
$ git push
$ git push origin tag debian/2.6.3+200709292116+4450e59-3
That first git-push may require a short explanation: without any arguments, git-push updates only the intersection of local and remote branches, so it would never push a new local branch (such as build above), but it updates all existing ones; thus, you cannot inadvertedly publish a local branch. Tags still need to be published explicitly.
Hacking on the software Imagine: on a rainy Saturday afternoon you get bored and decide to implement a better way to tell mdadm when to start which array. Since you're a genius, it'll take you only a day, but you do make mistakes here and there, so what could be better than to use version control? However, rather than having a branch that will live forever, you are just creating a local branch, which you will not publish. When you are done, you'll feed your work back into the existing branches. Git makes branching really easy and as you may have spotted, the poor-mans-gitbuild script reserves an entire branch namespace for people like you:
$ git checkout -b tmp/start-arrays-rework master
Unfortunately (or fortunately), fixing this issue will require work on two branches, since the initramfs script and hook are maintained in a separate branch. There are (again) two ways in which we can (sensibly) approach this:
  • create two separate, temporary branches, and switch between them as you work.
  • merge both into the temporary branch and later cherry-pick the commits into the appropriate branches.
I am undecided on this, but maybe the best would be a combination: merge both into a temporary branch and later cherry-pick the commits into two additional, temporary branches until you got it right, and then fast-forward the official branches to their tips:
$ git merge master deb/initramfs
$ editor debian/mdadm-raid                     #  
$ git commit -s debian/mdadm-raid
$ editor debian/initramfs/script.local-top     #  
$ git commit -s debian/initramfs/script.local-top
[many hours of iteration pass ]
[  until you are done]
$ git checkout -b tmp/start-arrays-rework-init master
  # for each commit $c in tmp/start-arrays-rework
  # applicable to the master branch:
$ git cherry-pick $c
$ git checkout -b tmp/start-arrays-rework-initramfs deb/initramfs
  # for each commit $c in tmp/start-arrays-rework
  # applicable to the deb/initramfs branch:
$ git cherry-pick $c
This is assuming that all your commits are logical units. If you find several commits which would better be bundled together into a single commit, this is the time to do it:
$ git cherry-pick --no-commit <commit7>
$ git cherry-pick --no-commit <commit4>
$ git cherry-pick --no-commit <commit5>
$ git commit -s
Before we now merge this into the official branches, let me briefly intervene and introduce the concept of a fast-forward. Git will "fast-forward" a branch to a new tip if it decides that no merge is needed. In the above example, we branched a temporary branch (T) off the tip of an official branch (O) and then worked on the temporary one. If we now merge the temporary one into the official one, Git determines that it can actually squash the ancestry into a single line and push the official branch tip to the same ref as the temporary branch tip. In cheap (poor man's), ASCII notation:
- - - O             >> merge T >>     - - - = - - OT
         - - T      >>  into O >>
This works because no new commits have been made on top of O (if there would be any, we might be able to rebase, but let's not go there quite yet; rebasing is how you shoot yourself in the foot with Git). Thus we can simply do the following:
$ git checkout deb/initramfs
$ git merge tmp/start-arrays-rework-initramfs
$ git checkout master
$ git merge tmp/start-arrays-rework-init
and test/build/push the result. Or well, since you are not an mdadm maintainer (We^W I have open job positions! Applications welcome!), you'll want to submit your work as patches via email:
$ git format-patch -s -M origin/master
This will create a number of files in the current directory, one corresponding for each commit you made since origin/master. Assuming each commit is a logical unit, you can now submit these to an email address. The --compose option lets you write an introductory message, which is optional:
$ git send-email --compose --to your@email.address <file1> <file2> < >
Once you've verified that everything is alright, swap your email address for the bug number (or the pkg-mdadm-devel list address). Thanks (in advance) for your contribution! Of course, you may also be working on a feature that you want to go upstream, in which case you'd probably branch off upstream-patches (if it depends on a patch not yet in upstream's repository), or upstream (if it does not):
$ git checkout -b tmp/cool-feature upstream
[ ]
when a new upstream version comes around After a while, upstream may have integrated your patches, in addition to various other changes, to give birth to mdadm-2.6.4. We thus first fetch all the new refs and merge them into our upstream branch:
$ git fetch upstream-repo
$ git checkout upstream
$ git merge upstream-repo/master
we could just as well have executed git-pull, which with the default configuration would have done the same; however, I prefer to separate the process into fetching and merging. Now comes the point when many Git people think about rebasing. And in fact, rebasing is exactly what you should be doing, iff you're still working on an unpublished branch, such as the previous tmp/cool-feature off upstream. By rebasing your branch onto the updated upstream branch, you are making sure that your patch will apply cleanly when upstream tries it, because potential merge conflicts would be handled by you as part of the rebase, rather than by upstream:
$ git checkout tmp/cool-feature
$ git rebase upstream
What rebasing does is quite simple actually: it takes every commit you made since you branched off the parent branch and records the diff and commit message. Then, for each diff/commit_message pair, it creates a new commit on top of the new parent branch tip, thus rewrites history, and orphans all your original commits. Thus, you should only do this if your branch has never been published or else you would leave people who cloned from your published branch with orphans.
If this still does not make sense, try it out: create a (source) repository, make a commit (with a meaningful commit message), branch B off the tip, make a commit on top of B (with a meaningful message), clone that repository and return to the source repository. There, checkout the master, make a commit (with a ), checkout B, rebase it onto the tip of master, make a commit (with a ), and now git-pull from the clone; use gitk to figure out what's going on.
So you should almost never rebase a published branch, and since all your branches outside of the tmp/* namespace are published on git.debian.org, you should not rebase those. But then again, Pierre actually rebases a published branch in his workflow, and he does so with reason: his patches branch is just a collection of branches to go upstream, from which upstream cherry-picks or which upstream merges, but which no one tracks (or should be tracking). But we can't (or at least will not at this point) do this for our feature branches (though we could treat upstream-patches that way), so we have to merge. At first, it suffices to merge the new upstream into the long-living build branch, and to call poor-mans-gitbuild, but if you run into merge conflicts or find that upstream's changes affect the functionality contained in your feature branches, you need to actually fix those. For instance, let's say that upstream started providing md.txt (which I previously provided in the deb/docs branch), then I need to fix that branch:
$ git checkout deb/docs
$ git rm md.txt
$ git commit -s
That was easy, since I could evade the conflict. But what if upstream made a change to Makefile, which got in the way with my configuration file location change? Then I'd have to merge upstream into deb/conffile-location, resolve the conflicts, and commit the change:
$ git checkout deb/conffile-location
$ git merge upstream
CONFLICT!
$ git-mergetool
$ git commit -s
When all conflicts have been resolved, I can prepare a new release, as before:
$ git checkout master
$ dch -i
$ dpkg-parsechangelog   sed -ne 's,Version: ,,p'
2.6.3+200709292116+4450e59-3
# git commit -s debian/changelog
$ poor-mans-gitbuild
# git push
$ git push origin tag debian/2.6.3+200709292116+4450e59-3
Note that Git often appears smart about commits that percolated upstream: since upstream included the two commits in upstream-patches in his 2.6.4 release, my upstream-patches branch got effectively annihilated, and Git was smart enough to figure that out without a conflict. But before you rejoice, let it be told that this does not always work.
Creating and using a maintenance branch Let's say Debian "lenny" is released with mdadm 2.7.6-1, then:
$ git checkout -b maint/lenny debian/2.7.6-1
You might do this to celebrate the release, or you may wait until the need arises. We've already left the domain of reality ("lenny" is not yet released), so the following is just theory. Now, assume that a security bug is found in mdadm 2.7.6 after "lenny" was released. Upstream is already on mdadm 2.7.8 and commits deadbeef and c0ffee fix the security issue, then you'd cherry-pick them into the maint/lenny branch:
$ git checkout upstream
$ git pull
$ git checkout maint/lenny
$ git cherry-pick deadbeef
$ git cherry-pick c0ffee
If there are no merge conflicts (which you'd resolve with git-mergetool), we can just go ahead to prepare the new package:
$ dch -i
$ dpkg-parsechangelog   sed -ne 's,Version: ,,p'
2.7.6-1lenny1
$ git commit -s debian/changelog
$ poor-mans-gitbuild
$ git push origin maint/lenny
$ git push origin tag debian/2.7.6-1lenny1
Future directions It should be trivial to create the Debian source package directly from the repository, and in fact, in response to a recent blog post of mine on the dispensability of pristine upstream tarballs, two people showed me their scripts to do it. My post also caused Joey Hess to clarify his position on pristine tarballs, before he went out to implement dpkg-source v3. This looks very promising. Yet, as Romain argues, there are benefits with simple patch management systems. Exciting times ahead! In addition to creating source packages from version control, a couple of other ideas have been around for a while:
  • create debian/changelog from commit log summaries when you merge into the build branch.
  • integrate version control with the BTS, bidirectionally:
    • given a bug report, create a temporary branch and apply any patches found in the bug report.
    • upon merging the temporary branch back into the feature branch it modifies, generate a patch, send it to the BTS and tag the bug report + pending patch.
And I am sure there are more. If you have any, I'd be interested to hear about them!
Wrapping up I hope this post was useful. Thank you for reading to the end, this was probably my longest blog post ever. I want to thank Pierre Habouzit, Johannes Schindelin, and all the others on the #git/freenode IRC channel for their tutelage. Thanks also to Manoj Srivastava, whose pioneering work on packaging with GNU arch got me started on most of the concepts I use in the above. And of course, the members of the the vcs-pkg mailing list for the various discussions on this subject, especially those who participated in the thread leading up to this post. Finally, thanks to Linus and Junio for Git and the continuously outstanding high level of support they give. If you are interested in the topic of using version control for distro packaging, I invite you to join the vcs-pkg mailing list and/or the #vcs-pkg/irc.oftc.net IRC channel. NP: Aphex Twin: Selected Ambient Works, Volume 2 (at least when I started writing )

Adam Rosi-Kessel: MBTA Responds

To follow up on yesterday’s MBTA philippic, I received a response from the T’s customer service regarding my complaints. Although it doesn’t give me hope that things will improve, it’s nice that they have at least hired someone to write personalized, polished replies. At least they can do that right:
Dear Mr. Kessel, Thank you for your email concerning service on the Needham Line. The past couple of months have been difficult for our passengers, and I want you to know we are very sorry for the inconveniences this has been causing. The causes of these delays have ranged from signal and mechanical issues to long stops boarding passengers at stations, and even track work on other lines. I know that it may seem odd that trains on other lines can impact your trains, but I assure you that is true. The Franklin, Needham, Providence, and Stoughton lines, as well as Amtrak all share the rail between Hyde Park and Boston. All it takes is one delayed train in this area to cause a cascading effect that delays other lines. There’s also the fact that trains may come in from one line to go out as another. For example, a train on the Worcester Line comes to Boston, and either the train set, or the crew (sometimes both) head out as an outbound Needham train. If the inbound is late from Worcester, then the outbound Needham will be late, which also means that its “turn,” the next inbound, will be delayed. In response to your comment about the doors not all being opened, even with a full compliment of conductors, crews are not able to staff every door, and especially at ground level stations we want to ensure that all customers are able to board and detrain safely. This is why conductors do not open all doors to the train. I contacted our Mechanical Department, asking that the PA system on train 625 be checked out to make sure everything is working properly. Please know that delays in service are not something that we take lightly, and all departments are committed to working together to ensure that our customers receive timely, safe, and reliable service. Once again, I am sorry for the inconvenience this has caused you. Thank you for writing. Sincerely, Linda Dillon
MBCR Customer Service Manager

Antti-Juhani Kaijanaho: It s time to fix the ABI

SELinux is entirely correct about disallowing dynamic code generation, as it is a major security risk. Disregarding Just-In-Time compilation, the main legitimate need for dynamic code generation is to support (downward) closures that are ABI-compatible with normal C functions. GCC’s local functions extension of C is one example, and many non-C languages need them badly in their foreign-function interfaces (Haskell is one, Ada I’m told is another). A closure is a function pointer that refers to a function that is local to another function. That function has access to the local variables of the parent function, and this access is provided by having the caller give the callee a static link (a pointer to the parent function’s stack frame) as a hidden parameter. If the call is direct (that is, not through a function pointer), the caller knows the appropriate static link and can just pass it. The trouble comes with function pointers, as we need some way of including the static link in the function pointer. The simplest way is to have function pointers be two words long; one of the words contains the classical function pointer (that is, the entry point address), and the other contains the static link. Unfortunately, the prevalent C ABIs, including the SYSV ABI used by GNU/Linux, mandate that function pointers are one word long. The only way I know to work around this is to dynamically generate, when the function pointer is created, a small snippet of code that loads the correct static link to the appropriate place and jumps to the actual code of the function, and use the address of this snippet (usually called a trampoline) as the function pointer. The snippet is generated on the stack or in the heap, and thus requires an executable stack or executable dynamic memory. It’s time to fix the ABI to allow for proper two-word function pointers.

Russell Coker: Execmem and SE Linux

Eddy writes about problems getting the game oolite to run under SE Linux [1]. Strangely after I fixed the shared object issue with libffcall1 (as described in my previous post [2]) it appeared to work for me. Eddy asked how to allow one application to create write and executable memory regions without allowing such access for all programs. This can be done, in the targeted policy the type unconfined_execmem_exec_t triggers a transtion to the domain unconfined_execmem_t which permits the execstack and execmem operations. For example if the program /usr/bin/foo needs such access then the command chcon -t unconfined_execmem_exec_t /usr/bin/foo will change the type and the next time the program is launched from an unconfined session (a user login session, cron job, or daemon which is not constrained) then the change will apply.

9 October 2007

Russell Coker: How SE Linux Prevents Local Root Exploits

In a comment on my previous post about SE Linux and worms/trojans [1] a user enquired about which methods of gaining local root are prevented by SE Linux. A local exploit is one that can not be run remotely. An attack via TCP or UDP is generally considered a remote exploit - even though in some cases you might configure a daemon to only bind to localhost (in which case the TCP or UDP attack would only work locally). When compromising a machine it’s not uncommon for a local exploit to be used after a remote exploit or social engineering has been used to gain non-root privileges. The two most common types of local root exploit seem to be those which attack the kernel and those which attack a SETUID process. For a non-SE Linux system it usually doesn’t matter much how the local exploit is run. But a SE Linux system in a default configuration will be running the Targeted policy that has almost no restrictions on a user shell session. So an attacker who wants to escalate their privileges from local user to local root on a typical SE Linux system has a significant benefit in starting from a user account instead of starting from a web server or other system process. In the SE Linux model access is granted to a domain, and the domain which is used for a process is determined by the policy based on the domain of the parent process and the labelling of the executable. Some domains are not permitted to transition to any other domains, such as the domain dhcpd_t (used for a DHCP server). Other domains are only permitted to transition to a small set of domains, for example the domain httpd_t (used for a web server) can only transition to a small number of domains none of which has any significant privileges. On a machine running without SE Linux a compromise of a DHCP server is game-over as the server runs as root. A compromise of a daemon such as Apache on a machine without SE Linux gives unrestricted access to run applications on the systems - if a SETUID-root program has a security flaw then you lose. The same bug in a SETUID program on a machine running SE Linux is not fatal because SE Linux will prevent the program from doing anything that it’s parent could not do - even if an attacker made Apache run a buggy SETUID program the broken program in question could do nothing other than what Apache is normally permitted to do. A security flaw in a SETUID-root program on a SE Linux system can still be exploited by a local user (someone who has logged in) when running the Targeted policy. When running the Strict or MLS policies many such vulnerabilities will not be exploitable by local users (for example exploiting PING would only permit network access). As a rule of thumb you should consider that a kernel security flaw will make it possible to bypass all other security features. However there are some situations where SE Linux can prevent local exploits. One example is a bug discovered in July 2006 which allowed the creation of SETUID files under /proc [2], the targeted policy of SE Linux prevented this from working. Another example is CVE-2003-0127 [3] (a kernel security flaw that was exploited by triggering a module load and then exploiting a race condition in the kernel module load process), the commonly used exploit for this did not work on a SE Linux system because the user process was not permitted the socket access used to trigger the module load (it is believed that an attacker could have written a version of the exploit to work on a SE Linux system - but AFAIK no-one ever did so).

Chris Lamb: Optimal solution for the block stacking problem found

I attended an interesting seminar on the block stacking problem today given by Professor Mike Paterson of the University of Warwick. Like all good problems, it can be stated simply: how far can a stack of n identical blocks be made to hang over the edge of a table? The answer was widely believed to be of order log n (like the white shaded example above), but Mike Paterson and Uri Zwick previously constructed overhangs of order n^ 1/3 . In the seminar today, Paterson and his co-authors presented their proof that order n^ 1/3 is indeed the upper bound possible, resolving a long-standing mathematical problem. Professor Paterson is an excellent orator, highly recommended.

Next.

Previous.