From: Ondrej Lichtner <olichtne(a)redhat.com>
This commit fixes a deadlock situation that appears in case we interrupt
a command which results in the command ending a large amount of data at
once through the communication pipe. The pipe is buffered so the write
operation starts blocking until somebody starts reading from the pipe.
However the main process that would be reading this message is waiting
in a join() call creating a deadlock.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/NetTestCommand.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/lnst/Common/NetTestCommand.py b/lnst/Common/NetTestCommand.py
index 2ce9b67..b5569a5 100644
--- a/lnst/Common/NetTestCommand.py
+++ b/lnst/Common/NetTestCommand.py
@@ -144,7 +144,6 @@ class NetTestCommand:
if os.path.exists("/proc/%d" % self._pid):
logging.debug("Interrupting background command with id \"%s\",
pid \"%d\"" % (self._id, self._pid))
os.killpg(os.getpgid(self._pid), signal.SIGINT)
- self._process.join()
def kill(self):
if os.path.exists("/proc/%d" % self._pid):
--
1.7.11.7
Show replies by date
From: Ondrej Lichtner <olichtne(a)redhat.com>
When using the Connection object for communication it is unnecessary to
pickle our data as this is automatically handled by the Connection
object.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/ConnectionHandler.py | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/lnst/Common/ConnectionHandler.py b/lnst/Common/ConnectionHandler.py
index eb80055..8e9e548 100644
--- a/lnst/Common/ConnectionHandler.py
+++ b/lnst/Common/ConnectionHandler.py
@@ -17,16 +17,15 @@ import socket
from _multiprocessing import Connection
def send_data(s, data):
- pickled_data = cPickle.dumps(data)
- length = len(pickled_data)
-
- data_to_send = str(length) + " " + pickled_data
-
try:
if isinstance(s, socket.SocketType):
+ pickled_data = cPickle.dumps(data)
+ length = len(pickled_data)
+
+ data_to_send = str(length) + " " + pickled_data
s.sendall(data_to_send)
elif isinstance(s, Connection):
- s.send(pickled_data)
+ s.send(data)
else:
return False
except socket.error:
@@ -57,7 +56,6 @@ def recv_data(s):
data = cPickle.loads(data)
elif isinstance(s, Connection):
data = s.recv()
- data = cPickle.loads(data)
else:
return None
return data
--
1.7.11.7
From: Ondrej Lichtner <olichtne(a)redhat.com>
This commit adds a new method that can be used to remove all the
handlers in the logging system. This effectively disables the logging
functionality and any log messages will be discarded.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/Logs.py | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/lnst/Common/Logs.py b/lnst/Common/Logs.py
index f00082d..032a4af 100644
--- a/lnst/Common/Logs.py
+++ b/lnst/Common/Logs.py
@@ -78,6 +78,7 @@ class MultilineFormater(Formatter):
class LoggingCtl:
log_folder = ""
formatter = None
+ display_handler = None
recipe_handlers = (None,None)
recipe_log_path = ""
slaves = {}
@@ -101,19 +102,19 @@ class LoggingCtl:
#the display_handler will display logs in the terminal
- display_handler = logging.StreamHandler(sys.stdout)
- display_handler.setFormatter(self.formatter)
+ self.display_handler = logging.StreamHandler(sys.stdout)
+ self.display_handler.setFormatter(self.formatter)
if not debug:
- display_handler.setLevel(logging.INFO)
+ self.display_handler.setLevel(logging.INFO)
else:
if debug == 1:
- display_handler.setLevel(logging.DEBUG)
+ self.display_handler.setLevel(logging.DEBUG)
else:
- display_handler.setLevel(logging.NOTSET)
+ self.display_handler.setLevel(logging.NOTSET)
logger = logging.getLogger()
logger.setLevel(logging.NOTSET)
- logger.addHandler(display_handler)
+ logger.addHandler(self.display_handler)
def set_recipe(self, recipe_path, clean=True, expand=""):
recipe_name = os.path.splitext(os.path.split(recipe_path)[1])[0]
@@ -162,7 +163,7 @@ class LoggingCtl:
logger.removeHandler(self.slaves[name][0])
logger.removeHandler(self.slaves[name][1])
- del slaves[name]
+ del self.slaves[name]
def set_connection(self, target):
if self.transmit_handler != None:
@@ -181,6 +182,17 @@ class LoggingCtl:
logger.removeHandler(self.transmit_handler)
del self.transmit_handler
+ def disable_logging(self):
+ self.cancel_connection()
+
+ for s in self.slaves.keys():
+ self.remove_slave(s)
+
+ self.unset_recipe()
+ logger = logging.getLogger()
+ logger.removeHandler(self.display_handler)
+ self.display_handler = None
+
def _clean_folder(self, path):
try:
shutil.rmtree(path)
--
1.7.11.7
From: Ondrej Lichtner <olichtne(a)redhat.com>
The NetTestCommand object only disabled the recipe handler and the
connection handler. This was incorrect as it ment that the logs from
commands wouldn't be saved on the slave machine. Also when there were
multiple commands running they would be accessing the tty without
synchronization which is probably not correct.
This commit changes the behaviour by calling the disable_logging method
which clears all the handlers to files, tty or sockets. And after
creates a new connection handler that forwards the log messages to the
main server process.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/NetTestCommand.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lnst/Common/NetTestCommand.py b/lnst/Common/NetTestCommand.py
index b5569a5..57a9350 100644
--- a/lnst/Common/NetTestCommand.py
+++ b/lnst/Common/NetTestCommand.py
@@ -107,9 +107,8 @@ class NetTestCommand:
self._connection_pipe = self._write_pipe
- self._log_ctl.unset_recipe()
- self._log_ctl.cancel_connection()
- self._log_ctl.set_connection(self._write_pipe)
+ self._log_ctl.disable_logging()
+ self._log_ctl.set_connection(self._connection_pipe)
result = {}
try:
--
1.7.11.7
From: Ondrej Lichtner <olichtne(a)redhat.com>
The server process now handles the logs from the commands by directing
them to its root logger which will result in the log message being
written on the tty, the log file and sent to the controller.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Slave/NetTestSlave.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py
index be85da4..5e71ba1 100644
--- a/lnst/Slave/NetTestSlave.py
+++ b/lnst/Slave/NetTestSlave.py
@@ -396,9 +396,9 @@ class NetTestSlave:
self._cmd_context.cleanup()
self._log_ctl.cancel_connection()
elif msg["type"] == "log":
- if not self._server_handler.send_data_to_ctl(msg):
- self._cmd_context.cleanup()
- self._log_ctl.cancel_connection()
+ logger = logging.getLogger()
+ record = logging.makeLogRecord(msg["record"])
+ logger.handle(record)
elif msg["type"] == "exception":
if msg["cmd_id"] != None:
logging.debug("Recieved an exception from command with id: %s"
--
1.7.11.7