Mechiel Lukkien | 3 Apr 2011 22:42

emu (or, instant inferno)

i've done some work on making it easier to install & use hosted
inferno.  the result is emuq [1].  for now i only made a binary for
windows (tested with windows xp):  emuq.exe.

short explanation:

emuq.exe is a slightly modified[2] emu.exe, with a builtin root file
system containing vacinit[3] and vacsrv[4].  upon "boot", vacinit
is called instead of the normal emuinit.  vacinit has a tk interface
that lets you select the "boot parameters" (variables).  among those 
parameters is a vac score (and venti server) to serve as root file
system.  after mounting the (read-only) root file system with vacsrv,
wm/wm is run.  emuq comes with (the score of) a root file system that
has a /lib/wmsetup modified to run /lib/vacwmsetup.  /lib/vacwmsetup uses
boot parameters to determine which commands to run.

emuq has defaults to do the following:

- bind your host os's $home/.. on /usr;  run $home/lib/vacwmsetup if 
  it exists.
- start ndb/cs, memfs for /tmp, mntgen for /n & /mnt
- start factotum & feedkey, and an agent for ssh keys
- try binding: #U* at /n/local, #Uc: at /n/c, #Ud: at /n/d
- ask for secstore information to initialize factotum
- ask for an sftp address to mount on /n/home
- add a few menu entries to wm/toolbar's menu.  e.g. one called
  "Ventistream".  running it fetches all scores referenced from the
  root file system vac score.
- run /n/home/lib/vacwmsetup if it exists

(Continue reading)

Alex Efros | 5 Apr 2011 09:59
Favicon
Gravatar

close(fd)

Hi!

Mechiel asked in IRC about closing file descriptors, and I'd like to
confirm here we doesn't missed anything.

Process may have some open file descriptors without having Sys->FD for them:
1) if it started by sh with some extra redirections:
    ; process >[10=1]
2) if it dup() some fd
3) if it parent opened some files (often with pipe()), and then this
   process did pctl(FORKFD,nil) (like mount(1) does)
4) … any other cases?

While there are no sys->close(), looks like only ways to close them are:
1) use dup() to replace file descriptor you wanna close with another fd
   which you needs open (this doesn't release file descriptor number,
   but it at least does close target opened file)
2) use Mechiel's "spawn close" trick:

	spawn close(list of {stdin.fd, otherfd}, csync := chan of int);
	<-csync;

	close(fds: list of int, sync: chan of int)
	{
		sys->pctl(Sys->FORKFD, fds);
		sync <-= 1;
	}

Is that correct, and there are no other ways to close fd?

(Continue reading)

roger peppe | 5 Apr 2011 11:03
Picon
Gravatar

Re: close(fd)

On 5 April 2011 08:59, Alex Efros <powerman@...> wrote:
> Hi!
>
> Mechiel asked in IRC about closing file descriptors, and I'd like to
> confirm here we doesn't missed anything.
>
> Process may have some open file descriptors without having Sys->FD for them:
> 1) if it started by sh with some extra redirections:
>    ; process >[10=1]
> 2) if it dup() some fd
> 3) if it parent opened some files (often with pipe()), and then this
>   process did pctl(FORKFD,nil) (like mount(1) does)
> 4) … any other cases?
>
> While there are no sys->close(), looks like only ways to close them are:
> 1) use dup() to replace file descriptor you wanna close with another fd
>   which you needs open (this doesn't release file descriptor number,
>   but it at least does close target opened file)
> 2) use Mechiel's "spawn close" trick:
>
>        spawn close(list of {stdin.fd, otherfd}, csync := chan of int);
>        <-csync;
>
>        close(fds: list of int, sync: chan of int)
>        {
>                sys->pctl(Sys->FORKFD, fds);
>                sync <-= 1;
>        }
>
> Is that correct, and there are no other ways to close fd?
(Continue reading)

Mechiel Lukkien | 5 Apr 2011 11:56

