commit-hurd
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]