[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 01/03: New upstream snapshot
From: |
Samuel Thibault |
Subject: |
[hurd] 01/03: New upstream snapshot |
Date: |
Thu, 06 Feb 2014 02:05:10 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch master
in repository hurd.
commit 75eeca5b9eb3806e8a5c54a3e7af22639b55db48
Author: Samuel Thibault <address@hidden>
Date: Thu Feb 6 00:29:17 2014 +0000
New upstream snapshot
---
daemons/getty.c | 3 +-
exec/main.c | 17 ++++++-
trans/fakeroot.c | 143 +++++++++++++++++++++++++++----------------------------
3 files changed, 87 insertions(+), 76 deletions(-)
diff --git a/daemons/getty.c b/daemons/getty.c
index 7112660..40ad4d7 100644
--- a/daemons/getty.c
+++ b/daemons/getty.c
@@ -102,7 +102,7 @@ load_banner (void)
out:
free (buf);
- return "\r\n\n\\s \\r (\\n) (\\l)\r\n\n";
+ return "\n\\s \\r (\\n) (\\l)\r\n\n";
}
/* Print a suitable welcome banner */
@@ -115,6 +115,7 @@ print_banner (int fd, char *ttyname)
if (uname (&u))
u.sysname[0] = u.release[0] = '\0';
+ write (fd, "\r\n", 2);
for (s = load_banner (); *s; s++)
{
for (t = s; *t && *t != '\\'; t++) /* nomnomnom */;
diff --git a/exec/main.c b/exec/main.c
index c1f347c..27f33b1 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -200,7 +200,7 @@ kern_return_t
S_exec_init (struct trivfs_protid *protid,
auth_t auth, process_t proc)
{
- mach_port_t host_priv, startup;
+ mach_port_t host_priv, device_master, startup;
error_t err;
if (! protid || ! protid->isroot)
@@ -232,9 +232,22 @@ S_exec_init (struct trivfs_protid *protid,
mach_port_deallocate (mach_task_self (), right);
}
- err = get_privileged_ports (&host_priv, NULL);
+ err = get_privileged_ports (&host_priv, &device_master);
assert_perror (err);
+ {
+ /* Get our stderr set up to print on the console, in case we have
+ to panic or something. */
+ mach_port_t cons;
+ error_t err;
+ err = device_open (device_master, D_READ|D_WRITE, "console", &cons);
+ assert_perror (err);
+ mach_port_deallocate (mach_task_self (), device_master);
+ stdin = mach_open_devstream (cons, "r");
+ stdout = stderr = mach_open_devstream (cons, "w");
+ mach_port_deallocate (mach_task_self (), cons);
+ }
+
proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION);
err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup);
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index 0e0b618..252ba31 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -54,7 +54,7 @@ struct netnode
#define FAKE_GID (1 << 1)
#define FAKE_AUTHOR (1 << 2)
#define FAKE_MODE (1 << 3)
-#define FAKE_REFERENCE (1 << 4) /* got node_norefs with st_nlink > 0 */
+#define FAKE_DEFAULT (1 << 4)
pthread_mutex_t idport_ihash_lock = PTHREAD_MUTEX_INITIALIZER;
struct hurd_ihash idport_ihash
@@ -123,15 +123,53 @@ new_node (file_t file, mach_port_t idport, int locked,
int openmodes,
return err;
}
+static void
+set_default_attributes (struct node *np)
+{
+ np->nn->faked = FAKE_UID | FAKE_GID | FAKE_DEFAULT;
+ np->nn_stat.st_uid = 0;
+ np->nn_stat.st_gid = 0;
+}
+
+static void
+set_faked_attribute (struct node *np, unsigned int faked)
+{
+ np->nn->faked |= faked;
+
+ if (np->nn->faked & FAKE_DEFAULT)
+ {
+ /* Now that the node has non-default faked attributes, they have to be
+ retained for future accesses. Account for the hash table reference.
+
+ XXX This means such nodes are currently leaked. Hopefully, there
+ won't be too many of them until the translator is shut down, and
+ the data structures should make implementing garbage collection
+ easy enough if it's ever needed, although scalability could be
+ improved. */
+ netfs_nref (np);
+ np->nn->faked &= ~FAKE_DEFAULT;
+ }
+}
+
/* Node NP has no more references; free all its associated storage. */
void
netfs_node_norefs (struct node *np)
{
assert (np->nn->np == np);
+
+ pthread_mutex_unlock (&np->lock);
+ pthread_spin_unlock (&netfs_node_refcnt_lock);
+
+ pthread_mutex_lock (&idport_ihash_lock);
+ hurd_ihash_locp_remove (&idport_ihash, np->nn->idport_locp);
+ pthread_mutex_unlock (&idport_ihash_lock);
+
mach_port_deallocate (mach_task_self (), np->nn->file);
mach_port_deallocate (mach_task_self (), np->nn->idport);
free (np->nn);
free (np);
+
+ pthread_spin_lock (&netfs_node_refcnt_lock);
}
/* This is the cleanup function we install in netfs_protid_class. If
@@ -140,49 +178,6 @@ netfs_node_norefs (struct node *np)
static void
fakeroot_netfs_release_protid (void *cookie)
{
- struct node *np = ((struct protid *) cookie)->po->np;
- assert (np->nn->np == np);
-
- pthread_mutex_lock (&idport_ihash_lock);
- pthread_mutex_lock (&np->lock);
-
- assert ((np->nn->faked & FAKE_REFERENCE) == 0);
-
- /* Check if someone else reacquired a reference to the node besides
- ours that is about to be dropped. */
- if (np->references > 1)
- goto out;
-
- if (np->nn->faked != 0
- && netfs_validate_stat (np, 0) == 0 && np->nn_stat.st_nlink > 0)
- {
- /* The real node still exists and we have faked some attributes.
- We must keep our node alive in core to retain those values.
- XXX
- For now, we will leak the node if it gets deleted later.
- That will keep the underlying file alive with st_nlink=0
- until this fakeroot filesystem dies. One easy solution
- would be to scan nodes with references=1 for st_nlink=0
- at some convenient time, periodically or in syncfs. */
-
- /* Keep a fake reference. */
- netfs_nref (np);
-
- /* Set the FAKE_REFERENCE flag so that we can properly
- account for that fake reference. */
- np->nn->faked |= FAKE_REFERENCE;
-
- /* Clear the lock box as if the file was closed. */
- fshelp_lock_init (&np->userlock);
-
- /* We keep our node. */
- goto out;
- }
-
- hurd_ihash_locp_remove (&idport_ihash, np->nn->idport_locp);
-
- out:
- pthread_mutex_unlock (&np->lock);
netfs_release_protid (cookie);
int cports = ports_count_class (netfs_control_class);
@@ -201,8 +196,6 @@ fakeroot_netfs_release_protid (void *cookie)
if (err != EBUSY)
error (1, err, "netfs_shutdown");
}
-
- pthread_mutex_unlock (&idport_ihash_lock);
}
/* Given an existing node, make sure it has NEWMODES in its openmodes.
@@ -287,6 +280,8 @@ netfs_S_dir_lookup (struct protid *diruser,
err = dir_lookup (dir, filename,
flags & (O_NOLINK|O_RDWR|O_EXEC|O_CREAT|O_EXCL|O_NONBLOCK),
mode, do_retry, retry_name, &file);
+ if (dir != dnp->nn->file)
+ mach_port_deallocate (mach_task_self (), dir);
if (err)
return err;
@@ -349,14 +344,27 @@ netfs_S_dir_lookup (struct protid *diruser,
}
mach_port_deallocate (mach_task_self (), fsidport);
+
+ redo_hash_lookup:
pthread_mutex_lock (&idport_ihash_lock);
pthread_mutex_lock (&dnp->lock);
struct netnode *nn = hurd_ihash_find (&idport_ihash, idport);
if (nn != NULL)
{
assert (nn->np->nn == nn);
- np = nn->np;
/* We already know about this node. */
+
+ if (np->references == 0)
+ {
+ /* But it might be in the process of being released. If so,
+ unlock the hash table to give the node a chance to actually
+ be removed and retry. */
+ pthread_mutex_unlock (&dnp->lock);
+ pthread_mutex_unlock (&idport_ihash_lock);
+ goto redo_hash_lookup;
+ }
+
+ np = nn->np;
mach_port_deallocate (mach_task_self (), idport);
if (np == dnp)
@@ -369,13 +377,7 @@ netfs_S_dir_lookup (struct protid *diruser,
pthread_mutex_unlock (&dnp->lock);
}
- /* If the looked-up file carries a fake reference, we
- use that and clear the FAKE_REFERENCE flag. */
- if (np->nn->faked & FAKE_REFERENCE)
- np->nn->faked &= ~FAKE_REFERENCE;
- else
- netfs_nref (np);
-
+ netfs_nref (np);
err = check_openmodes (np->nn, (flags & (O_RDWR|O_EXEC)), file);
pthread_mutex_unlock (&idport_ihash_lock);
}
@@ -384,7 +386,10 @@ netfs_S_dir_lookup (struct protid *diruser,
err = new_node (file, idport, 1, flags, &np);
pthread_mutex_unlock (&dnp->lock);
if (!err)
- err = netfs_validate_stat (np, diruser->user);
+ {
+ set_default_attributes (np);
+ err = netfs_validate_stat (np, diruser->user);
+ }
}
if (err)
goto lose;
@@ -404,8 +409,6 @@ netfs_S_dir_lookup (struct protid *diruser,
}
else
{
- err = netfs_attempt_chown (user, np, 0, 0);
- assert_perror (err); /* Our netfs_attempt_chown cannot fail. */
*retry_port = ports_get_right (newpi);
*retry_port_type = MACH_MSG_TYPE_MAKE_SEND;
ports_port_deref (newpi);
@@ -467,12 +470,12 @@ netfs_attempt_chown (struct iouser *cred, struct node *np,
{
if (uid != -1)
{
- np->nn->faked |= FAKE_UID;
+ set_faked_attribute (np, FAKE_UID);
np->nn_stat.st_uid = uid;
}
if (gid != -1)
{
- np->nn->faked |= FAKE_GID;
+ set_faked_attribute (np, FAKE_GID);
np->nn_stat.st_gid = gid;
}
return 0;
@@ -481,7 +484,7 @@ netfs_attempt_chown (struct iouser *cred, struct node *np,
error_t
netfs_attempt_chauthor (struct iouser *cred, struct node *np, uid_t author)
{
- np->nn->faked |= FAKE_AUTHOR;
+ set_faked_attribute (np, FAKE_AUTHOR);
np->nn_stat.st_author = author;
return 0;
}
@@ -509,17 +512,11 @@ netfs_attempt_chmod (struct iouser *cred, struct node
*np, mode_t mode)
mode |= np->nn_stat.st_mode & S_IFMT;
if ((mode & S_IFMT) != (np->nn_stat.st_mode & S_IFMT))
return EOPNOTSUPP;
- if (((mode | (mode << 3) | (mode << 6))
- ^ (np->nn_stat.st_mode | (np->nn_stat.st_mode << 3)
- | (np->nn_stat.st_mode << 6)))
- & S_IEXEC)
- {
- /* We are changing the executable bit, so this is not all fake. We
- don't bother with error checking since the fake mode change should
- always succeed--worst case a later open will get EACCES. */
- (void) file_chmod (np->nn->file, real_from_fake_mode (mode));
- }
- np->nn->faked |= FAKE_MODE;
+
+ /* We don't bother with error checking since the fake mode change should
+ always succeed--worst case a later open will get EACCES. */
+ (void) file_chmod (np->nn->file, mode);
+ set_faked_attribute (np, FAKE_MODE);
np->nn_stat.st_mode = mode;
return 0;
}
@@ -668,11 +665,11 @@ netfs_attempt_mkfile (struct iouser *user, struct node
*dir,
file_t newfile;
error_t err = dir_mkfile (dir->nn->file, O_RDWR|O_EXEC,
real_from_fake_mode (mode), &newfile);
+ pthread_mutex_unlock (&dir->lock);
if (err == 0)
err = new_node (newfile, MACH_PORT_NULL, 0, O_RDWR|O_EXEC, np);
if (err == 0)
pthread_mutex_unlock (&(*np)->lock);
- pthread_mutex_unlock (&dir->lock);
return err;
}
@@ -1020,7 +1017,7 @@ any user to open nodes regardless of permissions as is
done for root." };
netfs_root_node->nn_stat.st_mode &= ~(S_IPTRANS | S_IATRANS);
netfs_root_node->nn_stat.st_mode |= S_IROOT;
- netfs_root_node->nn->faked |= FAKE_MODE;
+ set_faked_attribute (netfs_root_node, FAKE_MODE);
pthread_mutex_unlock (&netfs_root_node->lock);
netfs_server_loop (); /* Never returns. */
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git