summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2011-11-07 23:43:41 +0100
committerLudovic Courtès <ludo@gnu.org>2011-11-07 23:43:41 +0100
commit170e28da4e96be1ad05de180c3b157ca48ff1f26 (patch)
tree03c2c3c34b5e0a361ee45c4b1f296c813cc47289
parentab5584af46001e8f9ceb1f9406c1da4b4df57d1d (diff)
Allow /hurd/init to be a symlink.
* libdiskfs/boot-start.c (diskfs_start_bootstrap): Retry `dir_lookup' calls for INITNAME until either SYMLOOP_MAX is reached or the lookup process completes.
-rw-r--r--libdiskfs/boot-start.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index e73e4d37..15563bdb 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,10
+ Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,10,11
Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -104,6 +104,7 @@ diskfs_start_bootstrap ()
struct protid *rootpi;
struct peropen *rootpo;
mach_port_t diskfs_exec;
+ unsigned int init_lookups = 0;
/* Create the port for current and root directory. */
err = diskfs_make_peropen (diskfs_root_node, O_READ | O_EXEC, 0,
@@ -222,8 +223,10 @@ diskfs_start_bootstrap ()
initname = exec_argv + 1;
}
+ lookup_init:
err = dir_lookup (root_pt, initname, O_READ, 0,
&retry, pathbuf, &startup_pt);
+ init_lookups++;
if (err)
{
printf ("\nCannot find startup program `%s': %s\n",
@@ -232,6 +235,15 @@ diskfs_start_bootstrap ()
free (exec_argv);
assert_perror (err); /* XXX this won't reboot properly */
}
+ else if (retry == FS_RETRY_MAGICAL && pathbuf[0] == '/')
+ {
+ assert (init_lookups < SYMLOOP_MAX);
+
+ /* INITNAME is a symlink with an absolute target, so try again. */
+ initname = strdupa (pathbuf);
+ goto lookup_init;
+ }
+
assert (retry == FS_RETRY_NORMAL);
assert (pathbuf[0] == '\0');