Revision f9323011 daemons/import-export

b/daemons/import-export
207 207

  
208 208

  
209 209
def ProcessChildIO(child, socat_stderr_read_fd, dd_stderr_read_fd,
210
                   dd_pid_read_fd, status_file, child_logger,
210
                   dd_pid_read_fd, exp_size_read_fd, status_file, child_logger,
211 211
                   signal_notify, signal_handler, mode):
212 212
  """Handles the child processes' output.
213 213

  
......
221 221
  socat_stderr_read = os.fdopen(socat_stderr_read_fd, "r", 0)
222 222
  dd_stderr_read = os.fdopen(dd_stderr_read_fd, "r", 0)
223 223
  dd_pid_read = os.fdopen(dd_pid_read_fd, "r", 0)
224
  exp_size_read = os.fdopen(exp_size_read_fd, "r", 0)
224 225

  
225 226
  tp_samples = DD_THROUGHPUT_SAMPLES
226 227

  
228
  if options.exp_size == constants.IE_CUSTOM_SIZE:
229
    exp_size = None
230
  else:
231
    exp_size = options.exp_size
232

  
227 233
  child_io_proc = impexpd.ChildIOProcessor(options.debug, status_file,
228
                                           child_logger,
229
                                           throughput_samples=tp_samples)
234
                                           child_logger, tp_samples,
235
                                           exp_size)
230 236
  try:
231 237
    fdmap = {
232 238
      child.stderr.fileno():
......
237 243
        (dd_pid_read, child_io_proc.GetLineSplitter(impexpd.PROG_DD_PID)),
238 244
      dd_stderr_read.fileno():
239 245
        (dd_stderr_read, child_io_proc.GetLineSplitter(impexpd.PROG_DD)),
246
      exp_size_read.fileno():
247
        (exp_size_read, child_io_proc.GetLineSplitter(impexpd.PROG_EXP_SIZE)),
240 248
      signal_notify.fileno(): (signal_notify, None),
241 249
      }
242 250

  
......
372 380
                    type="choice", help="Compression method",
373 381
                    metavar="[%s]" % "|".join(constants.IEC_ALL),
374 382
                    choices=list(constants.IEC_ALL), default=constants.IEC_GZIP)
383
  parser.add_option("--expected-size", dest="exp_size", action="store",
384
                    type="string", default=None,
385
                    help="Expected import/export size (MiB)")
375 386
  parser.add_option("--cmd-prefix", dest="cmd_prefix", action="store",
376 387
                    type="string", help="Command prefix")
377 388
  parser.add_option("--cmd-suffix", dest="cmd_suffix", action="store",
......
390 401
    # Won't return
391 402
    parser.error("Invalid mode: %s" % mode)
392 403

  
404
  if (options.exp_size is not None and
405
      options.exp_size != constants.IE_CUSTOM_SIZE):
406
    try:
407
      options.exp_size = int(options.exp_size)
408
    except (ValueError, TypeError), err:
409
      # Won't return
410
      parser.error("Invalid value for --expected-size: %s (%s)" %
411
                   (options.exp_size, err))
412

  
393 413
  return (status_file_path, mode)
394 414

  
395 415

  
396 416
class ChildProcess(subprocess.Popen):
397
  def __init__(self, cmd, noclose_fds):
417
  def __init__(self, env, cmd, noclose_fds):
398 418
    """Initializes this class.
399 419

  
400 420
    """
......
402 422

  
403 423
    # Not using close_fds because doing so would also close the socat stderr
404 424
    # pipe, which we still need.
405
    subprocess.Popen.__init__(self, cmd, shell=False, close_fds=False,
425
    subprocess.Popen.__init__(self, cmd, env=env, shell=False, close_fds=False,
406 426
                              stderr=subprocess.PIPE, stdout=None, stdin=None,
407 427
                              preexec_fn=self._ChildPreexec)
408 428
    self._SetProcessGroup()
......
474 494
      # Pipe to receive dd's PID
475 495
      (dd_pid_read_fd, dd_pid_write_fd) = os.pipe()
476 496

  
497
      # Pipe to receive size predicted by export script
498
      (exp_size_read_fd, exp_size_write_fd) = os.pipe()
499

  
477 500
      # Get child process command
478 501
      cmd_builder = impexpd.CommandBuilder(mode, options, socat_stderr_write_fd,
479 502
                                           dd_stderr_write_fd, dd_pid_write_fd)
480 503
      cmd = cmd_builder.GetCommand()
481 504

  
505
      # Prepare command environment
506
      cmd_env = os.environ.copy()
507

  
508
      if options.exp_size == constants.IE_CUSTOM_SIZE:
509
        cmd_env["EXP_SIZE_FD"] = str(exp_size_write_fd)
510

  
482 511
      logging.debug("Starting command %r", cmd)
483 512

  
484 513
      # Start child process
485
      child = ChildProcess(cmd, [socat_stderr_write_fd, dd_stderr_write_fd,
486
                                 dd_pid_write_fd])
514
      child = ChildProcess(cmd_env, cmd,
515
                           [socat_stderr_write_fd, dd_stderr_write_fd,
516
                            dd_pid_write_fd, exp_size_write_fd])
487 517
      try:
488 518
        def _ForwardSignal(signum, _):
489 519
          """Forwards signals to child process.
......
506 536
            utils.RetryOnSignal(os.close, socat_stderr_write_fd)
507 537
            utils.RetryOnSignal(os.close, dd_stderr_write_fd)
508 538
            utils.RetryOnSignal(os.close, dd_pid_write_fd)
539
            utils.RetryOnSignal(os.close, exp_size_write_fd)
509 540

  
510 541
            if ProcessChildIO(child, socat_stderr_read_fd, dd_stderr_read_fd,
511
                              dd_pid_read_fd, status_file, child_logger,
542
                              dd_pid_read_fd, exp_size_read_fd,
543
                              status_file, child_logger,
512 544
                              signal_wakeup, signal_handler, mode):
513 545
              # The child closed all its file descriptors and there was no
514 546
              # signal

Also available in: Unified diff