mksquashfs: fix limit on the number of dynamic pseudo files

Dynamic pseudo files exist to enable users to dynamically
create files which don't actually exist in the source filesystem,
where the contents of the file are obtained from running
a command or piece of shell.

For instance

"a_file f 0777 root root dmesg"

will create a file named "a_file", which has the output of "dmesg"
as its contents.

When I implemented "dynamic pseudo files" I anticipated they would
be used for a limited amount of files.  As such, when I implemented
them, I had Mksquashfs at start-up run through the set of dynamic
pseudo files and fork and exec the commands/shell upfront, with
Mksquashfs later reading from the pipes connecting the forked processes
at file system generation when that part of the filesystem was generated.

Doing this ensured maximum parallelism, as it allowed the forked
processes to run and produce output in parallel with Mksquashfs.  By
the time the output of the processes was needed in filesystem
generation it was anticipated the forked processes run in parallel
would have finished any computation, and would be waiting to output
(or if the output was small, it would already be buffered in the pipe).

But this strategy had a known defect.  It relied on the fact that
the total number of dynamic pseudo files when kicked off in their
entirety at Mksquashfs startup would not exceed process limits or
open file limits (each pipe created uses fds, and there's normally
omly 1024 that can be open at the same time by the ultimate parent
Mksquashfs process).  Due to the fact I assumed dynamic pesudo files
would be only used for a limited number of files, this seemed like
worrying about a defect that would never in practice occur.

But, quite unexpectedly, I received a bug report last year where
a user tried to do exactly that, a pseudo file with more than 1000
dynamic pseudo files, and of course Mksquashfs failed when the
maximum open file limit was reached.

So, this commit fixes that bug.  Dynamic pseudo file process creation
has been moved to the reader thread, and the process is created when
the output from that process is needed in filesystem generation, ensuring
the reader thread can read the sub-process' output and wait for it to die
and reap the resources used (pipe fds etc.) before starting another
dynamic pseudo file process.  This ensures the minimal amount of
processes/fds/memory is in use at any one time by the pseudo file
processes and therefore prevents users from "mis-using" the
dynamic pseudo facility to create a DOS (denial of service) situation
where system limits are exceeded.

Note, I do not suspect the user who reported the bug of trying to
deliberately exploit a weakness in Mksquashfs to generate a DOS
situation, this appears to be one of the cases where a user wanted
to create many dynamic pseudo files and came accross this bug
by accident.

But, this bug needed to be fixed, both for the users who need to
create lots of dynamic pseudo files, and to close a "system resource
exhaustion" vulnerability.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>