Re: close(fd)

On Tue, Apr 05, 2011 at 10:03:51AM +0100, roger peppe wrote:
> you can close most fds by simply nilling out the Sys->FD that
> points to them.
> 
> in my experience, case 1 isn't generally an issue.
> case 2 is only encountered when doing shell-like
> stuff, in which case you can do:
>   spawn {
>      FORKFD
>      dup
>      NEWFD
>    }
> when ends up with exactly the fds you want.

the reason for this was the following.  run:

% mount {mntgen} /tmp
% unmount /tmp

you'll see the mntgen processes are still lingering.
this is because, as powerman said, mount(1) passes both sides of the
styx pipe to mntgen, so mntgen never sees eof from the styxmsg reader.

so i made a patch (see the bottom of the mail).  i didn't like it,
so i wondered how it could be done better.

NEWFD would work if you know the exact list of fd's you need.  i thought
(this is the part i'm unsure about) that you shouldn't nullify the
effect of fd redirections on the shell command line.  that would break
something like this (fictional fd numbers):
(Continue reading)

roger peppe | 5 Apr 2011 13:05
Picon
Gravatar

Re: close(fd)

On 5 April 2011 10:56, Mechiel Lukkien <mechiel@...> wrote:
> On Tue, Apr 05, 2011 at 10:03:51AM +0100, roger peppe wrote:
>> you can close most fds by simply nilling out the Sys->FD that
>> points to them.
>>
>> in my experience, case 1 isn't generally an issue.
>> case 2 is only encountered when doing shell-like
>> stuff, in which case you can do:
>>   spawn {
>>      FORKFD
>>      dup
>>      NEWFD
>>    }
>> when ends up with exactly the fds you want.
>
> the reason for this was the following.  run:
>
> % mount {mntgen} /tmp
> % unmount /tmp
>
> you'll see the mntgen processes are still lingering.
> this is because, as powerman said, mount(1) passes both sides of the
> styx pipe to mntgen, so mntgen never sees eof from the styxmsg reader.
>
> so i made a patch (see the bottom of the mail).  i didn't like it,
> so i wondered how it could be done better.
>
> NEWFD would work if you know the exact list of fd's you need.  i thought
> (this is the part i'm unsure about) that you shouldn't nullify the
> effect of fd redirections on the shell command line.  that would break
(Continue reading)

Alex Efros | 5 Apr 2011 16:24
Favicon
Gravatar

Re: close(fd)

Hi!

On Tue, Apr 05, 2011 at 12:05:59PM +0100, roger peppe wrote:
> there are two solutions - neither very palatable.
> get rid of Sys->FD entirely and just use integers,
> or get rid of the fd table entirely and have Sys->FD
> point to the underlying Chan directly.
> 
> i think i favour the latter, but it has its disadvantages
> (for instance, no way to see what files a process currently
> has open).

If it possible to modify sys->fildes() to not duplicate fds which doesn't
have Sys->FD associated with them in current process, but instead create
and return new Sys->FD associated with that fd, then it will become
possible to close such fds simply with:

    sys->fildes(2);

or, more clear:

    tmp := sys->fildes(2);
    tmp = nil;

--

-- 
			WBR, Alex.

roger peppe | 5 Apr 2011 16:58
Picon
Gravatar

Re: close(fd)

On 5 April 2011 15:24, Alex Efros <powerman@...> wrote:
> Hi!
>
> On Tue, Apr 05, 2011 at 12:05:59PM +0100, roger peppe wrote:
>> there are two solutions - neither very palatable.
>> get rid of Sys->FD entirely and just use integers,
>> or get rid of the fd table entirely and have Sys->FD
>> point to the underlying Chan directly.
>>
>> i think i favour the latter, but it has its disadvantages
>> (for instance, no way to see what files a process currently
>> has open).
>
> If it possible to modify sys->fildes() to not duplicate fds which doesn't
> have Sys->FD associated with them in current process, but instead create
> and return new Sys->FD associated with that fd, then it will become
> possible to close such fds simply with:
>
>    sys->fildes(2);
>
> or, more clear:
>
>    tmp := sys->fildes(2);
>    tmp = nil;

if you're going to do that, you might just as well add sys->close IMHO.
otherwise eveyone that does:

sys->fprint(sys->fildes(2), ...)

(Continue reading)

Charles Forsyth | 5 Apr 2011 18:51

Re: close(fd)

>it tries to maintain the illusion that
>there's a one-to-one correspondence between Sys->FD
>and file descriptors, but there isn't, and it's very
>easy to get things wrong when using pctl.

independent of whether the set of primitives could be completely different,
or is an adequate set for what the system does attempt,
it isn't attempting to maintain that illusion.

Mechiel Lukkien | 6 Apr 2011 12:56

Re: close(fd)

On Tue, Apr 05, 2011 at 12:05:59PM +0100, roger peppe wrote:
> > NEWFD would work if you know the exact list of fd's you need.  i thought
> > (this is the part i'm unsure about) that you shouldn't nullify the
> > effect of fd redirections on the shell command line.  that would break
> > something like this (fictional fd numbers):
> >
> >        mount <>[4=0] {something using fd4} /tmp
> 
> yes, but already you can't guarantee that fds outside [0,1,2]
> are passed through to underlying processes, for precisely this
> reason.
> 
> for instance, this fails:
> 
> sh -c {wc /fd/4} <[4] /lib/keyboard

ok, so if i understand it correctly, this does not work because the shell
has no obligation to pass around anything other than fds 0,1,2, right?
if the shell did guarantee that all other fd's were passed untouched,
it should work?
just to get this clear, i'm fine with the shell only passing around 0,1,2.

> an alternative patch to mount, in the same spirit:
> 
> runcmd(sh: Sh, ctxt: ref Draw->Context, argv: list of string, stdin:
> ref Sys->FD, sync: chan of int)
> {
> 	sys->pctl(Sys->FORKFD, nil);
> 	sys->dup(stdin.fd, 0);
> 	stdin = nil;
(Continue reading)

Mechiel Lukkien | 6 Apr 2011 13:18

Re: emu (or, instant inferno)

On Sun, Apr 03, 2011 at 10:42:01PM +0200, Mechiel Lukkien wrote:
> emuq.exe is a slightly modified[2] emu.exe, with a builtin root file

some notes about the modifications in the vacinit branch:

- i added the env variable $emuhome.  it points to the homedir of the
user that started emu.  $UserProfile on windows, $home on plan 9, $HOME
on the other systems.

- i removed the "rootdir" variable from emu/*/devfs*.c, put them in the
generated kernel config .c file, and initialized them to the new variable
ROOTDIR.  devfs ("#U") is the driver giving access to the host os file
system, and most importantly to the root directory of the inferno tree
(with all the .dis programs in it).  unmodified devfs's use $ROOT (the
build dir) for emu's root directory, and it's even hardcoded to \inferno
on windows.  this is a problem, because emu panics if the root directory
does not exist.  you can work around this by explicitly specifying
the rootdir with "emu -r ...", but for emuq i wanted to make things as
simple as possible (download & run, no command-lines).  so, variable
ROOTDIR is still defaults to $ROOT, but the emuq kernel configs set it to
"/" in their "env" sections.  all host os's are expected to have roots
named "/". :)

- the init section from the kernel config is used.  conf(10) says:
"For hosted kernels, emuinit is normally used, referring to /dis/emuinit.dis.".
emu/port/main.c hardcodes it to "/dis/emuinit.dis".  in most cases,
it suffices to specify an alternative file to use as /dis/emuinit.dis
in the root section of a kernel config.  but i did not want a "/dis"
in the builtin root filesystem, because i bind #/ in front of the vac
root dir in vacinit.  so that would leave me with an empty /dis directory.
(Continue reading)


Gmane