[PATCH 0/2] first stab at NOFORK applet support

Rob Landley rob at landley.net
Fri May 5 14:49:25 UTC 2006


On Friday 05 May 2006 2:37 am, Denis Vlasenko wrote:
> Hi Rob,
>
> I looked at implementing NOFORK as discussed a while ago.
>
> Two following patches are a RFC. They add a bss_size field
> to struct BB_applet and global bss_buffer, which is
> 	memset(bss_buffer, 0 applet->bss_size);
> just before applet invocation. This allows for repeated calls
> of an applet from e.g. shell with correctly zeroed-out bss.

It should be possible to do this without anybody having to know what a bss is.  
If we consolidate the global and static variables each applet uses into a 
single structure, and then have that structure be in a union of all such 
structures, we can memset that based on sizeof(struct) and not have to .

> Also patches convert one applet (sed) so that it has neither
> initialized data section nor bss section. #defines in quickshell.h
> are provided to make it easier.
>
> Conversion goes like this:
>
> 1) Remove 'static' keyword, bracket all bss variables in
>    BEGIN_BSS/END_BSS (this places them in struct BSS_DATA).
>    check with "make objsizes" that you didn't miss anything.

Way too brittle in future.

> 2) Either globally s/var/B.var/g or add line
>        #define var B.var
>    for each variable

Is either gcc 4.0 or gcc 4.1 smart enough for this not to bloat the binary 
size with an extra dereference?  (If the structure is at a fixed location in 
the heap, then the structure member is too.  But I don't want to switch over 
until the compiler is capable of figuring this out, which gcc 2.95 definitely 
wasn't and I don't think 3.2 was either.  4.0 or 4.1 might be, though.  
They've got to have gained _something_ in exchange for the ability to build 
qemu 0.8.0 and bash 2.05b...)

> 3) edit line
> 	APPLET_DATA_SIZE(sed, <bss_size>, <data_size>)
>    in quickshell.h. Set bss_size to something greater
>    or equal [*] to total size of sed's bss.

We shouldn't have to know this.  The compiler should figure it out for us.  
Having to edit this by hand makes the app unmaintainable.

> 4) add line
>        CHECK_BSS_SIZE(sed);
>    at the beginning of sed_main()
>    (its's a compile check, no code generated)
>
> This will make sed use bss_buffer for all bss variables.

I like the idea, I think I'm going to work up a counter-proposal on the 
implementation, though.

> Initialized data is not yet handled. To be done
> after this RFC will be discussed.

Initialized data has to be initialized in main.  Not much alternative I can 
see.

> [*] Why? Because it is impractical to move struct BSS_DATA
>     definition out of sed.c into something.h and just use
>     sizeof(struct BSS_DATA_sed). Too many applets have
>     local structs and local vars with names which will
>     pollute namespace. This will wreak havoc.

Then those can't be converted to NOFORK yet.  We have to clean them up.

>     Just entering bss size by hand in quickshell.h
>     is a bit awkward, but at least I make compiler
>     check that entered value is not less than sizeof(BSS_SIZE_sed),
>     preventing a "bss is not entirely cleared" bug.
>     CHECK_BSS_SIZE(sed) does that check. Spesifying
>     too big a value is harmless (will memset a few extra bytes)
>
> Please comment...

I'll take a look.

The larger issue with nofork is that our code is littered with the assumption 
that we handle errors via exit().  Half the libbb functions do this, usually 
via error_msg_and_die.c.  Individual applets need to be audited to make sure 
they don't exit on error before we can mark them NOFORK.

Cleaning up globals so we don't allocate so much global data is a separate 
(but related) issue.

> --
> vda

Rob
-- 
Never bet against the cheap plastic solution.



More information about the busybox mailing list