[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/3] Start the mountee after the initialization.
From: |
Sergiu Ivanov |
Subject: |
[PATCH 2/3] Start the mountee after the initialization. |
Date: |
Sun, 5 Jul 2009 16:00:49 +0300 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
>From 0d9b7ceaa601ce9bbaae1673b44b46f86609776e Mon Sep 17 00:00:00 2001
From: Sergiu Ivanov <unlimitedscolobb@gmail.com>
Date: Sun, 5 Jul 2009 14:36:36 +0300
Subject: [PATCH] Start the mountee after initialization.
* main.c (main): Schedule an update to start the mountee.
* mount.c (unionmount_proxy): New variable.
(mountee_port): Likewise.
(mountee_started): Likewise.
(setup_unionmount): New function.
(start_mountee): New function (based on node_set_translator
in nsmux).
* mount.h (unionmount_proxy): New variable.
(mountee_port): Likewise.
(mountee_started): Likewise.
(setup_unionmount): New function.
(start_mountee): New function.
(setup_unionmount): New function.
* update.c (_root_update_thread): Start the mountee at the
first iteration.
---
main.c | 5 ++
mount.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mount.h | 23 ++++++++
update.c | 13 ++++-
4 files changed, 219 insertions(+), 1 deletions(-)
diff --git a/main.c b/main.c
index c33b065..a38e1a9 100644
--- a/main.c
+++ b/main.c
@@ -128,6 +128,11 @@ main (int argc, char **argv)
fshelp_touch (&netfs_root_node->nn_stat,
TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME, maptime);
+ /* The update thread will start the mountee when unionfs will be
+ ready for servicing RPCs (will have completed the
+ initialization). */
+ root_update_schedule ();
+
/* Start serving clients. */
for (;;)
netfs_server_loop ();
diff --git a/mount.c b/mount.c
index 7bc1fb8..f05fe7c 100644
--- a/mount.c
+++ b/mount.c
@@ -22,8 +22,187 @@
#define _GNU_SOURCE
+#include <hurd/fsys.h>
+#include <fcntl.h>
+
#include "mount.h"
+#include "lib.h"
/* The command line for starting the mountee. */
char * mountee_argz;
size_t mountee_argz_len;
+
+/* The node the mountee is sitting on. */
+node_t * unionmount_proxy;
+
+mach_port_t mountee_port;
+
+int mountee_started = 0;
+
+/* Starts the mountee (given by `argz` and `argz_len`), sets it on
+ node `np` and opens a port `port` to with `flags`. */
+error_t
+start_mountee (node_t * np, char * argz, size_t argz_len, int flags,
+ mach_port_t * port)
+{
+ error_t err;
+ mach_port_t underlying_port;
+
+ /* The intermediate container for the port to the root of the
+ mountee. */
+ mach_port_t res_port;
+
+ /* An unauthenticated port to the root of the translator, which
+ plays the role of the directory containing the underlying node of
+ the mountee. This one is used in fsys_getroot as the dotdot
+ parameter, so it is not really important what we put here because
+ the dotdot parameter is used mostly with symlinks. */
+ mach_port_t unauth_dir;
+
+ /* The control port of the mountee. */
+ mach_port_t control;
+
+ /* The user which has created this process. */
+ struct iouser * user;
+
+ /* The user who has no priveleges at all. */
+ struct iouser * nobody;
+
+ /* A protid which will be created from the supplied node. */
+ struct protid * newpi;
+
+ /* Identity information about the current process (for
+ fsys_getroot). */
+ uid_t * uids;
+ size_t nuids;
+
+ gid_t * gids;
+ size_t ngids;
+
+ /* The retry information returned by fsys_getroot. */
+ string_t retry_name;
+ mach_port_t retry_port;
+
+ /* Fetch the effective UIDs of this process. */
+ nuids = geteuids (0, 0);
+ if (nuids < 0)
+ return EPERM;
+ uids = alloca (nuids * sizeof (uid_t));
+
+ nuids = geteuids (nuids, uids);
+ assert (nuids > 0);
+
+ /* Fetch the effective GIDs of this process. */
+ ngids = getgroups (0, 0);
+ if (ngids < 0)
+ return EPERM;
+ gids = alloca (ngids * sizeof (gid_t));
+
+ ngids = getgroups (ngids, gids);
+ assert (ngids > 0);
+
+ /* Create an iouser instance basing on the obtained authority
+ information. */
+ err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
+ if (err)
+ return err;
+
+ /* Opens the port on which to set the mountee. */
+ error_t
+ open_port (int flags, mach_port_t * underlying,
+ mach_msg_type_name_t * underlying_type, task_t task,
+ void *cookie)
+ {
+ err = 0;
+
+ /* Create a port to `np`. */
+ newpi = netfs_make_protid
+ (netfs_make_peropen (np, flags, NULL), user);
+ if (!newpi)
+ {
+ iohelp_free_iouser (user);
+ return errno;
+ }
+
+ *underlying = underlying_port = ports_get_send_right (newpi);
+ *underlying_type = MACH_MSG_TYPE_COPY_SEND;
+
+ ports_port_deref (newpi);
+
+ return err;
+ } /*open_port */
+
+ /* Create a completely unprivileged user. */
+ err = iohelp_create_iouser(&nobody, NULL, NULL);
+
+ /* Create a port to `np` for the unprivileged user. */
+ newpi = netfs_make_protid
+ (netfs_make_peropen (np, flags, NULL), nobody);
+ if (!newpi)
+ {
+ iohelp_free_iouser (nobody);
+ err = errno;
+ return err;
+ }
+
+ unauth_dir = ports_get_send_right (newpi);
+ ports_port_deref (newpi);
+
+ /* Start the translator. The value 60000 for the timeout is the one
+ found in settrans. */
+ err = fshelp_start_translator (open_port, NULL, argz, argz, argz_len,
+ 60000, &control);
+ if (err)
+ return err;
+
+ /* Attempt to attach the mountee to the port opened in the previous
+ call. */
+ err = file_set_translator (underlying_port, 0, FS_TRANS_SET, 0, argz,
+ argz_len, control, MACH_MSG_TYPE_COPY_SEND);
+ port_dealloc (underlying_port);
+ if (err)
+ return err;
+
+ /* Obtain the port to the root of the newly-set translator. */
+ err = fsys_getroot (control, unauth_dir, MACH_MSG_TYPE_COPY_SEND,
+ uids, nuids, gids, ngids, flags, &retry_port,
+ retry_name, &res_port);
+ if (err)
+ return err;
+
+ *port = res_port;
+
+ return 0;
+} /* start_mountee */
+
+/* Sets up a proxy node, sets the translator on it, and registers the
+ filesystem published by the translator in the list of merged
+ filesystems. */
+error_t
+setup_unionmount (void)
+{
+ error_t err = 0;
+
+ /* The proxy node on which the mountee will be sitting must be able
+ to forward some of the RPCs coming from the mountee to the
+ underlying filesystem. That is why we create this proxy node as
+ a clone of the root node: the mountee will feel as if there is no
+ unionfs under itself. */
+ unionmount_proxy = netfs_make_node (netfs_root_node->nn);
+ if (!unionmount_proxy)
+ return ENOMEM;
+
+ /* Set the mountee on the proxy node.
+ Note that the O_READ flag does not actually limit access to the
+ mountee's filesystem considerably. Whenever a client looks up a
+ node which is not a directory, unionfs will give off a port to
+ the node itself, withouth proxying it. Proxying happens only for
+ directory nodes. */
+ err = start_mountee (unionmount_proxy, mountee_argz,
+ mountee_argz_len, O_READ, &mountee_port);
+
+ mountee_started = 1;
+
+ return err;
+} /* setup_unionmount */
+
diff --git a/mount.h b/mount.h
index 69b5574..aba174f 100644
--- a/mount.h
+++ b/mount.h
@@ -23,10 +23,33 @@
#ifndef INCLUDED_UNIONMOUNT_H
#define INCLUDED_UNIONMOUNT_H
+#include <error.h>
#include <unistd.h>
+#include <hurd/hurd_types.h>
+
+#include "node.h"
/* The command line for starting the mountee. */
extern char * mountee_argz;
extern size_t mountee_argz_len;
+/* The node the mountee is sitting on. */
+extern node_t * unionmount_proxy;
+
+extern mach_port_t mountee_port;
+
+extern int mountee_started;
+
+/* Starts the mountee (given by `argz` and `argz_len`), sets it on
+ node `np` and opens a port `port` to with `flags`. */
+error_t
+start_mountee (node_t * np, char * argz, size_t argz_len, int flags,
+ mach_port_t * port);
+
+/* Sets up a proxy node, sets the translator on it, and registers the
+ filesystem published by the translator in the list of merged
+ filesystems. */
+error_t
+setup_unionmount (void);
+
#endif /* not INCLUDED_UNIONMOUNT_H */
diff --git a/update.c b/update.c
index 8ec6688..50e93b2 100644
--- a/update.c
+++ b/update.c
@@ -1,7 +1,10 @@
/* Hurd unionfs
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2009 Free Software Foundation, Inc.
+
Written by Gianluca Guida <glguida@gmail.com>.
+ Adapted for unionmount by Sergiu Ivanov <unlimitedscolobb@gmail.com>.
+
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
@@ -30,6 +33,7 @@
#include "ncache.h"
#include "node.h"
#include "ulfs.h"
+#include "mount.h"
/* Reader lock is used by threads that are going to
add/remove an ulfs; writer lock is hold by the
@@ -64,6 +68,13 @@ _root_update_thread ()
ncache_reset ();
+ if (!mountee_started)
+ {
+ err = setup_unionmount ();
+ if (err)
+ error (EXIT_FAILURE, err, "failed to setup the mountee");
+ }
+
rwlock_writer_unlock (&update_rwlock);
}
}
--
1.5.2.4