]> sourceware.org Git - lvm2.git/commitdiff
lvmdbusd: Extra report FD read on no data
authorTony Asleson <tasleson@redhat.com>
Wed, 16 Nov 2016 21:57:04 +0000 (15:57 -0600)
committerTony Asleson <tasleson@redhat.com>
Thu, 17 Nov 2016 17:35:16 +0000 (11:35 -0600)
Our expectation was that when using the lvm shell that when the lvm prompt
was read from stdout, that all other ouput had been written and flushed.
However, this doesn't appear to be the case.  Add extra read passes to
retrieve delayed report data.

daemons/lvmdbusd/lvm_shell_proxy.py

index 4cdb71774a86976b48c6c363b405f34b8a2dd2cd..193c844a59aac9358b6596f49d2df74ff1e6e60d 100755 (executable)
@@ -42,16 +42,19 @@ def _quote_arg(arg):
 
 
 class LVMShellProxy(object):
-       def _read_until_prompt(self):
+       def _read_until_prompt(self, no_output=False):
                stdout = ""
                report = ""
                stderr = ""
+               keep_reading = True
+               extra_passes = 2
 
                # Try reading from all FDs to prevent one from filling up and causing
-               # a hang.  We are also assuming that we won't get the lvm prompt back
+               # a hang.  We were assuming that we won't get the lvm prompt back
                # until we have already received all the output from stderr and the
-               # report descriptor too.
-               while not stdout.endswith(SHELL_PROMPT):
+               # report descriptor too, this is an incorrect assumption.  Lvm will
+               # return the prompt before we get the report!
+               while keep_reading:
                        try:
                                rd_fd = [
                                        self.lvm_shell.stdout.fileno(),
@@ -90,6 +93,22 @@ class LVMShellProxy(object):
                                if self.lvm_shell.poll():
                                        raise Exception(self.lvm_shell.returncode, "%s" % stderr)
 
+                               if stdout.endswith(SHELL_PROMPT):
+                                       # It appears that lvm doesn't write the report and flush
+                                       # that before it writes the shell prompt as occasionally
+                                       # we get the prompt with no report.
+                                       if no_output:
+                                               keep_reading = False
+                                       else:
+                                               # Most of the time we have data, if we have none lets
+                                               # take another spin and hope we get it.
+                                               if len(report) != 0:
+                                                       keep_reading = False
+                                               else:
+                                                       extra_passes -= 1
+                                                       if extra_passes <= 0:
+                                                               keep_reading = False
+
                        except IOError as ioe:
                                log_debug(str(ioe))
                                pass
@@ -141,7 +160,7 @@ class LVMShellProxy(object):
                        fcntl(self.lvm_shell.stderr, F_SETFL, flags | os.O_NONBLOCK)
 
                        # wait for the first prompt
-                       errors = self._read_until_prompt()[2]
+                       errors = self._read_until_prompt(no_output=True)[2]
                        if errors and len(errors):
                                raise RuntimeError(errors)
                except:
This page took 0.039174 seconds and 5 git commands to generate.