diff options
author | Sergiu Ivanov <unlimitedscolobb@gmail.com> | 2009-04-12 22:31:26 +0300 |
---|---|---|
committer | Sergiu Ivanov <unlimitedscolobb@gmail.com> | 2009-04-12 22:31:26 +0300 |
commit | 0a5fcd403943fbbdc0a2ba35283f1135f97c48dc (patch) | |
tree | 538585395c4376368118a32d93e1c83569bf4a0d | |
parent | 68c018b02a8eff826cd30480ce73202ce9cc9e48 (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-x | build | 2 | ||||
-rw-r--r-- | node.h | 12 | ||||
-rw-r--r-- | trans.c | 108 | ||||
-rw-r--r-- | trans.h | 73 |
4 files changed, 182 insertions, 13 deletions
@@ -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 @@ -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__*/ |