summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergiu Ivanov <unlimitedscolobb@gmail.com>2009-04-12 22:31:26 +0300
committerSergiu Ivanov <unlimitedscolobb@gmail.com>2009-04-12 22:31:26 +0300
commit0a5fcd403943fbbdc0a2ba35283f1135f97c48dc (patch)
tree538585395c4376368118a32d93e1c83569bf4a0d
parent68c018b02a8eff826cd30480ce73202ce9cc9e48 (diff)
Added dynamic translator tracking facilities
nsmux cannot presently shut down gracefully (without the -f option) after having done a magic lookup, because the dynamic translators it starts hold ports (references) to its nodes and make the standard fsys_goaway handler return with EBUSY. To solve the problem, nsmux will need to keep track of dynamic translators and shut them down explicitly, not relying on standard mechanisms, which don't know that the translators might be stacked and might try stopping a translator in the middle of the dynamic stack, which will certainly result in EBUSY. (Note that this commit comes on top of an erroneous one and is meant to fix it. I could not revert the previous commit because of ``bad index'', so I hope this commit will solve the problem...)
-rwxr-xr-xbuild2
-rw-r--r--node.h12
-rw-r--r--trans.c108
-rw-r--r--trans.h73
4 files changed, 182 insertions, 13 deletions
diff --git a/build b/build
index 2234dad6f..bfe91357a 100755
--- a/build
+++ b/build
@@ -1 +1 @@
-gcc -DDEBUG -Wall -g -lnetfs -lfshelp -liohelp -lthreads -lports -lihash -lshouldbeinlibc -o nsmux nsmux.c node.c lnode.c ncache.c options.c lib.c 2>&1 | tee errors
+gcc -DDEBUG -Wall -g -lnetfs -lfshelp -liohelp -lthreads -lports -lihash -lshouldbeinlibc -o nsmux nsmux.c node.c lnode.c ncache.c options.c lib.c magic.c trans.c 2>&1 | tee errors
diff --git a/node.h b/node.h
index de0013086..72adcbebb 100644
--- a/node.h
+++ b/node.h
@@ -59,18 +59,6 @@
/*---------------------------------------------------------------------------*/
/*--------Types--------------------------------------------------------------*/
-/*A list element containing a port*/
-struct port_el
-{
- /*the port */
- mach_port_t p;
-
- /*the next element in the list */
- struct port_el *next;
-}; /*struct port_el */
-/*---------------------------------------------------------------------------*/
-typedef struct port_el port_el_t;
-/*---------------------------------------------------------------------------*/
/*The user-defined node for libnetfs*/
struct netnode
{
diff --git a/trans.c b/trans.c
new file mode 100644
index 000000000..8d05286ce
--- /dev/null
+++ b/trans.c
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------------*/
+/*trans.c*/
+/*---------------------------------------------------------------------------*/
+/*Facilities to keep track of dynamic translators.*/
+/*---------------------------------------------------------------------------*/
+/*Copyright (C) 2008, 2009 Free Software Foundation, Inc. Written 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
+ License, or * (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.*/
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+#define _GNU_SOURCE 1
+/*---------------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <hurd/fsys.h>
+/*---------------------------------------------------------------------------*/
+#include "trans.h"
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*---------Variables---------------------------------------------------------*/
+/*The list of dynamic translators */
+trans_el_t * dyntrans = NULL;
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*---------Functions---------------------------------------------------------*/
+/*Adds a translator control port to the list of ports. One should use
+ only this function to add a new element to the list of ports. */
+error_t
+trans_register (mach_port_t cntl)
+{
+ /*The new entry in the list */
+ trans_el_t * el;
+
+ el = malloc (sizeof (trans_el_t));
+ if (!el)
+ return ENOMEM;
+
+ el->cntl = cntl;
+
+ el->prev = NULL;
+ el->next = dyntrans;
+ dyntrans = el;
+
+ return 0;
+} /*trans_register */
+
+/*---------------------------------------------------------------------------*/
+/*Removes a translator control port from the list of ports. One should
+ use only this function to remove an element from the list of
+ ports. This function does not shut down the translator. */
+void
+trans_unregister (trans_el_t * trans)
+{
+ if (trans->prev)
+ trans->prev->next = trans->next;
+ if(trans->next)
+ trans->next->prev = trans->prev;
+
+ free(trans);
+} /*trans_unregister */
+
+/*---------------------------------------------------------------------------*/
+/*Gracefully shuts down all the translators registered in the
+ list with `flags`. */
+error_t
+trans_shutdown_all (int flags)
+{
+ error_t err;
+
+ /*The element being dealt with now. */
+ trans_el_t * el;
+
+ for (el = dyntrans; el; el = el->next)
+ {
+ err = fsys_goaway (el->cntl, flags);
+
+ if (err)
+ {
+ /*The error cannot happen because the translators are being
+ shut down in the incorrect order, so something is
+ wrong. Stop and update dyntrans. */
+
+ dyntrans = el;
+ return err;
+ }
+ }
+
+ dyntrans = NULL;
+ return 0;
+} /*trans_shutdown_all */
+
+/*---------------------------------------------------------------------------*/
diff --git a/trans.h b/trans.h
new file mode 100644
index 000000000..86e21c9d6
--- /dev/null
+++ b/trans.h
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------------*/
+/*trans.h*/
+/*---------------------------------------------------------------------------*/
+/*Facilities to keep track of dynamic translators.*/
+/*---------------------------------------------------------------------------*/
+/*Copyright (C) 2008, 2009 Free Software Foundation, Inc. Written 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
+ License, or * (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.*/
+/*---------------------------------------------------------------------------*/
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+/*---------------------------------------------------------------------------*/
+#include <hurd.h>
+#include <error.h>
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*---------Types-------------------------------------------------------------*/
+/*An element in the list of dynamic translators */
+struct trans_el
+{
+ /*the control port to the translator */
+ mach_port_t cntl;
+
+ /*the next and the previous elements in the list */
+ struct trans_el * next, * prev;
+}; /*struct trans_el */
+/*---------------------------------------------------------------------------*/
+typedef struct trans_el trans_el_t;
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*---------Variables---------------------------------------------------------*/
+/*The list of dynamic translators */
+extern trans_el_t * dyntrans;
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*---------Functions---------------------------------------------------------*/
+/*Adds a translator control port to the list of ports. One should use
+ only this function to add a new element to the list of ports. */
+error_t
+trans_register (mach_port_t cntl);
+/*---------------------------------------------------------------------------*/
+/*Removes a translator control port from the list of ports. One should
+ use only this function to remove an element from the list of
+ ports. This function does not shut down the translator. */
+void
+trans_unregister (trans_el_t * trans);
+/*---------------------------------------------------------------------------*/
+/*Gracefully shuts down all the translators registered in the
+ list with `flags`. */
+error_t
+trans_shutdown_all (int flags);
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+#endif /*__TRANS_H__*/