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