Weblogs from Hurd programmers and enthusiasts.
There are some similarities between the Hurd and Plan 9 regarding the file system handling -- but there are also very fundamental differences which go far beyond monolithic vs. microkernel design:
The Hurd is UNIX (POSIX) compatible
While (almost) all services are attached to the file system tree, not all services actually export a file system interface!
Personally, I advocate using FS-based interfaces as much as possible. Yet, there are some cases where they get very awkward and/or inefficient, and domain-specific interfaces simply make a lot more sense.
Also, some Hurd services are indeed used to implement the file systems in the first place -- they work below the FS level, and obviously can't use an FS interface!
File systems are completely decentralized -- clients always talk to the FS servers directly, without any central VFS layer. (I don't think that's the case in Plan 9?)
This offers much more flexibility -- the way the FS interfaces themselves work can be modified. Many things can be implemented as normal translators, that would require special VFS support on other systems. (Extended attributes, VFS-based union mounts, local namespaces, firmlink, magic file name suffixes etc.)
The system design allows users and applications to change almost all aspects of the system functionality in the local environment easily and without affecting other parts of the system.
(This is possible with Plan 9 to some extent; but the Hurd allows it at a much lower level -- including stuff like the filesystem interfaces, access control mechanisms, program execution and process management, and so on.)
I hope I didn't forget any major differences...
I wanted to import an old GNU arch repository into Git, but only had HTTP
access via ArchZoom. I spent quite some time to try teaching git archimport
to use HTTP access to that repository, but this didn't work out. Too bad --
but at least, using ArchZoom, I was able to get the individual revisions'
tarballs:
$ ls -1 *.tar.gz
bpf--devel--0.0--base-0.tar.gz
bpf--devel--0.0--patch-1.tar.gz
bpf--devel--0.0--patch-10.tar.gz
bpf--devel--0.0--patch-11.tar.gz
bpf--devel--0.0--patch-12.tar.gz
bpf--devel--0.0--patch-2.tar.gz
bpf--devel--0.0--patch-3.tar.gz
[...]
bpf--devel--0.0--patch-9.tar.gz
bpf--release--0.1--base-0.tar.gz
bpf--release--0.1--patch-1.tar.gz
bpf--release--0.1--patch-2.tar.gz
[...]
bpf--release--0.1--patch-8.tar.gz
I unpacked these:
$ for f in *.tar.gz; do tar -xz < "$f" || echo >&2 "$f" failed; done
The last revision's tree apparently contains all previous revisions' commit information (author, date, message), so use that:
$ cp -a ↩
bpf--release--0.1--patch-8/{arch}/bpf/bpf--devel/bpf--devel--0.0/info@hurdfr.org--hurdfr/patch-log ↩
d-patch-log
$ cp -a ↩
bpf--release--0.1--patch-8/{arch}/bpf/bpf--release/bpf--release--0.1/info@hurdfr.org--hurdfr/patch-log ↩
r-patch-log
... and extract the information that we need:
$ base=bpf--devel--0.0-- && ↩
for f in d-patch-log/*; do ↩
grep < "$f" ^Creator: | head -n 1 ↩
| { read j c && ↩
echo "$c" | sed s%' <.*'%% ↩
> "$base""$(basename "$f")".author_name && ↩
echo "$c" | sed -e 's%.*<%%' -e 's%>.*%%' ↩
> "$base""$(basename "$f")".author_email; } && ↩
grep < "$f" ^Standard-date: | head -n 1 | { read j d && echo "$d" ↩
> "$base""$(basename "$f")".author_date; } && ↩
{ grep < "$f" ^Summary: | head -n 1 | { read j m && echo "$m"; } && ↩
echo && sed < "$f" '1,/^$/d'; } ↩
> "$base""$(basename "$f")".log ↩
|| echo >&2 "$f" failed; ↩
done
$ base=bpf--release--0.1-- && ↩
for f in r-patch-log/*; [...]
(Of course, I could have used something more elaborate than shell scripting...)
Remove the GNU arch stuff that we don't need anymore:
$ find bpf--*/ -type d \( -name {arch} -o -name .arch-ids \) -print0 ↩
| xargs -0 rm -r
The base-0 revisions are actually either empty (the devel one) or
equivalent to the previous revision (the release one), so remove these:
$ rm -rf bpf--devel--0.0--base-0 bpf--release--0.1--base-0
Finally, import all the other ones:
$ mkdir g && ( cd g/ && git init )
$ for d in bpf--d*-? bpf--d*-?? bpf--r*; do ↩
test -d "$d"/ || continue && ↩
( cd g/ && ↩
rsync -a --delete --exclude=/.git ../"$d"/ ./ && ↩
git add . && ↩
GIT_AUTHOR_NAME="$(cat ../"$d".author_name)" ↩
GIT_AUTHOR_EMAIL="$(cat ../"$d".author_email)" ↩
GIT_AUTHOR_DATE="$(cat ../"$d".author_date)" ↩
git commit -F ../"$d".log -a ); ↩
done
Voilà!
Update 2009-06-25:
Half a day later, ?HurdFr published a git archimport-converted repository
-- which was identical to my hand-crafted one (apart from having
git-archimport-id: tags in the commit messages, and the first (empty) commit
not being stripped off). 
I was revisiting the issue of getting the Hurd's code base compiled with recent
versions of GCC. Specifically, there were a lot of duplicate symbols shown at
linking time, and all these were related to inline functions. Originally, in
2007, we had solved this problem already (or rather, shifted it) by using GCC's
-fgnu89-inline option, but as we saw now,
that one obviously doesn't help anymore if third-party code is using the Hurd's
unfixed header files.
So I was revisiting this issue. I was already prepared that this would take some hours, with lots of editing, compiling cycles, plus some analyzing of the binaries. So I made up a fresh repository for this work.
$ mkdir hurd-ei
$ cd hurd-ei/
$ git init
[...]
$ git remote add savannah git://git.savannah.gnu.org/hurd/hurd.git
$ git fetch
[...]
Switch to a new topic-branch.
$ git checkout -b master-ei savannah/master
Branch master-ei set up to track remote branch master from savannah.
Switched to a new branch 'master-ei'
(ei is short for extern inline.)
The first thing to do was to disable that -fgnu89-inline option, so I edited
Makeconf where it was added to CFLAGS.
I started editing, compiling, editing, compiling, and so on.
Finally, the tree was in a shape where everything was building fine and the resulting libraries contained the symbols they should, etc.
I committed the whole junk as one big blob commit, to store it in a safe place (you never know with these Hurd machines...), and to continue working on it the next day.
$ git commit -a
For the commit message, I already mostly assembled a ChangeLog-style log.
Then:
$ git format-patch savannah/master..
0001-Bla.patch
... and here is 0001-Bla.patch.bz2 (compressed).
The next day, a.k.a. today, in a different Git repository.
$ git checkout -b master-fix_inline savannah/master
Branch master-fix_inline set up to track remote branch master from savannah.
Switched to a new branch 'master-fix_inline'
$ bunzip2 < ../some/where/0001-Bla.patch.bz2 | git am
Applying: Bla.
The big blob is now on top of savannah/master (which was
2772f5c6a6a51cf946fd95bf6ffe254273157a21, by the way -- in case that you want
to reproduce this tutorial later, simply substitute savannah/master with
2772...).
By then, I had come to the conclusion that the commit essentially was fine, but
should be split into two, and the configure hunk shouldn't be in there. So
be it.
So, the HEAD of the active branch is our big blob commit that we want to
work on. Check with git show HEAD:
$ git show HEAD
commit 93e97f3351337c349e2926f4041e61bc487ef9e6
Author: Thomas Schwinge <tschwinge@gnu.org>
Date: Tue Jun 23 00:27:28 2009 +0200
Bla.
* console-client/timer.h (fetch_jiffies): Use static inline instead of extern
inline.
* ext2fs/ext2fs.h (test_bit, set_bit, clear_bit, dino, global_block_modified)
(record_global_poke, sync_global_ptr, record_indir_poke, sync_global)
(alloc_sync): Likewise.
* libftpconn/priv.h (unexpected_reply): Likewise.
* term/term.h (qsize, qavail, clear_queue, dequeue_quote, dequeue)
(enqueue_internal, enqueue, enqueue_quote, unquote_char, char_quoted_p)
(queue_erase): Likewise.
* ufs/ufs.h (dino, indir_block, cg_locate, sync_disk_blocks, sync_dinode)
(swab_short, swab_long, swab_long_long): Likewise.
* term/munge.c (poutput): Use static inline instead of inline.
* libdiskfs/diskfs.h: Apply inline optimization only ifdef
[__USE_EXTERN_INLINES]. Use __extern_inline instead of extern inline.
* libftpconn/ftpconn.h: Likewise.
* libpipe/pipe.h: Likewise.
* libpipe/pq.h: Likewise.
* libshouldbeinlibc/idvec.h: Likewise.
* libshouldbeinlibc/maptime.h: Likewise.
* libshouldbeinlibc/ugids.h: Likewise.
* libstore/store.h: Likewise.
* libthreads/rwlock.h: Likewise.
* libdiskfs/extern-inline.c: Adapt to these changes.
* libftpconn/xinl.c: Likewise. And don't #include "priv.h".
* libpipe/pipe-funcs.c: Likewise.
* libpipe/pq-funcs.c: Likewise.
* libshouldbeinlibc/maptime-funcs.c: Likewise. And remove superfluous
includes.
* libstore/xinl.c: Likewise.
* libthreads/rwlock.c: Likewise.
* Makeconf (CFLAGS): Don't append $(gnu89-inline-CFLAGS).
* pfinet/Makefile (CFLAGS): Append $(gnu89-inline-CFLAGS).
diff --git a/Makeconf b/Makeconf
index e9b2045..236f1ec 100644
--- a/Makeconf
+++ b/Makeconf
@@ -65,7 +65,7 @@ INCLUDES += -I$(..)include -I$(top_srcdir)/include
CPPFLAGS += $(INCLUDES) \
-D_GNU_SOURCE -D_IO_MTSAFE_IO -D_FILE_OFFSET_BITS=64 \
$($*-CPPFLAGS)
-CFLAGS += -std=gnu99 $(gnu89-inline-CFLAGS) -Wall -g -O3 \
+CFLAGS += -std=gnu99 -Wall -g -O3 \
[...]
We want to undo this one commit, but preserve its changes in the working directory.
$ git reset HEAD^
Makeconf: locally modified
configure: locally modified
console-client/timer.h: locally modified
ext2fs/ext2fs.h: locally modified
libdiskfs/diskfs.h: locally modified
libdiskfs/extern-inline.c: locally modified
libftpconn/ftpconn.h: locally modified
libftpconn/priv.h: locally modified
libftpconn/xinl.c: locally modified
libpipe/pipe-funcs.c: locally modified
libpipe/pipe.h: locally modified
libpipe/pq-funcs.c: locally modified
libpipe/pq.h: locally modified
libshouldbeinlibc/idvec.h: locally modified
libshouldbeinlibc/maptime-funcs.c: locally modified
libshouldbeinlibc/maptime.h: locally modified
libshouldbeinlibc/ugids.h: locally modified
libstore/store.h: locally modified
libstore/xinl.c: locally modified
libthreads/rwlock.c: locally modified
libthreads/rwlock.h: locally modified
pfinet/Makefile: locally modified
term/munge.c: locally modified
term/term.h: locally modified
ufs/ufs.h: locally modified
Now, HEAD points to the commit before the previous HEAD, i.e. HEAD^.
Again, check with git show HEAD:
$ git show HEAD
commit 2772f5c6a6a51cf946fd95bf6ffe254273157a21
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Thu Apr 2 23:06:37 2009 +0000
2009-04-03 Samuel Thibault <samuel.thibault@ens-lyon.org>
* exec.c (prepare): Call PREPARE_STREAM earlier to permit calling
finish_mapping on E even after errors, as is already done in do_exec.
diff --git a/exec/ChangeLog b/exec/ChangeLog
index 5a0ad1d..a9300bf 100644
--- a/exec/ChangeLog
+++ b/exec/ChangeLog
@@ -1,3 +1,8 @@
+2009-04-03 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * exec.c (prepare): Call PREPARE_STREAM earlier to permit calling
+ finish_mapping on E even after errors, as is already done in do_exec.
+
2008-06-10 Samuel Thibault <samuel.thibault@ens-lyon.org>
* elfcore.c (TIME_VALUE_TO_TIMESPEC): Completely implement instead of
diff --git a/exec/exec.c b/exec/exec.c
index 05dc883..cb3d741 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -726,6 +726,9 @@ prepare (file_t file, struct execdata *e)
e->interp.section = NULL;
+ /* Initialize E's stdio stream. */
+ prepare_stream (e);
[...]
Luckily, Git saves the previous (i.e. before the git reset) HEAD reference
as ORIG_HEAD. Have a look at it with git show ORIG_HEAD -- it contains the
big blob commit, including the preliminary commit message -- just what HEAD
was before:
$ git show ORIG_HEAD
commit 93e97f3351337c349e2926f4041e61bc487ef9e6
Author: Thomas Schwinge <tschwinge@gnu.org>
Date: Tue Jun 23 00:27:28 2009 +0200
Bla.
* console-client/timer.h (fetch_jiffies): Use static inline instead of extern
inline.
[...]
diff --git a/Makeconf b/Makeconf
index e9b2045..236f1ec 100644
--- a/Makeconf
+++ b/Makeconf
@@ -65,7 +65,7 @@ INCLUDES += -I$(..)include -I$(top_srcdir)/include
CPPFLAGS += $(INCLUDES) \
-D_GNU_SOURCE -D_IO_MTSAFE_IO -D_FILE_OFFSET_BITS=64 \
$($*-CPPFLAGS)
-CFLAGS += -std=gnu99 $(gnu89-inline-CFLAGS) -Wall -g -O3 \
+CFLAGS += -std=gnu99 -Wall -g -O3 \
[...]
OK, now let's pick the files that we want to have in the first of the envisioned two commits: these are the static inline instead of extern inline and apply inline optimization only... sections.
$ git add console-client/timer.h ext2fs/ext2fs.h [...] libthreads/rwlock.c
Oh, we forgot something: now that we're preparing this stuff to go into the master repository, update the copyright years. Edit, edit, edit, and then, again:
$ git add console-client/timer.h ext2fs/ext2fs.h [...] libthreads/rwlock.c
Now Git's staging area contains the changes that we want to commit (and the
working directory contains the rest of the big blob). Commit these added
files, and use big blob's commit message as a template for the new one, as it
already contains most of what we want (don't forget to chop off the unneeded
parts).
$ git commit -c ORIG_HEAD
Waiting for Emacs...
[master-fix_inline 51c15bc] Use static inline where appropriate.
6 files changed, 50 insertions(+), 51 deletions(-)
$ git show HEAD
commit c6c9d7a69dea26e04bba7010582e7bcd612e710c
Author: Thomas Schwinge <tschwinge@gnu.org>
Date: Tue Jun 23 00:27:28 2009 +0200
Use static inline where appropriate and use glibc's __extern_inline machinery.
* console-client/timer.h (fetch_jiffies): Use static inline instead of extern
inline.
* ext2fs/ext2fs.h (test_bit, set_bit, clear_bit, dino, global_block_modified)
(record_global_poke, sync_global_ptr, record_indir_poke, sync_global)
(alloc_sync): Likewise.
* libftpconn/priv.h (unexpected_reply): Likewise.
* term/term.h (qsize, qavail, clear_queue, dequeue_quote, dequeue)
(enqueue_internal, enqueue, enqueue_quote, unquote_char, char_quoted_p)
(queue_erase): Likewise.
* ufs/ufs.h (dino, indir_block, cg_locate, sync_disk_blocks, sync_dinode)
(swab_short, swab_long, swab_long_long): Likewise.
* term/munge.c (poutput): Use static inline instead of inline.
* libdiskfs/diskfs.h: Apply inline optimization only ifdef
[__USE_EXTERN_INLINES]. Use __extern_inline instead of extern inline.
* libftpconn/ftpconn.h: Likewise.
* libpipe/pipe.h: Likewise.
* libpipe/pq.h: Likewise.
* libshouldbeinlibc/idvec.h: Likewise.
* libshouldbeinlibc/maptime.h: Likewise.
* libshouldbeinlibc/ugids.h: Likewise.
* libstore/store.h: Likewise.
* libthreads/rwlock.h: Likewise.
* libdiskfs/extern-inline.c: Adapt to these changes.
* libftpconn/xinl.c: Likewise. And don't #include "priv.h".
* libpipe/pipe-funcs.c: Likewise.
* libpipe/pq-funcs.c: Likewise.
* libshouldbeinlibc/maptime-funcs.c: Likewise. And remove superfluous
includes.
* libstore/xinl.c: Likewise.
* libthreads/rwlock.c: Likewise.
diff --git a/console-client/timer.h b/console-client/timer.h
index 4204192..5e64e97 100644
--- a/console-client/timer.h
+++ b/console-client/timer.h
@@ -1,5 +1,7 @@
/* timer.h - Interface to a timer module for Mach.
- Copyright (C) 1995,96,2000,02 Free Software Foundation, Inc.
+
+ Copyright (C) 1995, 1996, 2000, 2002, 2009 Free Software Foundation, Inc.
+
Written by Michael I. Bushnell, p/BSG and Marcus Brinkmann.
This file is part of the GNU Hurd.
@@ -54,7 +56,7 @@ int timer_remove (struct timer_list *timer);
/* Change the expiration time of the timer TIMER to EXPIRES. */
void timer_change (struct timer_list *timer, long long expires);
-extern inline long long
+static inline long long
[...]
As you can see, HEAD now points to the new commit on top of the current
branch. (ORIG_HEAD doesn't change.)
On to the next, and last one, only two changes should be left: the Makeconf
and pfinet/Makefile ones.
$ git status
# On branch master-fix_inline
# Your branch is ahead of 'savannah/master' by 1 commit.
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: Makeconf
# modified: configure
# modified: pfinet/Makefile
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# 0001-Bla.patch
# autom4te.cache/
# hurd_extern_inline_fix.patch?file_id=18191
no changes added to commit (use "git add" and/or "git commit -a")
Alright, there is as well still the configure hunk that we want to get rid
of. But first for the real second commit, after editing for again adding the
copyright year update:
$ git add Makeconf pfinet/Makefile
$ git commit -c ORIG_HEAD
Waiting for Emacs...
[master-fix_inline 6a967d1] We're now C99 inline safe -- apart from the Linux code in pfinet.
2 files changed, 6 insertions(+), 3 deletions(-)
Check that we're in a clean state now:
$ git status
# On branch master-fix_inline
# Your branch is ahead of 'savannah/master' by 2 commits.
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: configure
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# 0001-Bla.patch
# autom4te.cache/
# hurd_extern_inline_fix.patch?file_id=18191
no changes added to commit (use "git add" and/or "git commit -a")
Oops, we forgot something...
$ git checkout -- configure
Now, our tree is clean again. (Check with git status.)
By now, we came to the conclusion that the first of the two commits should have been further split into two separate ones. Of course, essentially we would do the same splitting again that we've done just now -- but how to easily modify the first commit, now that we have another one on top of it?
Alright, git rebase --interactive to the rescue -- let's interactively
rebase the last two commits, to modify them as wanted.
$ git rebase --interactive HEAD~2
Waiting for Emacs...
Emacs wants us to tell which commits we want to keep as they are (pick),
which should be merged into others (squash), and which we want to edit. In
our scenario, we want to edit the first one and pick the second one.
Change the file thusly and close it.
Stopped at 5becbb5... Use static inline where appropriate and use...
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
We want to undo this first commit to split it into two. Again, use git reset
for that, while preserving the commit's changes in the working directory.
$ git reset HEAD^
console-client/timer.h: locally modified
[...]
Pick the set of files that we want to have in the first of the envisioned two commits: the static inline instead of extern inline section, and commit them, again using the previous commit message as a template for the new one:
$ git add console-client/timer.h ext2fs/ext2fs.h [...] term/munge.c
$ git commit -c ORIG_HEAD
Waiting for Emacs...
[detached HEAD 51c15bc] Use static inline where appropriate.
6 files changed, 50 insertions(+), 51 deletions(-)
Next part: apply inline optimization only.... Again, git add those files
that shall be part of the next commit, i.e. all remaining ones. As before, use
the previous commit message as a template.
$ git add libdiskfs/diskfs.h [...] libthreads/rwlock.c
$ git commit -c ORIG_HEAD
Waiting for Emacs...
[detached HEAD 8ac30ea] [__USE_EXTERN_INLINES]: Use glibc's __extern_inline machinery.
16 files changed, 508 insertions(+), 356 deletions(-)
Now we're done with splitting that commit into two. (Check with git status
that we didn't forget anything.) What's missing is getting back the other
commit on top of the two now-split ones:
$ git rebase --continue
Successfully rebased and updated refs/heads/master-fix_inline.
Here we go. The other commit has been applied on top of the two new ones.
Due to time-honored tradition, I always double-check what I have just committed, before distributing it to the world:
$ git log --reverse -p -C --cc savannah/master..
... and promptly, I recognize some changes that shouldn't be in there: when
using it on some files, Emacs' copyright-fix-years, aside from indeed fixing
the list of copyright years, and adding the current year, also changed GPL
... version 2 into version 3, which would be nice, but which we can't do for
the moment. The error is present only in the first and second commit. If it
were in only in the third (the last) one, simply editing the files, and then
using git commit --amend would be the solution. But again there is the
problem about how to modify the first (HEAD~2) and second (HEAD~1, or
HEAD^) commit now that there is another one on top of it. By now, we know
the solution:
$ git rebase --interactive HEAD~3
Waiting for Emacs...
This time, we need to edit the first and second commits, and pick the third
one.
Stopped at ffd215b... Use static inline where appropriate.
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
git show (which defaults to showing HEAD, by the way) can again be used to
have a look at the current HEAD (which is the first of the three commits),
and then we revert the unwanted changes in the editor, resulting with the
following changed files:
$ git status
# Not currently on any branch.
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: ext2fs/ext2fs.h
# modified: libftpconn/priv.h
# modified: term/munge.c
# modified: term/term.h
# modified: ufs/ufs.h
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# 0001-Bla.patch
# autom4te.cache/
# hurd_extern_inline_fix.patch?file_id=18191
no changes added to commit (use "git add" and/or "git commit -a")
Then, we can -- as git rebase suggested above -- amend the existing HEAD
commit with these changes (--amend and --all), reusing HEAD's commit
message without spawning an editor (-C HEAD):
$ git commit --amend -C HEAD --all
[detached HEAD c6c9d7a] Use static inline where appropriate.
6 files changed, 45 insertions(+), 46 deletions(-)
Continue with the next commit:
$ git rebase --continue
Stopped at 8ac30ea... [__USE_EXTERN_INLINES]: Use glibc's __extern_inline machinery.
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
Again, have a look at the commit (git show), revert the unwanted changes,
amend HEAD, and continue to the next commit:
$ git commit --amend -C HEAD --all
[detached HEAD 9990dc6] [__USE_EXTERN_INLINES]: Use glibc's __extern_inline machinery.
16 files changed, 500 insertions(+), 348 deletions(-)
$ git rebase --continue
Stopped at 6a967d1... We're now C99 inline safe -- apart from the Linux code in pfinet.
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
Two files are left to be edited (git show, etc., again), and finally:
$ git commit --amend -C HEAD --all
[detached HEAD 241c605] We're now C99 inline safe -- apart from the Linux code in pfinet.
2 files changed, 5 insertions(+), 2 deletions(-)
$ git rebase --continue
Successfully rebased and updated refs/heads/master-fix_inline.
That's it. git log --reverse -p -C --cc savannah/master.. now looks as nice
as can be.
Of course, this is only a small insight of what is possible to do with git
rebase and friends -- see the manual for further explanations.
For a while I have been thinking about the lack of a roadmap for the Hurd; but now I realized that we lack something even more fundamental: a simple mission statement -- i.e. saying where we want to go, rather than how we want to get there. I think many of the problems we have are directly or indirectly related to that.
As we didn't have such a mission statement so far, the people currently involved have vastly different ideas about the mission, which of course makes it a bit hard to come up with a suitable one now. However, I managed to come up with something that I believe is generic enough so all contributors can subscribe to it:
The mission of the Hurd project is: to create a general-purpose kernel suitable for the GNU operating system, which is viable for everyday use, and gives users and programs as much control over their computing environment as possible.
"Suitable for GNU" in the first part implies a number of things. I explicitely mentioned "general-purpose", because this an important feature that sets the Hurd apart from many other microkernel projects, but isn't immediately obvious.
I didn't mention that it must be entirely free software, as this should be obvious to anyone familiar with GNU.
Another thing I did not mention, because it's too controversial: how much UNIX do we need? I think that being suitable for GNU requires a pretty high degree of UNIX compatibility, and also that the default environment looks to the user more or less like UNIX. However, some people claimed in the past that GNU could do without UNIX -- the wording used here doesn't totally preclude such views.
The second part also leaves a lot of slack: I for my part still believe that a Mach-based Hurd can be viable for everyday use; but those who think that a microkernel change is required, should be happy with this wording as well.
The third part tries to express the major idea behind the Hurd design in the most compact and generic way possible.
Hurd GSoC 2008 code_swarm
I created a code_swarm of the work done in the Hurd project during this years Google Summer of Code.
I hope you enjoy it!
PS: Now also available on vimeo thanks to scolobb!
Niches for the Hurd
In the bug-hud mailinglist we did a search for niches where the Hurd is the biggest fish in the pond.
This search was segmented into four distinct phases, three of them major:
- Brainstorm
- Reality check: can already do vs. could be used for
- Turn ideas into applications
- Find a compromise -> About which niches should we talk in the wiki?
Brainstorm
"Which niches could there be for the Hurd?"
Basic Results
The result is a mix of target groups, nice features and options of the Hurd, reasons for running a Hurd and areas where the Hurd offers advantages:
Nice features and options the Hurd offers
- Give back power to users: arbitrary mounts, subhurds
- Nice features: dpkg -iO ftp://foo/bar/*.deb
- Easier access to low-level functions
- Advanced lightweight virtualization
- operating system study purposes as its done with minix
- The possibility to create more efficient and powerful desktop environments
- Having a complete GNU System
- All-in-one out-of-the-box distro running a webserver for crash-proof operation.
Target groups and strong environments
- Tinkerers who like its design.
- multicore-systems
The keyphrases in more detail or with additional ideas
Give back power to users: arbitrary mounts, subhurds
Simpler virtual computing environments - no need to setup XEN, everyone can just open up his/her computer for someone else by creating a new user account, and the other one can login and easily adapt the system for his/her own needs. If most systems just differ by the translators setup on them, people could even transfer their whole environment from one computer to another one without needing root access or more root interaction than creating a new user account. "I want my tools" -> "no problem, just setup your translators".
Also it would be possible to just open an account for stuff like joining the "World Community Grid" allowing for easier sharing of CPU time.
Easier access to low-level functions
"One important use is for very technical people, who don't always go with standard solutions, but rather use new approaches to best solve their problems, and will often find traditional kernels too limiting."
"Another interesting aspect is application development: With the easily customized/extended system functionality, and the ability to contain such customizations in subenvironments, I believe that Hurd offers a good platform for much more efficient development of complex applications. Application developers can just introduce the desired mechanisms on a very low level, instead of building around existing abstractions. The extensible filesystem in particular seems extremely helpful as a powerful, intuitive and transparent communication mechanism, which allows creating truly modular applications."
Advanced lightweight virtualization
"There is also the whole area I called "advanced lightweight virtualization" (see http://tri-ceps.blogspot.com/2007/10/advanced-lightweight-virtualization.html ), i.e. the ability to create various kinds of interesting subenvironments. Many use cases are covered by much bigger fish; but the flexibility we offer here could still be interesting: I think the middle grounds we cover between directly running applications, and full isolation through containers or VMs, are quite unique. This could simplify management of demanding applications for example, by partially isolating them from other applications and the main system, and thus reducing incompatibilities. Creating lightweight software appliances sounds like an interesting option."
The possibility to create more efficient and powerful desktop environments
*"While I believe this can be applied to any kind of applications, I'm personally most interested in more efficient and powerful desktop environments -- these considerations are in fact what got me seriously interested in the Hurd.
Even more specifically, I've done most considerations (though by far not all) on modular web browsing environments. Those interested can read up some of my thoughts on this:
http://sourceforge.net/mailarchive/message.php?msg_name=20080909073154.GB821%40alien.local
(Just skip the text mode browsing stuff -- the relevant part is the long monologue at the end... I really should put these ideas into my blog.)"*
Nice features
Another example of features which would be easily possible with the Hurd:
transparent ftp (already possible!):
- settrans -c ftp: /hurd/hostmux /hurd/ftpfs /
- ls ftp://ftp.gnu.org/
- # -> list the files on the FTP server.
media-player translator:
- settrans play /hurd/mediaplayer_play
- cp song1.ogg song2.ogg play
- # -> files get buffered and played.
or even:
- cp ftp://foo/bar/ogg play
that's KDEs fabled network transparency on the filesystem / shell level.
Reality check
Check which of the ideas can already be done easily with the Hurd in its current state, which ones are a bit more complex but already possible, which ones need a bit of coding (could be accomplished in a few months judging from the current speed of development), which ones need a lot of work (or fundamental changes) and which ones aren't possible.
Already possible and easy
Sample translators:
- hello world.
- transparently bind FTP into the filesystem
- hostmux + ftpfs -> connect to FTP automatically via asking for a dir named after the hostname -> fully transparent FTP filesystem: "touch ftp: ; settrans ftp: /hurd/hostmux /hurd/ftpfs / "
- bind any filesystem at any place in the directory tree (you have access to) without needing to be root.
- elegantly mount iso images and similar as unprivileged user.
Other useful stuff:
- Install deb-packages from an ftp server via 'dpkg -iO ftp://foo/bar/*.deb'
- remount a filesystem readonly as regular user: fsysopts /foo -r
- give a process additional group and user permissions at runtime:
$ groups
root
$ ps -L # gives me the PID of my login bash -> bashPID
...
$ addauth -p bashPID -g mail
$ groups
root mail
Having a complete GNU System (but not yet on every hardware, and only about half the software Debian offers has been ported).
Already possible but complex or underdocumented
Easier access to low-level functions via translators.
Operating system study purposes as it's done with minix.
Tinkering for fun - need documentation about the fun things which can be done.
Need a few months of coding
A filesystem-based package manager.
subhurds for regular users
- A framework for confining individual applications is really just one possible use case of the hurdish subenvironments. Writing the tools necessary for that should be quite doable in a few months. It's probably not really much coding -- most of the work would be figuring out how it should be set up exactly.
- subusers
- "subdo":
# Example: Let a virus run free, but any effect vanishes
# once the subhurd closes.
$ subdo --no-lasting-changes ./virus
Running parts of the Hurd on different computers, maybe even with shared servers on dedicated hardware (Cloud Computing when the servers can be made to migrate from between computers). Maybe this should be placed in "need a lot of coding".
subhurds for quickly adapting the whole system without bothering others.
Define your personal environment via translators, so you can easily take it with you (translators written in scripting laguages can make this easier - they could also for example be taken to each computer on USB stick).
A more powerful alternative to FUSE filesystems: While FUSE is limited to standard filesystem semantics, while Hurd translators can implement whatever they want. It is possible to change the behaviour in any aspect, including the way file name lookup works. Admittedly the only specific use case I know is the possibility to implement namespace-based translator selection with a set of normal translators, without any changes to the Hurd itself. It is also possible to extend the filesystem interfaces, adding new RPCs and options as needed. This allows using the filesystem for communication, yet implementing domain-specific interfaces where standard filesystems are too unefficient or cumbersome. A sound server would be one possible use case.
Namespace based translator selection (if you for example want to quickly check the contents of an iso image, just look at them via 'ls image.iso,,iso9660fs').
Need a lot of coding or fundamental changes
Effective resource management (For example via Viengoos on which Neal Walfield is working). The idea is that we could make a virtue out of necessity: Once we have a proper resource management framework, we should be able not only to catch up with traditional systems in this reagard, but in fact surpass them.
The possibility to create more efficient and powerful desktop environments.
Multicore systems (need to fixup Mach for SMP)
Currently to offer CPU time to some project (like the World Community Grid), it is necessary to install a program from them, and they can then do only what that proram allows them to - which leads to reinventing a processing environment instead of just using the existing OS. With the Hurd people could just create a user for them, give that user specific permissions (like "you're always lowest priority"), add the public ssh keys of the project they want to donate CPU cycles to, and the project could just turn the computer into the environment it needs for the specific computation, without compromising the main system in any way (needs better resource management).
A shared MMORPG game world consisting simply of files for levels and person descriptions with access rights. All synchronizing is done on the translator level. Programs only have to display the given files and quickly update the state of their own files, so the programs stay very easy. The translator could notify the program when something changes.
Unfeasible ideas
Applications
A minor phase, which will surely be interleaved with the others: Making the ideas tangible to turn them into ways how people can use the Hurd.
"Hey, look, this is the Hurd. You can use it like this to do that which you can't do as well/easily/elegantly in any other way."
Applications for private use
Applications for companies
How an application should be presented so people can easily test and digest it
We need stuff which gets people to say "hey that's cool!"
And it must be readily available. If I have to search for arcane command line parameters before I can use it, it's too hard.
From what I see, each direct cool application must be about as simple as
$ qemu hurd-is-cool.img
$ login root
$ settrans cool /hurd/cool
$ ls cool
One main focus in this example is: No command line parameters but the ones we really need. No "-a", if the example is also cool without it. No "--console" if it works otherwise.
Especially no "qemu --cd livecd --hda hurd.img ..." - that one is great for people who already know qemu or want to learn it, but the goal here isn't to teach people better usage of qemu, but to show them that the Hurd is cool, and only that.
All that interesting advanced stuff just gets newcomers confused.
The translator concept in itself is enough news to faze a mind - anything else can easily be too much.
If the application isn't as simple as the example above, then the best step would be to see if we can make it as simple - if that involves writing trivial scripts than be it so. They are trivial only to those who already understand the underlying concepts.
And now enough with rambling
The Hurd is cool, and the complex to use applications are cool, too. But they are hard to present in a way newcomers easily understand.
Compromise
For each niche:
- What do we have to do to conquer the niche?
- How many additional programmers can the Hurd get in this niche?
- How does choosing this niche limit the flexibility of further development (for example due to the goals of the people who join up)?
- Can we easily move on to conquering the next niche once we got this one?
- What should the Hurd accomplish on the long term (long term goals)? Which possible niches help that?
Each participant:
- Give your personal priorities to the niches:
- Must -> all of these of all developers must be included; remember that at most 3 to 4 ideas can be conveyed in any text.
- Should -> The number of shoulds can be used for ranking and similar.
("must", because in a community people can do what they perceive as important, and telling someone to stop what he's doing is no option (in my opinion))
Things to do
todo-item -> niches for which it is useful.
Easy
- Port debian packages to the Hurd -> mainly tinkerers, but also any other niche.
Getting X to work on the GNU/Hurd
This is a try to get X to work in my qemu GNU/Hurd.
This is a first try, my next one will be with the ?guide from this wiki.
Firstoff: I used the following guides:
What I did
I worked as root.
First I installed xorg, x-window-system-code, rxvt and twm:
apt-get install xserver-xorg x-window-system-core rxvt twm
Then I set the LD_LIBRARY_PATH and DISPLAY
export LD_LIBRARY_PATH=/usr/X11R6/lib
export DISPLAY=localhost:0.0
After that I set the mouse and keyboard translator.
settrans /dev/kbd /hurd/kbd /dev/kbd
settrans -c /dev/mouse /hurd/mouse --protocol=ps/2
Then I started x
startx
It didn't work yet - but watch the blog for updates - I'll post once I get it working.
In the past few months the Hurd got quite many commits.
I want to write a bit about the changes they brought, and what they mean to the Hurd.
If some of my comments seem too 'simple' to you, just ignore them
First we got many Bug fixes from Samuel Thibault, mainly in libpthread (multithreading), ext2fs and libdiskfs (both filesystem interaction).
Then hurd-l4 (the port of the Hurd on the L4 kernel) seems to get quite much love by Neal H. Walfield (neal) at the moment.
Quite much is saying a bit to little: hurd-l4 looks steamingly active in the commits
And there is the PyHurd project. It attempts to create a full binding to the GNU/Hurd API, so people should someday be able to, for example, create translators in Python.
There's been more - a lot more in fact, but much of it is above my coding horizon, and this entry shall end someplace (it's late - too late
).
Best wishes, Arne
Today (OK, this night) I created some codeswarm movies to visualize the code history of the Hurd.
What's particularly interesting to me in gnumach is the tschwinge - sthibaul effect in march 2008, where development suddenly seems to speed up enormeously.
It clearly shows how much impact just two developers can have - you can have that kind of an impact, too!
The code movies are created from the history of the cvs branches gnumach, hurd-l4 and hurd.
The movies:
in gnumach, red is the "kern", while in "hurd" red is stuff in "release".
.doc. is dark blue and any stuff named .linux. is shown in a blue-green in both. In Hurd-L4 is annotated: It shows libc, gcc, Hurd and L4 kernel commits in different colors.
The hurd wiki movie shows all web commits as "web-hurd@gnu.org", and you can clearly see that most changes are being done via the version control system. There's a way to split the web-commits, but since there aren't many, I leave that for another day
- article on the ikiwiki page.
Best wishes, Arne
Yesterday I spent a few hours trying to get my german keyboard to let me use my umlauts (and to let me type without having to hunt down the right keys), but without much luck.
I got xkb installed after following this FaQ answer:
and this info:
(you can find the second under /etc/default/hurd-console ).
But I didn't get it to work.
What I did in short:
First I got the needed apt-sources:
Then I installed the xkb console:
apt-get install console-driver-xkb
And set it in the file /etc/default/hurd-console
Sadly it didn't work, but maybe this posts will give You the needed headstart for success
(I'd be glad to see a guide from you!).
Some additional info:
