All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [uml-devel] filemap feature 2.4.22-5um
@ 2003-10-14 14:08 Steve Schmidtke
  0 siblings, 0 replies; 15+ messages in thread
From: Steve Schmidtke @ 2003-10-14 14:08 UTC (permalink / raw)
  To: doug; +Cc: user-mode-linux-devel

Doug Dumitru wrote:
>A couple of questions.  I noticed that you are not mapping /proc/mm.
[...]
>This looks like one per virtual process (minus threads).  Am I reading this 
>right.

yes. The discussion for a previous patch considered a "mm" table to hold a 
pool of /proc/mm files to handle one fd per process.  One side effect of 
this would place a hard limit on the number of processes in the UML: the 
number of /proc/mm files opened.  I'm not sure what side effects re-using 
/proc/mm files would have, either.  I should have mentioned TT/SKAS issues, 
but it slipped my mind (I only use TT mode). So to use skas in a chroot, 
you'll still have to mount /proc/mm in there.  Hopefully Jeff has a fix for 
/proc/mm in the works.

>On virtuals that I run, I tend to only see a single "vm" file opened:

yup. Things have changed since I looked at it for the last filemap patch 
*sigh*.  It used to be 1 file for every 256M of memory, but now, it is just 
one big happy file, so in SKAS mode you should need only one vm file entry.  
In TT mode there are a few more files required, but the max now seems to be 
3 or 4 entries.

>Is there any reason the tun/tap networking wouldn't work with this layout 
>by pre-opening /dev/net/tun.

Possibly, but you will have to check out the "TUN/TAP with a preconfigured 
tap device" section of the virtual networking howto as the uml_net helper 
won't pick up the filemapped fd for /dev/net/tun inside a chroot (nor will 
it likely have ifconfig or route binaries available).   Let me know if you 
get this to work.

Steve Schmidtke

_________________________________________________________________
The new MSN 8: advanced junk mail protection and 2 months FREE*  
http://join.msn.com/?page=features/junkmail



-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-18 21:57   ` Goetz Bock
@ 2003-10-18 22:29     ` Henrik Nordstrom
  0 siblings, 0 replies; 15+ messages in thread
From: Henrik Nordstrom @ 2003-10-18 22:29 UTC (permalink / raw)
  To: Goetz Bock; +Cc: User-mode-linux-devel

On Sat, 18 Oct 2003, Goetz Bock wrote:

> No, there is no need to be root inside a chrooted environment, or better
> yet you should not be.

The application running inside the chroot obviously should not be root, 
but the one who chroots it must be..

Toe point being that with mount --bind you can set up the chroot directory 
to give access to only the exact files needed before the application is 
started, even if these files normaly lives in a completely different 
location (i.e. /proc/mm and other special files)

Regards
Henrik



-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-18 12:37 ` Henrik Nordstrom
@ 2003-10-18 21:57   ` Goetz Bock
  2003-10-18 22:29     ` Henrik Nordstrom
  0 siblings, 1 reply; 15+ messages in thread
From: Goetz Bock @ 2003-10-18 21:57 UTC (permalink / raw)
  To: User-mode-linux-devel

[-- Attachment #1: Type: text/plain, Size: 1205 bytes --]


On Sat, Oct 18 '03 at 14:37, Henrik Nordstrom wrote:
> > It would be nice if a chroot wrapper could open the files and pass the 
> > "filemap=" config strings to your config parser.  Something like this:
> 
> What I do not quite get in this discussion is why one does not want to
> have the selected files available in the chroot in the first place?
> 
> To chroot you need to be root. As root you are also allowed to map files
> around using mount --bind.
No, there is no need to be root inside a chrooted environment, or better
yet you should not be.

I've created a patch to su (from coreutils) to allow root to chroot into
a given directory, than su to a user, and execute a binary (attached).

My uml setup for an uml instance includeds a /bin/ directory for each
user with one copy of the uml instance, the commandline than looks like
this

su -r /home/uml/utest utest -s /bin/utest  umid=utest ...

where utest is a user on the host.
-- 
/"\ Goetz Bock at blacknet dot de  --  secure mobile Linux everNETting
\ /                     (c) 2003 as GNU FDL 1.1
 X   [ 1. Use descriptive subjects - 2. Edit a reply for brevity -  ]
/ \  [ 3. Reply to the list - 4. Read the archive *before* you post ]

[-- Attachment #2: coreutils-5.0-su-chroot.patch.gz --]
[-- Type: application/x-gzip, Size: 1297 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
@ 2003-10-18 17:15 Steve Schmidtke
  0 siblings, 0 replies; 15+ messages in thread
From: Steve Schmidtke @ 2003-10-18 17:15 UTC (permalink / raw)
  To: hno, blaisorblade_spam; +Cc: User-mode-linux-devel

Henrik Nordstrom wrote:
>What I do not quite get in this discussion is why one does not want to
>have the selected files available in the chroot in the first place?

Check out Jeff's talk on UML security and chroot:

  http://user-mode-linux.sourceforge.net/slides/ists2002/text17.htm

>To chroot you need to be root. As root you are also allowed to map files
>around using mount --bind.

I can't really argue with that, except hundreds of /etc/mtab entries might 
be annoying :)  (yes, I know you could mount -n to hide them).

BlaisorBlade wrote:
>Alle 16:08, marted� 14 ottobre 2003, Steve Schmidtke ha scritto:
> > yes. The discussion for a previous patch considered a "mm" table to hold 
>a
> > pool of /proc/mm files to handle one fd per process.
> > [....]
>Nooo! Don't make your like hard!

It's making the crackers lives hard that I'm attempting; making mine 
difficult in the process is merely an occupational hazard.

>cd <chroot path>
>mkdir proc
>touch proc/mm #You must create the mount point. In this case it's a file.
>(as root)mount --bind /proc/mm proc/mm
><start Uml binary with "# chroot . linux ...." >

--bind is useful, and I'm trying to avoid it out of principle, not because I 
don't know about it.  In this case --bind would work because /proc/mm is 
writable by everyone, so when the chroot wrapper drops root, the UML can 
still access the file.  That is not the case for all files you may want to 
give a non-root UML access to.

>About the ugliness, it's only a userspace syntax matter. This is the v2 of 
>the
>umlwrap syntax. Instead of this:
>   umlwrap -bind=21,/dev/shm/mconsole1 -dir=/home/uml -- \
>   /bin/linux mem=48M uml_dir=/uml/ umid=um1 filemap=22,/uml/um1/pid \
>   22</dev/shm/pid filemap=21,/uml/um1/mconsole
>
>We can have this:
>   umlwrap -dir=/home/uml -bind=/dev/shm/mconsole1,/uml/um1/mconsole \
>   -map=r,/dev/shm/pid,/uml/um1/pid-- /bin/linux mem=48M uml_dir=/uml/ 
>umid=um1

Yup, that's what I'm leaning towards.

>umlwrap will then setup the needed "filemap" options, at the end of the
>command line.

The order of the command line arguments may be important:  filemap options 
should be parsed before options that reference them (i.e. they should come 
first, not last, on the command line).

>However, does UML(unlike vanilla kernel) supports so long(>512
>char) command lines in the internal kernel part, (in the userspace part 
>it's
>granted)? If not, we can use a patch out there that is already used by
>Knoppix.

Adam Heath is working on a patch for reading config files that will also 
make command line length irrelevant.  I like this approach since the UML 
command line wouldn't have to be mangled to add filemap options to it.

Steve Schmidtke

_________________________________________________________________
Fretting that your Hotmail account may expire because you forgot to sign in 
enough? Get Hotmail Extra Storage today!   
http://join.msn.com/?PAGE=features/es



-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
@ 2003-10-18 16:34 BlaisorBlade
  0 siblings, 0 replies; 15+ messages in thread
From: BlaisorBlade @ 2003-10-18 16:34 UTC (permalink / raw)
  To: user-mode-linux-devel

Alle 16:08, martedì 14 ottobre 2003, Steve Schmidtke ha scritto:
> Doug Dumitru wrote:
> >A couple of questions.  I noticed that you are not mapping /proc/mm.
>
> [...]
>
> >This looks like one per virtual process (minus threads).  Am I reading
> > this right.
>
> yes. The discussion for a previous patch considered a "mm" table to hold a
> pool of /proc/mm files to handle one fd per process.
> [....]

Nooo! Don't make your like hard!

Search for this thread "[uml-user] chroot'ing an UML - /proc/mm" on
http://marc.theaimsgroup.com/ !
You can use mount --bind inside the host to make /proc/mm visible to UML.
 I.e. it should be something such(NOT TRIED!):

cd <chroot path>
mkdir proc
touch proc/mm #You must create the mount point. In this case it's a file.
(as root)mount --bind /proc/mm proc/mm
<start Uml binary with "# chroot . linux ...." >

About the ugliness, it's only a userspace syntax matter. This is the v2 of
 the umlwrap syntax. Instead of this:
  umlwrap -bind=21,/dev/shm/mconsole1 -dir=/home/uml -- \
  /bin/linux mem=48M uml_dir=/uml/ umid=um1 filemap=22,/uml/um1/pid \
  22</dev/shm/pid filemap=21,/uml/um1/mconsole

We can have this:
  umlwrap -dir=/home/uml -bind=/dev/shm/mconsole1,/uml/um1/mconsole \
  -map=r,/dev/shm/pid,/uml/um1/pid-- /bin/linux mem=48M uml_dir=/uml/
 umid=um1

umlwrap will then setup the needed "filemap" options, at the end of the
command line. However, does UML(unlike vanilla kernel) supports so long(>512
char) command lines in the internal kernel part, (in the userspace part it's
granted)? If not, we can use a patch out there that is already used by
Knoppix.

By the way, if umlwrap is smart enough, maybe it can guess whether to use
-map, -bind or -connect by itself(at least partially, i.e. stating the file).
However this isn't a problem here. And for the length of settings, there is
scripting!

Bye
--
cat <<EOSIGN
Paolo Giarrusso, aka Blaisorblade
Linux Kernel 2.4.21/2.6.0-test on an i686; Linux registered user n. 292729
EOSIGN



-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-18  1:31 Steve Schmidtke
  2003-10-18 12:37 ` Henrik Nordstrom
@ 2003-10-18 14:27 ` Adam Heath
  1 sibling, 0 replies; 15+ messages in thread
From: Adam Heath @ 2003-10-18 14:27 UTC (permalink / raw)
  To: Steve Schmidtke; +Cc: User-mode-linux-devel

On Sat, 18 Oct 2003, Steve Schmidtke wrote:

> Though a bonus would be if your config file parser could handle input from a
> given fd as well. :)

Yes, it can.  :)



-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-18  1:31 Steve Schmidtke
@ 2003-10-18 12:37 ` Henrik Nordstrom
  2003-10-18 21:57   ` Goetz Bock
  2003-10-18 14:27 ` Adam Heath
  1 sibling, 1 reply; 15+ messages in thread
From: Henrik Nordstrom @ 2003-10-18 12:37 UTC (permalink / raw)
  To: Steve Schmidtke; +Cc: adam, User-mode-linux-devel

On Sat, 18 Oct 2003, Steve Schmidtke wrote:

> It would be nice if a chroot wrapper could open the files and pass the 
> "filemap=" config strings to your config parser.  Something like this:

What I do not quite get in this discussion is why one does not want to
have the selected files available in the chroot in the first place?

To chroot you need to be root. As root you are also allowed to map files
around using mount --bind.

Regards
Henrik



-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
@ 2003-10-18  1:31 Steve Schmidtke
  2003-10-18 12:37 ` Henrik Nordstrom
  2003-10-18 14:27 ` Adam Heath
  0 siblings, 2 replies; 15+ messages in thread
From: Steve Schmidtke @ 2003-10-18  1:31 UTC (permalink / raw)
  To: adam; +Cc: User-mode-linux-devel

Adam Heath wrote:
>On Tue, 14 Oct 2003, Steve Schmidtke wrote:
> >   filemap=file,10,/proc/cpuinfo 10</proc/cpuinfo \
>
>I have some unfinished code to make uml read a config file.  It fits in 
>nicely
>with the cmdline parsing.

It may help with half the problem here.  There are two parts, the
"filemap=10/proc/cpuinfo" config string to be parsed within the UML, and the 
"10</proc/cpuinfo" redirection in the parent shell.  The uglyness I see is 
the duplication that must be syncronized between the two.

It would be nice if a chroot wrapper could open the files and pass the 
"filemap=" config strings to your config parser.  Something like this:

  umlwrap -map=/proc/cpuinfo -bind=/tmp/uml.ctl \
  -config=tmp.file -- ./linux 32M config=tmp.file ...

The hypothetical umlwrap program opens /proc/cpuinfo (on fd 5, say -- you 
would no longer have to define it) and /tmp/uml.ctl (on fd 6).  The umlwrap 
program then builds the config strings "filemap=file,5,/proc/cpuinfo" and 
"filemap=file,6,/tmp/uml.ctl" and writes them out to tmp.file for the UML to 
pick up.  No more messing around with arbitrary file descriptors on the 
command line.

Though a bonus would be if your config file parser could handle input from a 
given fd as well. :)

Steve Schmidtke

_________________________________________________________________
The new MSN 8: advanced junk mail protection and 2 months FREE*  
http://join.msn.com/?page=features/junkmail



-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-14  3:54 Steve Schmidtke
  2003-10-13  5:15 ` Jeff Dike
  2003-10-14  6:19 ` Doug Dumitru
@ 2003-10-17 17:14 ` Adam Heath
  2 siblings, 0 replies; 15+ messages in thread
From: Adam Heath @ 2003-10-17 17:14 UTC (permalink / raw)
  To: Steve Schmidtke; +Cc: User-mode-linux-devel

On Tue, 14 Oct 2003, Steve Schmidtke wrote:

>   umlwrap -bind=15,/dev/shm/mconsole-$$ -connect=17,/tmp/uml.ctl \
>   -dir=/home/uml -user=guest -- /bin/linux mem=64M \
>   uml_dir=/uml/ umid=um$$ ubd0=/disk.cow,/disk.dat \
>   eth0=daemon con=null con0=fd:0,fd:1 \
>   filemap=file,10,/proc/cpuinfo 10</proc/cpuinfo \
>   filemap=file,11,/disk.dat 11</mnt/backing.dat \
>   filemap=file,12,/disk.cow 12<>/home/uml/cow-$$.cow \
>   filemap=file,15,/uml/um$$/mconsole \
>   filemap=file,16,/uml/um$$/pid 16</dev/shm/pid-$$ \
>   filemap=file,17,/tmp/uml.ctl \
>   filemap=vm,20-23 20<>/dev/shm/vm-$$.0 21<>/dev/shm/vm-$$.1 \
>   22<>/dev/shm/vm-$$.2 23<>/dev/shm/vm-$$.3 \
>
> Ugly, isn't it.  If you find a nicer way to do this let me know.  Notice how
> networking is carried out here via the daemon transport, connecting to the
> /tmp/uml.ctl socket run by uml_switch.  Your mileage may vary.

I have some unfinished code to make uml read a config file.  It fits in nicely
with the cmdline parsing.



-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-14 22:58 Steve Schmidtke
  2003-10-15  8:43 ` azu
@ 2003-10-15 20:13 ` Jeff Dike
  1 sibling, 0 replies; 15+ messages in thread
From: Jeff Dike @ 2003-10-15 20:13 UTC (permalink / raw)
  To: Steve Schmidtke; +Cc: User-mode-linux-devel

steve_schmidtke@hotmail.com said:
> ISSUE:  The UML will panic if it runs out of /proc/mm fds.

This won't be an issue with the skas4 patch, which uses a system call to
get new address spaces.

> TODO:  Make the filemap lookup routine re-entrant safe.

Before you go wild with locking, look at the callers and see if they are
re-entrant.  This obviously won't work for things that are called from all
over the place, but if something is called from one place that is itself
locked, then you don't need to worry about it.

				Jeff



-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-14 22:58 Steve Schmidtke
@ 2003-10-15  8:43 ` azu
  2003-10-15 20:13 ` Jeff Dike
  1 sibling, 0 replies; 15+ messages in thread
From: azu @ 2003-10-15  8:43 UTC (permalink / raw)
  To: Steve Schmidtke; +Cc: User-mode-linux-devel

> ISSUE:  The UML will panic if it runs out of /proc/mm fds.

returning -ENOMEM for example triggers the oom-killer in my tests.
and thats not what we want.

> ISSUE:  What side effects does re-using an address space have?

it's slow, but should work:

you need to cleanup (unmap all pages or reopen the fd) an dirty address
space before switching it if the mm differs.

the pager will map you all pages you need on demand.
i tested this by removing the premapping (removed the mmap() and
mprotect() calls in fix_range()), but it's much slower.

access to userspace is always safe in skas-mode.

alex




-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
@ 2003-10-14 22:58 Steve Schmidtke
  2003-10-15  8:43 ` azu
  2003-10-15 20:13 ` Jeff Dike
  0 siblings, 2 replies; 15+ messages in thread
From: Steve Schmidtke @ 2003-10-14 22:58 UTC (permalink / raw)
  To: jdike; +Cc: User-mode-linux-devel

[-- Attachment #1: Type: text/plain, Size: 1744 bytes --]

Jeff Dike wrote:
>Why so pessimistic?  I like filemap - IIRC, i suggested it.

Yeah, but finding the right interface to express it is tough.  I don't even 
want to go in the whole *in* OS_ layer/*above* os_* layer argument again. :) 
  I am also thinking that the filemap database should be generalized so that 
any translation can be supported - like an "xlate" table that can map Unix 
filenames to DOS filenames...

>I'd also like people to use this to see what's missing, if anything, and to
>get any improvements on the command line syntax.

Just so SKAS users don't feel left out, I've attached a small patch that 
adds a "mm" table to filemap for chrooted SKAS mode operation.  Just apply 
it after the first patch.

The following example shows how to use this patch to set up a chrooted SKAS 
UML with 20 available process slots:

  chroot /home/uml /linux mem=32M filemap=mm,30-49 \
  30>/proc/mm 31>/proc/mm 32>/proc/mm 33>/proc/mm 34>/proc/mm \
  35>/proc/mm 36>/proc/mm 37>/proc/mm 38>/proc/mm 39>/proc/mm \
  40>/proc/mm 41>/proc/mm 42>/proc/mm 43>/proc/mm 44>/proc/mm \
  45>/proc/mm 46>/proc/mm 47>/proc/mm 48>/proc/mm 49>/proc/mm \
  filemap=file,25,/proc/mm 25>/proc/mm \
  filemap=vm,20 20<>/dev/shm/vm-$$.0 con=null con0=fd:0,fd:1

Note the dummy "file" table entry for /proc/mm.  This is needed so the boot 
test for /proc/mm succeeds.

ISSUE:  The UML will panic if it runs out of /proc/mm fds.
ISSUE:  What side effects does re-using an address space have?
TODO:  Make the filemap lookup routine re-entrant safe.

Comments? Concerns?

Steve Schmidtke

_________________________________________________________________
STOP MORE SPAM with the new MSN 8 and get 2 months FREE*   
http://join.msn.com/?page=features/junkmail

[-- Attachment #2: filemap5-02.diff --]
[-- Type: application/octet-stream, Size: 2149 bytes --]

--- linux-2.4.22-5um.fm/arch/um/kernel/filemap.c	Tue Oct 14 10:44:50 2003
+++ linux-2.4.22-5um.new/arch/um/kernel/filemap.c	Tue Oct 14 13:56:37 2003
@@ -502,6 +502,11 @@
 		.entries = NULL,
 		.ops     = &fm_ops_pool,
 	},
+	{
+		.name    = "mm",
+		.entries = NULL,
+		.ops     = &fm_ops_pool,
+	},
 };
 
 static struct filemap_table* filemap_get_table(const char* table_name)
--- linux-2.4.22-5um.fm/arch/um/kernel/skas/process.c	Tue Oct 14 10:44:31 2003
+++ linux-2.4.22-5um.new/arch/um/kernel/skas/process.c	Tue Oct 14 14:28:39 2003
@@ -27,6 +27,8 @@
 #include "skas_ptrace.h"
 #include "chan_user.h"
 
+#include "filemap.h"
+
 int is_skas_winch(int pid, int fd, void *data)
 {
 	if(pid != getpid())
@@ -340,12 +342,27 @@
 int new_mm(int from)
 {
 	struct proc_mm_op copy;
-	int n, fd = os_open_file("/proc/mm", 
+	int n, fd;
+
+	/* use the raw access since /proc/mm opens a new file every time */ 
+        fd = filemap_access("mm", "/proc/mm");
+        if(fd >= 0) {
+                printk("filemap aquire: fd=%d, file=%s\n", fd, "/proc/mm");
+                goto handle_fd;
+        }
+
+	/* if /proc/mm exists, the same fd would be returned over and over */
+        if(filemap_access("file", "/proc/mm") >= 0) {
+		return(-1);	
+	}
+
+	fd = os_open_file("/proc/mm", 
 				 of_cloexec(of_write(OPENFLAGS())), 0);
 
 	if(fd < 0)
 		return(fd);
 
+handle_fd:
 	if(from != -1){
 		copy = ((struct proc_mm_op) { .op 	= MM_COPY_SEGMENTS,
 					      .u 	= 
--- linux-2.4.22-5um.fm/arch/um/kernel/skas/mmu.c	Tue Oct 14 10:44:31 2003
+++ linux-2.4.22-5um.new/arch/um/kernel/skas/mmu.c	Tue Oct 14 16:48:36 2003
@@ -21,14 +21,23 @@
 
 	mm->context.skas.mm_fd = new_mm(from);
 	if(mm->context.skas.mm_fd < 0)
+#if 1
 		panic("init_new_context_skas - new_mm failed, errno = %d\n",
 		      mm->context.skas.mm_fd);
+#else /* DON'T PANIC */
+		return(mm->context.skas.mm_fd);
+#endif
 
 	return(0);
 }
 
 void destroy_context_skas(struct mm_struct *mm)
 {
+	/* filemapped files will return something other than -ENOENT */
+	if(filemap_release("mm", mm->context.skas.mm_fd) != -ENOENT) {
+		return;
+	}
+
 	os_close_file(mm->context.skas.mm_fd);
 }
 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-14  3:54 Steve Schmidtke
  2003-10-13  5:15 ` Jeff Dike
@ 2003-10-14  6:19 ` Doug Dumitru
  2003-10-17 17:14 ` Adam Heath
  2 siblings, 0 replies; 15+ messages in thread
From: Doug Dumitru @ 2003-10-14  6:19 UTC (permalink / raw)
  To: Steve Schmidtke, user-mode-linux-devel

Steve,

I like your file mapping, especially as a way of keeping a chroot jail 
as empty as possible.

A couple of questions.  I noticed that you are not mapping /proc/mm.  Is 
this a 2.4.x only issue or is this needed in SKAS mode with 2.6.x.  I am 
running 2.4.22 with all of my virtuals just to keep things "stable".  I 
also tend to see a "lot" of open handles to /proc/mm.  Sometimes >50 of 
these.  This looks like one per virtual process (minus threads).  Am I 
reading this right.

On virtuals that I run, I tend to only see a single "vm" file opened:

linux   5595 root    3u   REG       58,0 268435457 4941730 
/usr2/vsys/v_2020/tmpdir/vm_file-OeeMw1 (deleted)

This one is 256Meg.  When does the vm try to open "pieces".

Is there any reason the tun/tap networking wouldn't work with this 
layout by pre-opening /dev/net/tun.

Thanks for the script examples of how to get this rolling.

---
Doug Dumitru

Steve Schmidtke wrote:

> This patch adds filemap support to 2.4.22-5um.  The function of this 
> patch is an awkard and convoluted solution to an arcane problem.  Unless 
> you know this is what you need, you may just want to skip this post.
> 
> Filemaping is a method of mapping open file descriptors to arbitrary 
> file names within a UML.  Once a file name has been mapped, all UML file 
> requests on that name act upon the open file descriptor.  The main 
> purpose of filemap is to support empty chroot environments, allowing the 
> UML to access files, such as /proc/cpuinfo and virtual memory files, 
> without requiring those files to be present within the chroot directory.
> 
> The filemap boot string syntax lookes like this:
> 
>  filemap=<table>,<table specific syntax>
> 
> There are two tables available, "file" and "vm".  "file" type filemaps 
> handle fd/filename pairs, while "vm" type filemaps handle pools of fd's 
> that represent virtual memory files.
> 
> For example, a "file" table boot string may look like this:
> 
>  filemap=file,12,/proc/cpuinfo
> 
> which redirects the UML to file descriptor 12 when accessing the file
> /proc/cpuinfo.  In this case, file descriptor 12 must be opened 
> beforehand, possibly like this on the UMLs command line:
> 
>  12</proc/cpuinfo
> 
> A "vm" table filemap boot string may look like this:
> 
>  filemap=vm,20-23
> 
> which will set up a pool of file descriptors (20, 21, 22, and 23) to be 
> mete out to the UML as it requests virtual memory files.
> 
> Here are some example command lines using filemaps:
> 
>  chroot /home/uml /bin/linux mem=32M \
>  filemap=file,11,/proc/cpuinfo 11</proc/cpuinfo
> 
> The above line tells the chrooted UML to use file descriptor 11 whenever 
> accessing /proc/cpuinfo (which it only ever reads).
> 
>  chroot /cdrom /linux mem=16M filemap=vm,20-21 \
>  20<>/dev/shm/vm1 21<>/dev/shm/vm2
> 
> This invocation tells the chrooted UML to use file descriptors 20 and 21 
> for (some of) its virtual memory files.  How do you know how many to 
> specify?  The number is proportional to how much memory you have given 
> the UML. Start with booting the UML with a bunch of zero length files, 
> and review how many end up with non-zero file sizes.  Adjust to suit.  
> Note the above examples read+write redirection on the vm files.
> 
>  umlwrap -bind=22,/dev/shm/mconsole1 -dir=/home/uml -- \
>  /bin/linux mem=48M uml_dir=/uml/ umid=um1 filemap=22,/uml/um1/pid \
>  22</dev/shm/pid filemap=22,/uml/um1/mconsole
> 
> Here, a hypothetical chroot helper opens a bound unix socket on file 
> descriptor 21.  The chrooted UML will pick up the fd as its mconsole 
> socket (by way of a crafty command line).  Note that the method used to 
> tell uml_mconsole to open a socket in /dev/shm/ is beyond the scope of 
> this example.  Also note that the umid pid file has been filemaped as 
> well -- the umid directory does not have to exist for things to work.
> 
> In fact, there is no writable media necessary within the chroot to run 
> UML at all.  The only file necessary to be present is the staticly 
> linked linux binary.
> 
> One final example to put it all together:
> 
>  umlwrap -bind=15,/dev/shm/mconsole-$$ -connect=17,/tmp/uml.ctl \
>  -dir=/home/uml -user=guest -- /bin/linux mem=64M \
>  uml_dir=/uml/ umid=um$$ ubd0=/disk.cow,/disk.dat \
>  eth0=daemon con=null con0=fd:0,fd:1 \
>  filemap=file,10,/proc/cpuinfo 10</proc/cpuinfo \
>  filemap=file,11,/disk.dat 11</mnt/backing.dat \
>  filemap=file,12,/disk.cow 12<>/home/uml/cow-$$.cow \
>  filemap=file,15,/uml/um$$/mconsole \
>  filemap=file,16,/uml/um$$/pid 16</dev/shm/pid-$$ \
>  filemap=file,17,/tmp/uml.ctl \
>  filemap=vm,20-23 20<>/dev/shm/vm-$$.0 21<>/dev/shm/vm-$$.1 \
>  22<>/dev/shm/vm-$$.2 23<>/dev/shm/vm-$$.3 \
> 
> Ugly, isn't it.  If you find a nicer way to do this let me know.  Notice 
> how networking is carried out here via the daemon transport, connecting 
> to the /tmp/uml.ctl socket run by uml_switch.  Your mileage may vary.
> 
> Other filemap issues I know about:
> 
> - Reboots may not work as expected.  Best is to shutdown and restart.
> - A given file may be corrupted if access to it is not serialized.
> - Hostfs accessed files are NOT filemapped.  See above.
> - Directories cannot be filemapped.
> - Vm files are visible and persistent!  Bug or feature:  you decide.
> - Notify feature of mconsole is not supported.  Why so complicated?
> - You can bet this patch won't make it into Jeff's official source 
> tree.  I'm cool with that.
> 
> Enjoy!
> 
> Steve Schmidtke
> 
> _________________________________________________________________
> The new MSN 8: advanced junk mail protection and 2 months FREE*  
> http://join.msn.com/?page=features/junkmail


-- 

--------------------------------------------------------------------
Doug Dumitru     800-470-2756     (610-237-2000)
EasyCo LLC       doug@easyco.com  http://easyco.com
--------------------------------------------------------------------
D3, U2, jBase Virtual Servers.    Off-site backup over the internet.
Develop/test/deploy from $20/mo.  Fast, secure, cheaper than tape.
http://mirroredservers.com        http://mirroredbackup.com



-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [uml-devel] filemap feature 2.4.22-5um
@ 2003-10-14  3:54 Steve Schmidtke
  2003-10-13  5:15 ` Jeff Dike
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Steve Schmidtke @ 2003-10-14  3:54 UTC (permalink / raw)
  To: User-mode-linux-devel

[-- Attachment #1: Type: text/plain, Size: 4543 bytes --]

This patch adds filemap support to 2.4.22-5um.  The function of this patch 
is an awkard and convoluted solution to an arcane problem.  Unless you know 
this is what you need, you may just want to skip this post.

Filemaping is a method of mapping open file descriptors to arbitrary file 
names within a UML.  Once a file name has been mapped, all UML file requests 
on that name act upon the open file descriptor.  The main purpose of filemap 
is to support empty chroot environments, allowing the UML to access files, 
such as /proc/cpuinfo and virtual memory files, without requiring those 
files to be present within the chroot directory.

The filemap boot string syntax lookes like this:

  filemap=<table>,<table specific syntax>

There are two tables available, "file" and "vm".  "file" type filemaps 
handle fd/filename pairs, while "vm" type filemaps handle pools of fd's that 
represent virtual memory files.

For example, a "file" table boot string may look like this:

  filemap=file,12,/proc/cpuinfo

which redirects the UML to file descriptor 12 when accessing the file
/proc/cpuinfo.  In this case, file descriptor 12 must be opened beforehand, 
possibly like this on the UMLs command line:

  12</proc/cpuinfo

A "vm" table filemap boot string may look like this:

  filemap=vm,20-23

which will set up a pool of file descriptors (20, 21, 22, and 23) to be mete 
out to the UML as it requests virtual memory files.

Here are some example command lines using filemaps:

  chroot /home/uml /bin/linux mem=32M \
  filemap=file,11,/proc/cpuinfo 11</proc/cpuinfo

The above line tells the chrooted UML to use file descriptor 11 whenever 
accessing /proc/cpuinfo (which it only ever reads).

  chroot /cdrom /linux mem=16M filemap=vm,20-21 \
  20<>/dev/shm/vm1 21<>/dev/shm/vm2

This invocation tells the chrooted UML to use file descriptors 20 and 21 for 
(some of) its virtual memory files.  How do you know how many to specify?  
The number is proportional to how much memory you have given the UML. Start 
with booting the UML with a bunch of zero length files, and review how many 
end up with non-zero file sizes.  Adjust to suit.  Note the above examples 
read+write redirection on the vm files.

  umlwrap -bind=22,/dev/shm/mconsole1 -dir=/home/uml -- \
  /bin/linux mem=48M uml_dir=/uml/ umid=um1 filemap=22,/uml/um1/pid \
  22</dev/shm/pid filemap=22,/uml/um1/mconsole

Here, a hypothetical chroot helper opens a bound unix socket on file 
descriptor 21.  The chrooted UML will pick up the fd as its mconsole socket 
(by way of a crafty command line).  Note that the method used to tell 
uml_mconsole to open a socket in /dev/shm/ is beyond the scope of this 
example.  Also note that the umid pid file has been filemaped as well -- the 
umid directory does not have to exist for things to work.

In fact, there is no writable media necessary within the chroot to run UML 
at all.  The only file necessary to be present is the staticly linked linux 
binary.

One final example to put it all together:

  umlwrap -bind=15,/dev/shm/mconsole-$$ -connect=17,/tmp/uml.ctl \
  -dir=/home/uml -user=guest -- /bin/linux mem=64M \
  uml_dir=/uml/ umid=um$$ ubd0=/disk.cow,/disk.dat \
  eth0=daemon con=null con0=fd:0,fd:1 \
  filemap=file,10,/proc/cpuinfo 10</proc/cpuinfo \
  filemap=file,11,/disk.dat 11</mnt/backing.dat \
  filemap=file,12,/disk.cow 12<>/home/uml/cow-$$.cow \
  filemap=file,15,/uml/um$$/mconsole \
  filemap=file,16,/uml/um$$/pid 16</dev/shm/pid-$$ \
  filemap=file,17,/tmp/uml.ctl \
  filemap=vm,20-23 20<>/dev/shm/vm-$$.0 21<>/dev/shm/vm-$$.1 \
  22<>/dev/shm/vm-$$.2 23<>/dev/shm/vm-$$.3 \

Ugly, isn't it.  If you find a nicer way to do this let me know.  Notice how 
networking is carried out here via the daemon transport, connecting to the 
/tmp/uml.ctl socket run by uml_switch.  Your mileage may vary.

Other filemap issues I know about:

- Reboots may not work as expected.  Best is to shutdown and restart.
- A given file may be corrupted if access to it is not serialized.
- Hostfs accessed files are NOT filemapped.  See above.
- Directories cannot be filemapped.
- Vm files are visible and persistent!  Bug or feature:  you decide.
- Notify feature of mconsole is not supported.  Why so complicated?
- You can bet this patch won't make it into Jeff's official source tree.  
I'm cool with that.

Enjoy!

Steve Schmidtke

_________________________________________________________________
The new MSN 8: advanced junk mail protection and 2 months FREE*  
http://join.msn.com/?page=features/junkmail

[-- Attachment #2: filemap5-01.diff --]
[-- Type: application/octet-stream, Size: 21754 bytes --]

diff -Naur linux-2.4.22-5um.orig/arch/um/include/filemap.h linux-2.4.22-5um.new/arch/um/include/filemap.h
--- linux-2.4.22-5um.orig/arch/um/include/filemap.h	Wed Dec 31 19:00:00 1969
+++ linux-2.4.22-5um.new/arch/um/include/filemap.h	Thu Sep 25 20:29:17 2003
@@ -0,0 +1,13 @@
+/* 
+ * Copyright (C) 2003 Steve Schmidtke 
+ * Licensed under the GPL
+ */
+
+#ifndef __FILEMAP_H__
+#define __FILEMAP_H__
+
+extern int filemap_access(const char* table_name, const char* file_name);
+extern int filemap_aquire(const char* table_name, const char* file_name);
+extern int filemap_release(const char* table_name, int fd);
+
+#endif
diff -Naur linux-2.4.22-5um.orig/arch/um/kernel/Makefile linux-2.4.22-5um.new/arch/um/kernel/Makefile
--- linux-2.4.22-5um.orig/arch/um/kernel/Makefile	Thu Sep 25 19:29:45 2003
+++ linux-2.4.22-5um.new/arch/um/kernel/Makefile	Thu Sep 25 20:29:17 2003
@@ -11,7 +11,7 @@
 	sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
 	syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
 	time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
-	um_arch.o umid.o user_syms.o user_util.o
+	um_arch.o umid.o user_syms.o user_util.o filemap.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
 obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -29,7 +29,7 @@
 # building anything in export-objs
 
 USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
-	process.o tempfile.o time.o umid.o user_util.o 
+	process.o tempfile.o time.o umid.o user_util.o filemap.o
 
 DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
 DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
diff -Naur linux-2.4.22-5um.orig/arch/um/kernel/filemap.c linux-2.4.22-5um.new/arch/um/kernel/filemap.c
--- linux-2.4.22-5um.orig/arch/um/kernel/filemap.c	Wed Dec 31 19:00:00 1969
+++ linux-2.4.22-5um.new/arch/um/kernel/filemap.c	Thu Sep 25 20:29:17 2003
@@ -0,0 +1,655 @@
+/* 
+ * Copyright (C) 2003 Steve Schmidtke 
+ * Licensed under the GPL
+ */
+
+#include <stdlib.h> 
+#include <string.h> 
+#include <unistd.h> 
+#include <errno.h> 
+#include "init.h"
+#include "sys/types.h"
+#include "unistd.h"
+#include "fcntl.h"
+
+#define STRFD_ISEND(c)  ((c == '\0') || (c == ',') || (c == '-'))
+
+struct filemap_entry {
+	struct filemap_entry* next;
+	char* name;
+	int fd;
+	int count;
+	int cf; /* initial close on exec flag */
+};  
+
+struct filemap_ops {
+	int (*parse)(void* table, char* str);
+	int (*access)(void* table, char* filename);
+	int (*aquire)(void* table, char* filename);
+	int (*release)(void* table, int fd);
+	int (*shutdown)(void* table);
+};
+
+struct filemap_table {
+	char* name;
+	struct filemap_entry* entries;
+	struct filemap_ops* ops;
+};
+
+static struct filemap_entry* filemap_entry_alloc(void)
+{
+	return(malloc(sizeof(struct filemap_entry)));
+}
+
+/* FIXME: the os_* versions of these routines below may recurse? */
+
+static void seek_file(int fd, off_t offset)
+{
+	lseek(fd, offset, SEEK_SET);
+}
+
+static int get_close_on_exec(int fd, int* close_on_exec)
+{
+	int ret;
+
+	do {
+		ret = fcntl(fd, F_GETFD);
+	} while(ret<0 && errno==EINTR) ;
+
+	if(ret < 0)
+		return(-errno);
+
+	*close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
+
+	return(ret);
+}
+
+static int set_close_on_exec(int fd, int close_on_exec)
+{
+	int flag, err;
+
+	if(close_on_exec) flag = FD_CLOEXEC;
+	else flag = 0;
+
+	do {
+		err = fcntl(fd, F_SETFD, flag);
+	} while(err<0 && errno==EINTR) ;
+
+	if(err < 0)
+		return(-errno);
+
+	return(err);
+}
+
+/*
+ * Add a fd (and filename) to a table in the db.
+ */
+static int filemap_add_entry(struct filemap_table* table,
+    int fdesc, char* file_name)
+{
+	struct filemap_entry* entry;
+	struct filemap_entry* dup;
+	int coeflag;
+	int err;
+
+	if((table == NULL) || (fdesc < 0)) {
+		return(-EINVAL);
+	}
+
+	dup = NULL;
+	for(entry = table->entries; entry; entry = entry->next) {
+		if(!dup && (fdesc == entry->fd)) {
+			dup = entry;
+		}
+	}
+
+	if(dup) {
+		coeflag = dup->cf;
+	} else {
+		err = get_close_on_exec(fdesc, &coeflag);
+		if(err < 0) {
+			printk("filemap_add_entry: get close-on-exec flag"
+				" failed errno=%d fd=%d name=%s\n",
+				err, fdesc, file_name);
+			return(err);
+		}
+
+		/* by default, exec calls should close filemaps */ 
+		err = set_close_on_exec(fdesc, 1);
+		if(err < 0) {
+			printk("filemap_add_entry: set close-on-exec flag"
+				" failed errno=%d fd=%d name=%s\n",
+				err, fdesc, file_name);
+			return(err);
+		}
+	}
+
+	entry = filemap_entry_alloc();
+	if(entry == NULL) {
+		printk("filemap_add_entry: alloc failed fd=%d, name=%s\n",
+			fdesc, file_name);
+		return(-ENOMEM);
+	}
+
+	printk("installing filemap: table=%s fd=%d, c-o-e=%d name=%s\n",
+		table->name, fdesc, coeflag, file_name);
+
+	*entry = ((struct filemap_entry) {
+			.next	= table->entries,
+			.name	= file_name,
+			.fd	= fdesc,
+			.count	= 0,
+			.cf	= coeflag
+	});
+
+	table->entries = entry;
+
+	return(0);
+}
+
+/*
+ * Find the matching filename in the db and return the filemap entry. 
+ */
+static struct filemap_entry* filemap_lookup_name(struct filemap_table* table,
+    const char* file_name)
+{
+	struct filemap_entry* entry;
+
+	for(entry = table->entries; entry; entry = entry->next) {
+		if(strcmp(file_name, entry->name) == 0) {
+			return(entry);
+		}
+	}
+
+	return(NULL);
+}
+
+/*
+ * Find a fresh file descriptor in a file pool
+ */
+static struct filemap_entry* filemap_lookup_unused(struct filemap_table* table)
+{
+	struct filemap_entry* entry;
+
+	for(entry = table->entries; entry; entry = entry->next) {
+		if(entry->count == 0) {
+			return(entry);
+		}
+	}
+
+	return(NULL);
+}
+
+/*
+ * Find a matching fd in the db and return a filemap entry. 
+ */
+static struct filemap_entry* filemap_lookup_fd(struct filemap_table* table,
+    const int fd)
+{
+	struct filemap_entry* entry;
+
+	for(entry = table->entries; entry; entry = entry->next) {
+		if(fd == entry->fd) {
+			return(entry);
+		}
+	}
+
+	return(NULL);
+}
+
+/*
+ * set the filemapped file as pristine as possible
+ */
+static int filemap_scrub(struct filemap_entry* entry)
+{
+	int err;
+
+	err = set_close_on_exec(entry->fd, entry->cf);
+	if(err < 0) {
+		printk("filemap_scrub: reset close-on-exec flag failed"
+			" err=%d fd=%d c-o-e=%d name=%s\n",
+			err, entry->fd, entry->cf, entry->name);
+		return(err);
+	}
+
+	return(0);
+}
+
+/* 
+ * Return a disposable file descriptor for the one provided.
+ * dup() is used to guard against a close of the fd that was passed
+ * in.  This is not ideal as concurrent uses of the same file may
+ * wreak havoc with the shared position pointer, etc. between the
+ * duplicated file descriptors.
+ */ 
+static int filemap_newfd(int oldfd)
+{
+	int newfd, err;
+
+	if(oldfd < 0)
+		return(-EINVAL);
+
+	do {
+		newfd = dup(oldfd);
+	} while(newfd<0 && errno==EINTR) ;
+
+	if(newfd < 0)
+		return(-errno);
+
+	err = set_close_on_exec(newfd, 0);
+	if(err < 0) {
+		printk("filemap_newfd: clear close-on-exec flag failed"
+			" err=%d fd=%d\n", err, newfd);
+		return(err);
+	}
+
+	return(newfd);
+}
+
+/*
+ * parse the setup string for a file descriptor (number) and
+ * return * a pointer on the next argument in the setup string.
+ */
+static __init char* set_fdesc(char* str, int* fd)
+{
+	char* end;
+	int num;
+
+	if((str==NULL) || (*str=='\0'))
+		return(NULL);
+
+	if(*str == ',')
+		return(str);
+
+	num = strtoul(str, &end, 10);
+	if((end == str) || !STRFD_ISEND(*end)) {
+		printk("filemap: set_fd - invalid value '%s'\n", str);
+		goto endout;
+	}
+
+	*fd = num;
+
+endout:
+	while(!STRFD_ISEND(*end)) end++;
+	if(*end == '\0')
+		 return(NULL);
+
+	return(end);
+}
+
+
+/************************************************
+ *** Routines to support 'pool' type filemaps ***
+ ************************************************/
+
+static int fm_pool_parse(void* data, char* str)
+{
+	struct filemap_table* table = data;
+	char* end;
+	unsigned int count;
+	int fdfirst, fdlast, err;
+
+	end = set_fdesc(str, &fdfirst);
+	if(*end == '-') {
+		end = set_fdesc(end+1, &fdlast);
+	} else {
+		fdlast = fdfirst;
+	}
+
+	/* NOTE: add_entry loop must interate first -> last *inclusive* */
+
+	if(fdfirst < fdlast) count = fdlast - fdfirst;
+	else count = fdfirst - fdlast;
+
+	do { 
+		err = filemap_add_entry(table, fdfirst, NULL);
+		if(err < 0) {
+			printk("WARNING: filemap error %d on '%s':'%s'\n",
+			    err, table->name, str);
+			return(err);
+		}
+
+		if(fdfirst < fdlast) fdfirst++;
+		else fdfirst--;
+	} while(count--) ;
+
+	return(0);
+}
+
+static int fm_pool_access(void* data, char* file_name)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+
+	entry = filemap_lookup_unused(table);
+
+	if(entry == NULL)
+		return(-ENOENT);
+
+	entry->count++;
+
+	return(entry->fd);
+}
+
+static int fm_pool_aquire(void* data, char* file_name)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+	int fd;
+
+	entry = filemap_lookup_unused(table);
+
+	if(entry == NULL)
+		return(-ENOENT);
+
+	fd = filemap_newfd(entry->fd);
+	if(fd < 0)
+		return(fd);
+
+	entry->count++;
+
+	/* make sure this "new" file is rewound */
+	seek_file(fd, 0);
+
+	return(fd);
+}
+
+static int fm_pool_release(void* data, int fd)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+
+	/* the lookup_fd will always fail if the returned fd from _aquire is
+	 * a dup of the real fd.  This is OK: the caller will close the dup */
+	entry=filemap_lookup_fd(table, fd); 
+
+	if(entry == NULL)
+		return(-ENOENT);
+
+	if(entry->count > 0)
+		entry->count--;
+
+	return(0);
+}
+
+static int fm_pool_shutdown(void* data)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+
+	for(entry = table->entries; entry; entry = entry->next) {
+		filemap_scrub(entry);
+	}
+
+	return(0);
+}
+
+static struct filemap_ops fm_ops_pool = {
+	.parse        = fm_pool_parse,
+	.access       = fm_pool_access,
+	.aquire       = fm_pool_aquire,
+	.release      = fm_pool_release,
+	.shutdown     = fm_pool_shutdown,
+};
+
+
+/************************************************
+ *** Routines to support 'file' type filemaps ***
+ ************************************************/
+
+static int fm_file_parse(void* data, char* str)
+{
+	struct filemap_table* table = data;
+	char* file_name;
+	int fd, err;
+
+	file_name = set_fdesc(str, &fd);
+	if(*file_name == ',')
+		file_name++;
+
+	err = filemap_add_entry(table, fd, file_name);
+	if(err < 0) {
+		printk("WARNING: filemap error %d on '%s':'%s'\n",
+		    err, table->name, str);
+		return(err);
+	}
+
+	return(0);
+}
+
+static int fm_file_access(void* data, char* file_name)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+
+	entry = filemap_lookup_name(table, file_name);
+
+	if(entry == NULL)
+		return(-ENOENT);
+
+	return(entry->fd);
+}
+
+static int fm_file_aquire(void* data, char* file_name)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+	int fd;
+
+	entry = filemap_lookup_name(table, file_name);
+
+	if(entry == NULL)
+		return(-ENOENT);
+
+	fd = filemap_newfd(entry->fd);
+	if(fd < 0)
+		return(fd);
+
+	/* make sure this "new" file is rewound */
+	seek_file(fd, 0);
+
+	return(fd);
+}
+
+static int fm_file_release(void* data, int fd)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+
+	/* the lookup_fd will always fail if the returned fd from _aquire is
+	 * a dup of the real fd.  This is OK: the caller will close the dup */
+	entry = filemap_lookup_fd(table, fd);
+
+	if(entry == NULL)
+		return(-ENOENT);
+
+	return(0);
+}
+
+static int fm_file_shutdown(void* data)
+{
+	struct filemap_table* table = data;
+	struct filemap_entry* entry;
+
+	for(entry = table->entries; entry; entry = entry->next) {
+		filemap_scrub(entry);
+	}
+
+	return(0);
+}
+
+static struct filemap_ops fm_ops_file = {
+	.parse        = fm_file_parse,
+	.access       = fm_file_access,
+	.aquire       = fm_file_aquire,
+	.release      = fm_file_release,
+	.shutdown     = fm_file_shutdown,
+};
+
+
+/***********************
+ *** Filemap Tables  ***
+ ***********************/
+
+static struct filemap_table filemap_tables[] = {
+	{
+		.name    = "file",
+		.entries = NULL,
+		.ops     = &fm_ops_file,
+	},
+	{
+		.name    = "vm",
+		.entries = NULL,
+		.ops     = &fm_ops_pool,
+	},
+};
+
+static struct filemap_table* filemap_get_table(const char* table_name)
+{
+	struct filemap_table* table;
+	int i;
+
+	i = 0;
+
+	while(i < sizeof(filemap_tables)/sizeof(filemap_tables[0])) {
+		table = &filemap_tables[i];
+
+		if(strcmp(table_name, table->name) == 0)
+			return(table);
+
+		i++;
+	}
+
+	return(NULL);
+}
+
+
+/**********************************
+ *** Filemap Interface Routines ***
+ **********************************/
+
+/*
+ * Return THE file descriptor for the given filename from the db table.
+ * This is a raw interface for functions, like stat() wrappers that promise
+ * not to do IO, close the fd, or otherwise fiddle with the file state.
+ */
+int filemap_access(const char* table_name, char* file_name)
+{
+	struct filemap_table* table;
+	int fd;
+
+	table = filemap_get_table(table_name);
+
+	if(table == NULL) {
+		printk("ERROR: unknown filemap table '%s'\n", table_name);
+		return(0);
+	}
+
+	fd = table->ops->access(table, file_name);
+
+	return(fd);
+}
+
+/*
+ * Return A NEW file descriptor for the given filename from the db.
+ * Assume the modes of the file descriptor was set up to match what is
+ * being asked for.
+ */
+int filemap_aquire(const char* table_name, char* file_name)
+{
+	struct filemap_table* table;
+	int fd;
+
+	table = filemap_get_table(table_name);
+
+	if(table == NULL) {
+		printk("ERROR: unknown filemap table '%s'\n", table_name);
+		return(0);
+	}
+
+	fd = table->ops->aquire(table, file_name);
+
+	return(fd);
+}
+
+/*
+ * "Release" the file descriptor.  Do nothing - if not in the db,
+ * return -ENOENT.  The caller would want to use the close() system
+ * call on the fd in that event.
+ */
+int filemap_release(const char* table_name, const int fd)
+{
+	struct filemap_table* table;
+	int err;
+
+	table = filemap_get_table(table_name);
+
+	if(table == NULL) {
+		printk("ERROR: unknown filemap table '%s'\n", table_name);
+		return(-ENOENT); /* the caller expects ENOENT */ 
+	}
+
+	err = table->ops->release(table, fd);
+
+	return(err);
+}
+
+/*
+ * Do any table cleanup necessary before power cycle
+ */
+static void filemap_shutdown(void)
+{
+	struct filemap_table* table;
+	int i;
+
+	i = 0;
+
+	while(i < sizeof(filemap_tables)/sizeof(filemap_tables[0]))
+	{
+		table = &filemap_tables[i];
+
+		table->ops->shutdown(table);
+
+		i++;
+	}
+}
+
+__uml_exitcall(filemap_shutdown);
+
+static int __init parse_filemap(char* str, int* add)
+{
+	struct filemap_table* table;
+	char* table_name;
+	int err;
+
+	*add = 0;
+
+	table_name = str;
+	while(*str && *str != ',') str++;
+	if(*str == ',') *str++ = '\0';
+
+	table = filemap_get_table(table_name);
+
+	if(table == NULL) {
+		printk("ERROR: unknown filemap table '%s'\n", table_name);
+		return(0);
+	}
+
+	err = table->ops->parse(table, str);
+	if(err < 0) {
+		printk("ERROR: filemap parse error %d on '%s':'%s'\n",
+		    err, table_name, str);
+		return(0);
+	}
+
+	return(0);
+}
+
+__uml_setup("filemap=", parse_filemap,
+"filemap=<table>,<fd>[-<fd>][,<filename>]\n"
+"    Map <filename> to <fd> (already opened) into db table named <table>.\n"
+"    Common tables: file=normal files, vm=virtual memory. Examples for bash:\n"
+"    ./linux ubd0=fs.cow,fs.dat filemap=file,10,fs.dat 10</cdrom2/fs.dat\n"
+"    ./linux filemap=file,11,/proc/cpuinfo 11</proc/cpuinfo\n"
+"    ./linux filemap=vm,20-21 20<>/dev/shm/vm-$$.1 21<>/dev/shm/vm-$$.2\n"
+);
diff -Naur linux-2.4.22-5um.orig/arch/um/kernel/mem_user.c linux-2.4.22-5um.new/arch/um/kernel/mem_user.c
--- linux-2.4.22-5um.orig/arch/um/kernel/mem_user.c	Thu Sep 25 19:29:45 2003
+++ linux-2.4.22-5um.new/arch/um/kernel/mem_user.c	Thu Sep 25 20:29:17 2003
@@ -47,6 +47,8 @@
 #include "tempfile.h"
 #include "kern_constants.h"
 
+#include "filemap.h"
+
 extern struct mem_region physmem_region;
 
 #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
@@ -56,6 +58,12 @@
 	int fd, err;
 	char zero;
 
+	fd = filemap_aquire("vm",NULL);
+	if(fd >= 0) {
+		ftruncate(fd, len); /* use 0 instead of len to zero contents */
+		goto sizefile;
+	}
+
 	fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
 	if(fd < 0) {
 		os_print_error(fd, "make_tempfile");
@@ -66,6 +74,8 @@
 		os_print_error(err, "change_mode");
 		exit(1);
 	}
+
+sizefile:
 	err = os_seek_file(fd, len);
 	if(err < 0){
 		os_print_error(err, "seek_file");
diff -Naur linux-2.4.22-5um.orig/arch/um/kernel/umid.c linux-2.4.22-5um.new/arch/um/kernel/umid.c
--- linux-2.4.22-5um.orig/arch/um/kernel/umid.c	Thu Sep 25 19:29:45 2003
+++ linux-2.4.22-5um.new/arch/um/kernel/umid.c	Thu Sep 25 20:29:17 2003
@@ -19,6 +19,8 @@
 #include "user_util.h"
 #include "choose-mode.h"
 
+#include "filemap.h"
+
 #define UMID_LEN 64
 #define UML_DIR "~/.uml/"
 
@@ -68,8 +70,24 @@
 {
 	int n;
 
-	if(!umid_inited && make_umid(printk)) return(-1);
+	if(umid_inited) {
+		char path[MAXPATHLEN + 1];   /* XXX use buf instead? */
+
+		n = snprintf(path, sizeof(path), "%s%s/%s",
+			     uml_dir, umid, name);
+		if((n < 0) || (n >= sizeof(path)))
+			return(-1);
+
+		/* just test for existence in the filemap file table */
+		if(filemap_access("file", path) >= 0) {
+			goto handle_name;
+		}
+	} 
+
+	if(make_umid(printk))
+		return(-1);
 
+handle_name:
 	n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
 	if(n > len){
 		printk("umid_file_name : buffer too short\n");
diff -Naur linux-2.4.22-5um.orig/arch/um/os-Linux/file.c linux-2.4.22-5um.new/arch/um/os-Linux/file.c
--- linux-2.4.22-5um.orig/arch/um/os-Linux/file.c	Thu Sep 25 19:29:45 2003
+++ linux-2.4.22-5um.new/arch/um/os-Linux/file.c	Thu Sep 25 20:29:17 2003
@@ -19,6 +19,8 @@
 #include "user.h"
 #include "kern_util.h"
 
+#include "filemap.h"
+
 static void copy_stat(struct uml_stat *dst, struct stat64 *src)
 {
 	*dst = ((struct uml_stat) {
@@ -57,12 +59,22 @@
 int os_stat_file(const char *file_name, struct uml_stat *ubuf)
 {
 	struct stat64 sbuf;
-	int err;
+	int fd, err;
+
+	fd = filemap_access("file", file_name);
+	if(fd >= 0) {
+		do {
+			err = fstat64(fd, &sbuf);
+		} while((err < 0) && (errno == EINTR)) ;
+
+		goto did_stat;
+	}
 
 	do {
 		err = stat64(file_name, &sbuf);
 	} while((err < 0) && (errno == EINTR)) ;
 
+did_stat:
 	if(err < 0) 
 		return(-errno);
 
@@ -74,6 +86,26 @@
 int os_access(const char* file, int mode)
 {
 	int amode, err;
+	int fd, flags;
+
+	fd = filemap_access("file", file);
+	if(fd >= 0) {
+		do {
+			flags = fcntl(fd, F_GETFL);
+		} while((flags < 0) && (errno == EINTR)) ;
+	
+		if(flags < 0)
+			return(-errno);
+
+		if(mode & OS_ACC_X_OK)
+			return(-EACCES); /* XXX not executable not true? */
+		if((mode & OS_ACC_W_OK) && !(flags&O_RDWR || flags&O_WRONLY))
+			return(-EACCES);
+		if((mode & OS_ACC_R_OK) && (flags&O_WRONLY))
+			return(-EACCES);
+
+		return(0);
+	}
 
 	amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
 	      (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
@@ -257,6 +289,12 @@
 {
 	int fd, f = 0;
 
+	fd = filemap_aquire("file", file);
+	if(fd >= 0) {
+		printk("filemap aquire: fd=%d, file=%s\n", fd, file);
+		goto setfd;
+	}
+
 	if(flags.r && flags.w) f = O_RDWR;
 	else if(flags.r) f = O_RDONLY;
 	else if(flags.w) f = O_WRONLY;
@@ -271,6 +309,7 @@
 	if(fd < 0)
 		return(-errno);
 
+setfd:
 	if(flags.cl && fcntl(fd, F_SETFD, 1)){
 		os_close_file(fd);
 		return(-errno);
@@ -300,6 +339,13 @@
 
 void os_close_file(int fd)
 {
+#if 0
+	/* filemapped files will return something other than -ENOENT */
+	if(filemap_release("file", fd) != -ENOENT) {
+		return;
+	}
+#endif
+
 	close(fd);
 }
 
@@ -574,6 +620,12 @@
 	struct sockaddr_un addr;
 	int sock, err;
 
+	sock = filemap_aquire("file", file);
+	if(sock >= 0) {
+		printk("filemap aquire: fd=%d, file=%s\n", sock, file);
+		goto setfd;
+	}
+
 	sock = socket(PF_UNIX, SOCK_DGRAM, 0);
 	if (sock < 0){
 		printk("create_unix_socket - socket failed, errno = %d\n",
@@ -581,13 +633,6 @@
 		return(-errno);
 	}
 
-	if(close_on_exec) {
-		err = os_set_exec_close(sock, 1);
-		if(err < 0)
-			printk("create_unix_socket : close_on_exec failed, "
-		       "err = %d", -err);
-	}
-
 	addr.sun_family = AF_UNIX;
 
 	/* XXX Be more careful about overflow */
@@ -598,6 +643,14 @@
 		printk("create_listening_socket - bind failed, errno = %d\n",
 		       errno);
 		return(-errno);
+	}
+
+setfd:
+	if(close_on_exec) {
+		err = os_set_exec_close(sock, 1);
+		if(err < 0)
+			printk("create_unix_socket : close_on_exec failed, "
+		       "err = %d", -err);
 	}
 
 	return(sock);
diff -Naur linux-2.4.22-5um.orig/arch/um/drivers/daemon_user.c linux-2.4.22-5um.new/arch/um/drivers/daemon_user.c
--- linux-2.4.22-5um.orig/arch/um/drivers/daemon_user.c	Thu Sep 25 19:29:45 2003
+++ linux-2.4.22-5um.new/arch/um/drivers/daemon_user.c	Thu Sep 25 20:29:17 2003
@@ -18,6 +18,8 @@
 #include "user.h"
 #include "os.h"
 
+#include "filemap.h"
+
 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
 
 enum request_type { REQ_NEW_CONTROL };
@@ -53,6 +55,13 @@
 	struct request_v3 req;
 	int fd, n, err;
 
+	pri->control = filemap_aquire("file", ctl_addr->sun_path);
+	if(pri->control >= 0) {
+		printk("filemap aquire: fd=%d, file=%s\n",
+		       pri->control, ctl_addr->sun_path);
+		goto have_control;
+	}
+
 	pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
 	if(pri->control < 0){
 		printk("daemon_open : control socket failed, errno = %d\n", 
@@ -68,6 +77,7 @@
 		goto out;
 	}
 
+have_control:
 	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
 	if(fd < 0){
 		printk("daemon_open : data socket failed, errno = %d\n", 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [uml-devel] filemap feature 2.4.22-5um
  2003-10-14  3:54 Steve Schmidtke
@ 2003-10-13  5:15 ` Jeff Dike
  2003-10-14  6:19 ` Doug Dumitru
  2003-10-17 17:14 ` Adam Heath
  2 siblings, 0 replies; 15+ messages in thread
From: Jeff Dike @ 2003-10-13  5:15 UTC (permalink / raw)
  To: Steve Schmidtke; +Cc: User-mode-linux-devel

steve_schmidtke@hotmail.com said:
> You can bet this patch won't make it into Jeff's official source tree.
>   I'm cool with that.

Why so pessimistic?  I like filemap - IIRC, i suggested it.  We had that
argument a while back which I don't recall the details about, so what goes in
might not be exactly this patch, but at some point, I'm going to merge something
like this.

I'd also like people to use this to see what's missing, if anything, and to
get any improvements on the command line syntax.

				Jeff




-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2003-10-19  9:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-14 14:08 [uml-devel] filemap feature 2.4.22-5um Steve Schmidtke
  -- strict thread matches above, loose matches on Subject: below --
2003-10-18 17:15 Steve Schmidtke
2003-10-18 16:34 BlaisorBlade
2003-10-18  1:31 Steve Schmidtke
2003-10-18 12:37 ` Henrik Nordstrom
2003-10-18 21:57   ` Goetz Bock
2003-10-18 22:29     ` Henrik Nordstrom
2003-10-18 14:27 ` Adam Heath
2003-10-14 22:58 Steve Schmidtke
2003-10-15  8:43 ` azu
2003-10-15 20:13 ` Jeff Dike
2003-10-14  3:54 Steve Schmidtke
2003-10-13  5:15 ` Jeff Dike
2003-10-14  6:19 ` Doug Dumitru
2003-10-17 17:14 ` Adam Heath

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.