Random idea...

Rob Landley rob at landley.net
Tue Feb 21 15:55:42 UTC 2006


On Tuesday 21 February 2006 4:05 am, Mike Frysinger wrote:
> On Tuesday 21 February 2006 01:27, Rob Landley wrote:
> > On Monday 20 February 2006 10:48 pm, Mike Frysinger wrote:
> > > On Monday 20 February 2006 22:40, Rob Landley wrote:
> > > > union {
> > > >   APPLET1_globals APPLET1;
> > > >   APPLET2_globals APPLET2;
> > > >   APPLET3_globals APPLET3;
> > > > } bb_globals __attribute_(not_aliased_to_anything,really,I_mean_it);
> > > >
> > > > <snip>
> > > > The upside is collapsing together all the statics so we use less
> > > > runtime memory.
> > >
> > > what about applets that call other applets w/out a [v]fork ?  having a
> > > great big union would prevent that from happening ...
> >
> > A) Right now, nobody's doing this.
>
> i thought one of the things we wanted to be able to do down the line was to
> have a busybox that could do a lot of things w/out fork/exec ... for
> example, if busybox was built against libgloss, there would be no kernel to
> handle the fork as busybox would be running on bare metal ... this isnt
> such an unrealistic idea as people have done it already to a small degree
> ...

My priority here is being able to run the standalone shell without having to 
exec /proc/self/exe.  (Having to have /proc mounted to use the standalone 
shell _sucks_.)

Beyond that, eliminating the fork is indeed cool.  But I wasn't thinking that 
would be for everything, I was thinking that would be for applets we mark 
with a flag in applets.h, ala:

USE_ECHO(APPLET(echo, echo_main, _BB_DIR_BIN, _BB_SUID_NEVER|__BB_NOFORK))

And mostly, I was thinking about the standalone shell not having to jump 
through hoops for things like "built in echo", and then extending that to be 
more generic where applicable.

> > B) So we vfork().  Why is that a problem?
>
> what i meant was without a fork or a vfork/exec ... vfork by itself wont
> work as the memory is shared between child and parent

Hmmm...  You're right.

I had a half-formed idea that fixing this was just "the standalone shell can't 
use the shared global union thing because it has to call other applets and 
memset() clear the space for them when it doesn't fork".  But yeah, that 
won't work for vfork.

But that's only half the story, the other half is when you want to fork and 
pipe stuff through gzip().  Except that has to be a _real_ fork, not a vfork, 
because your parent won't continue until the child calls exec...

Back to the standalone shell, to make the vfork() case work, what those 
applets really want to do is re-exec themselves (which is what the bounce off 
of /proc/self/exe is doing now).  In fact you'd need to do that because your 
parent won't continue until the child calls execve() or exit().  Doing 
vfork() without exec() really isn't an option.

If we don't fork at _all_, then what we need is the ability to move the shared 
data block in cases where sharing it doesn't work.  Which means that it can't 
simply be a global struct but has to be a pointer to a chunk of memory 
dynamically allocated by run_applet_by_name().  Which means less efficient 
code and potentially icky debugging to get it to work...

It sounds like what we want is a CONFIG option "vfork for standalone shell" 
which adds the bounce off of /proc/self/exe.  Actually, faking fork() with 
vfork() and exec("/proc/self/exe") could solve the gzip case above.  (Or just 
shellout to a process called "gunzip" found in the path and assume a sanely 
configured system: tar should do that...)

Yeah, I need to think about this more.  (Queue winnie the pooh tapping 
forehead: think-think, think think think...)

I'll worry about this when I do the first drop of bbsh.  Which is _after_ 
1.1.1...

> -mike

Rob
-- 
Never bet against the cheap plastic solution.



More information about the busybox mailing list