xend: fix migration hangs by closing fds on exec

Signed-off-by: Zhigang Wang <zhigang.x.wang@oracle.com>
Reviewed-by: Xiaowei Hu <xiaowei.hu@oracle.com>
This commit is contained in:
Keir Fraser committed 2009-07-28 16:33:46 +01:00
1 parent dd512dd1e2
commit 54b4e4c5df
7 files changed
+41 -16

No files matched your search

+13
View File
@@ -1,6 +1,19 @@
import fcntl
import os
def close_fds(pass_fds=()):
try:
MAXFD = os.sysconf('SC_OPEN_MAX')
except:
MAXFD = 256
for i in range(3, MAXFD):
if i in pass_fds:
continue
try:
os.close(i)
except OSError:
pass
def fcntl_setfd_cloexec(file, bool):
f = fcntl.fcntl(file, fcntl.F_GETFD)
if bool: f |= fcntl.FD_CLOEXEC
+19 -5
View File
@@ -85,7 +85,7 @@ class xPopen3:
sts = -1 # Child not completed yet
def __init__(self, cmd, capturestderr=False, bufsize=-1, passfd=()):
def __init__(self, cmd, capturestderr=False, bufsize=-1, passfd=(), env=None):
"""The parameter 'cmd' is the shell command to execute in a
sub-process. The 'capturestderr' flag, if true, specifies that
the object should capture standard error output of the child process.
@@ -128,6 +128,10 @@ class xPopen3:
pass
try:
os.execvp(cmd[0], cmd)
if env is None:
os.execvp(cmd[0], cmd)
else:
os.execvpe(cmd[0], cmd, env)
finally:
os._exit(127)
@@ -154,16 +158,26 @@ class xPopen3:
return self.sts
def xpopen2(cmd, bufsize=-1, mode='t', passfd=[]):
def xpopen2(cmd, bufsize=-1, mode='t', passfd=[], env=None):
"""Execute the shell command 'cmd' in a sub-process. If 'bufsize' is
specified, it sets the buffer size for the I/O pipes. The file objects
(child_stdout, child_stdin) are returned."""
inst = xPopen3(cmd, False, bufsize, passfd)
inst = xPopen3(cmd, False, bufsize, passfd, env)
return inst.fromchild, inst.tochild
def xpopen3(cmd, bufsize=-1, mode='t', passfd=[]):
def xpopen3(cmd, bufsize=-1, mode='t', passfd=[], env=None):
"""Execute the shell command 'cmd' in a sub-process. If 'bufsize' is
specified, it sets the buffer size for the I/O pipes. The file objects
(child_stdout, child_stdin, child_stderr) are returned."""
inst = xPopen3(cmd, True, bufsize, passfd)
inst = xPopen3(cmd, True, bufsize, passfd, env)
return inst.fromchild, inst.tochild, inst.childerr
def call(*popenargs, **kwargs):
"""Run command with arguments. Wait for command to complete, then
return the status.
The arguments are the same as for the xPopen3 constructor. Example:
status = call("ls -l")
"""
return xPopen3(*popenargs, **kwargs).wait()
+2 -2
View File
@@ -31,7 +31,7 @@ from xen.xend import XendConstants
from xen.xend import XendOptions
from xen.xend.XendLogging import log
from xen.xend.XendError import VmError
from xen.util import dictio, xsconstants, auxbin
from xen.util import dictio, xsconstants, auxbin, xpopen
from xen.xend.XendConstants import *
#global directories and tools for security management
@@ -1710,7 +1710,7 @@ def run_resource_label_change_script(resource, label, command):
log.info("Running resource label change script %s: %s" %
(script, parms))
parms.update(os.environ)
os.spawnve(os.P_WAIT, script[0], script, parms)
xpopen.call(" ".join(script, params))
else:
log.info("No script given for relabeling of resources.")
if not __script_runner:
+2 -3
View File
@@ -18,10 +18,9 @@
"""Xend interface to networking control scripts.
"""
import os
import XendOptions
from xen.util import xpopen
def network(op):
"""Call a network control script.
@@ -33,4 +32,4 @@ def network(op):
script = XendOptions.instance().get_network_script()
if script:
script.insert(1, op)
os.spawnv(os.P_WAIT, script[0], script)
xpopen.call(script)
+2 -1
View File
@@ -17,7 +17,7 @@ import random
import shlex
from xen.xend import sxp
from xen.util import mkdir
from xen.util import mkdir, oshelp
from XendLogging import log
from XendError import VmError
@@ -113,6 +113,7 @@ def bootloader(blexec, disk, dom, quiet = False, blargs = '', kernel = '',
log.debug("Launching bootloader as %s." % str(args))
env = os.environ.copy()
env['TERM'] = 'vt100'
oshelp.close_fds()
os.execvpe(args[0], args, env)
except OSError, e:
print e
+1 -3
View File
@@ -431,9 +431,7 @@ class ImageHandler:
os.dup2(null, 0)
os.dup2(logfd, 1)
os.dup2(logfd, 2)
os.close(null)
os.close(logfd)
self.sentinel_fifo.close()
oshelp.close_fds((sentinel_write.fileno(),))
try:
os.execve(self.device_model, args, env)
except Exception, e:
@@ -1,9 +1,9 @@
# Copyright (c) 2005, XenSource Ltd.
import string, re
import popen2
from xen.xend.server.blkif import BlkifController
from xen.xend.XendLogging import log
from xen.util.xpopen import xPopen3
phantomDev = 0;
phantomId = 0;
@@ -34,7 +34,7 @@ blktap_disk_types = blktap1_disk_types + blktap2_disk_types
def doexec(args, inputtext=None):
"""Execute a subprocess, then return its return code, stdout and stderr"""
proc = popen2.Popen3(args, True)
proc = xPopen3(args, True)
if inputtext != None:
proc.tochild.write(inputtext)
stdout = proc.fromchild
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.