[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <33832325-EF32-4C6D-B566-8B7CE179FF1C@mac.com>
Date: Mon, 20 Nov 2006 09:38:06 -0600
From: Mark Rustad <mrustad@....com>
To: Linux-Kernel mailing-list <linux-kernel@...r.kernel.org>
Cc: Simon Richter <Simon.Richter@...yros.de>
Subject: Re: RFC: implement daemon() in the kernel
On Nov 20, 2006, at 7:20 AM, Simon Richter wrote:
> [please CC me on replies]
>
> Hi,
>
> I'm working with Linux on MMUless systems, and one of the biggest
> issues
> in porting software is the lack of working fork().
>
> Except some special cases (like openssh's priviledge separation),
> fork()
> is called in mainly three cases:
>
> - spawn off a new process, which calls exec() immediately
>
> This can be easily replaced by a call to vfork(), which invokes the
> clone() syscall with the CLONE_VFORK flag.
>
> - split off some work into a separate thread and provide address
> space
> separation
>
> Since we don't have a MMU, there is no address space separation
> anyway,
> so we can replace this with a pthread_create(), which in turn calls
> clone().
>
> - daemonize a process
>
> There is a function called daemon() that does this; its behaviour is
> roughly defined by (modulo error handling)
>
> int daemon(int nochdir, int noclose)
> {
> if(!nochdir)
> chdir("/");
>
> if(!noclose)
> {
> int fd = open("/dev/null", O_RDWR);
> dup2(fd, 0);
> dup2(fd, 1);
> dup2(fd, 2);
> close(fd);
> }
>
> if(fork() > 0)
> _exit(0);
> }
>
> Since it calls _exit() right after fork() returns (so daemon() never
> returns to the calling process except in case of an error) it would be
> possible to implement this on MMUless machines if the last two lines
> could happen in the kernel.
>
> I can see three possible implementations:
>
> - "cheap" implementation
>
> The process is assigned a new PID and the parent is pretended to have
> exited. There are a lot of pitfalls here, so it is probably not a
> good idea.
>
> - a reverse vfork()
>
> The child process is created and suspended, the parent continues to
> run
> until it calls exec() or _exit(). The good thing here is that it
> should
> be easy to implement as the infrastructure for suspending a process
> until another exits already exists.
>
> - "normal" implementation
>
> The child is created, the parent immediately zombiefied with a return
> code of zero. This might be more difficult to implement as the current
> implementation of fork() does not need to terminate a process in any
> way, so there might be funny locking and other issues.
>
> Questions? Comments?
There is a better way. Simply implement fork(). It can be done even
without an MMU. People think it is impossible, but that is only
because they don't consider the possibility of copying memory back
and forth on task switch. It sounds horrible, but in the vast
majority of cases, either the parent or child either exits or does an
exec pretty quickly, so in reality it doesn't cost much. The benefits
are many: being able to use real shells such as bash and thereby
being able to use real shell scripts.
When I was at BRECIS we implemented this in a 2.4 uClinux kernel - as
well as in an OpenBSD port. I can't take any credit for this work - a
friend of mine did it - but at least I recognized that such a thing
was possible. Having seen the results of this before, this really is
the way to go to improve MMU-less systems.
You do have to look out for any applications that fork and do not
either exit or exec, but that is so much better than having to modify
so many things just to get them to run.
--
Mark Rustad, MRustad@....com
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists