mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Merged.
This commit is contained in:
commit
2fdffd69ae
7 files changed
+155
-101
No files matched your search
@@ -89,6 +89,31 @@ legacy_mask_to_prefix() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
parse_kernel_ip() {
|
||||
if egrep 'ip=[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:' /proc/cmdline; then
|
||||
kip=`sed -e 's!.*ip=\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\):.*!\1!' /proc/cmdline`
|
||||
kmask=`sed -e 's!.*ip=[^:]*:[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
|
||||
kgate=`sed -e 's!.*ip=[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
|
||||
fi
|
||||
}
|
||||
|
||||
do_ifup() {
|
||||
if ! ifup $1 ; then
|
||||
if [ ${kip} ] ; then
|
||||
# use the addresses we grocked from /proc/cmdline
|
||||
if [ -z "${kmask}" ]; then
|
||||
PREFIX=32
|
||||
else
|
||||
legacy_mask_to_prefix ${kmask}
|
||||
fi
|
||||
ip addr flush $1
|
||||
ip addr add ${kip}/${PREFIX} dev $1
|
||||
ip link set dev $1 up
|
||||
[ ${kgate} ] && ip route add default via ${kgate}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage: transfer_addrs src dst
|
||||
# Copy all IP addresses (including aliases) from device $src to device $dst.
|
||||
transfer_addrs () {
|
||||
@@ -234,14 +259,11 @@ using loopback.nloopbacks=<N> on the domain 0 kernel command line.
|
||||
preiftransfer ${netdev}
|
||||
transfer_addrs ${netdev} ${vdev}
|
||||
if ! ifdown ${netdev}; then
|
||||
# if ifup didn't work, see if we have an ip= on cmd line
|
||||
if egrep 'ip=[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:' /proc/cmdline; then
|
||||
kip=`sed -e 's!.*ip=\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\):.*!\1!' /proc/cmdline`
|
||||
kmask=`sed -e 's!.*ip=[^:]*:[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
|
||||
kgate=`sed -e 's!.*ip=[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
|
||||
ip link set ${netdev} down
|
||||
ip addr flush ${netdev}
|
||||
fi
|
||||
# If ifdown fails, take the IP details from the kernel command
|
||||
# line.
|
||||
parse_kernel_ip
|
||||
ip link set ${netdev} down
|
||||
ip addr flush ${netdev}
|
||||
fi
|
||||
ip link set ${netdev} name ${pdev}
|
||||
ip link set ${vdev} name ${netdev}
|
||||
@@ -253,20 +275,8 @@ using loopback.nloopbacks=<N> on the domain 0 kernel command line.
|
||||
add_to_bridge ${bridge} ${pdev}
|
||||
ip link set ${bridge} up
|
||||
ip link set ${vif0} up
|
||||
ip link set ${pdev} up
|
||||
if ! ifup ${netdev} ; then
|
||||
if [ ${kip} ] ; then
|
||||
# use the addresses we grocked from /proc/cmdline
|
||||
if [ -z "${kmask}" ]; then
|
||||
PREFIX=32;
|
||||
else
|
||||
legacy_mask_to_prefix ${kmask};
|
||||
fi
|
||||
ip addr add ${kip}/${PREFIX} dev ${netdev}
|
||||
ip link set dev ${netdev} up
|
||||
[ ${kgate} ] && ip route add default via ${kgate}
|
||||
fi
|
||||
fi
|
||||
ip link set ${pdev} up
|
||||
do_ifup ${netdev}
|
||||
else
|
||||
# old style without ${vdev}
|
||||
transfer_addrs ${netdev} ${bridge}
|
||||
@@ -290,7 +300,9 @@ op_stop () {
|
||||
ip link set dev ${vif0} down
|
||||
mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
||||
transfer_addrs ${netdev} ${pdev}
|
||||
ifdown ${netdev}
|
||||
if ! ifdown ${netdev}; then
|
||||
parse_kernel_ip
|
||||
fi
|
||||
ip link set ${netdev} down arp off
|
||||
ip link set ${netdev} addr fe:ff:ff:ff:ff:ff
|
||||
ip link set ${pdev} down
|
||||
@@ -303,8 +315,7 @@ op_stop () {
|
||||
|
||||
ip link set ${netdev} name ${vdev}
|
||||
ip link set ${pdev} name ${netdev}
|
||||
ifup ${netdev}
|
||||
|
||||
do_ifup ${netdev}
|
||||
else
|
||||
transfer_routes ${bridge} ${netdev}
|
||||
ip link set ${bridge} down
|
||||
|
||||
@@ -61,9 +61,8 @@ case "$command" in
|
||||
;;
|
||||
|
||||
offline)
|
||||
brctl delif "$bridge" "$vif" ||
|
||||
log debug "brctl delif $bridge $vif failed"
|
||||
ifconfig "$vif" down || log debug "ifconfig $vif down failed"
|
||||
do_without_error brctl delif "$bridge" "$vif"
|
||||
do_without_error ifconfig "$vif" down
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ function handle_iptable()
|
||||
#
|
||||
function ip_of()
|
||||
{
|
||||
ip addr show "$1" | sed -n 's/^.*inet \([0-9.]*\).*$/\1/p'
|
||||
ip addr show "$1" | awk "/^.*inet.*$1\$/{print \$2}" | sed 's,/.*,,'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ case "$command" in
|
||||
;;
|
||||
offline)
|
||||
[ "$dhcp" != 'no' ] && dhcp_down
|
||||
ifconfig "$vif" down || true
|
||||
do_without_error ifconfig "$vif" down
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ do_or_die() {
|
||||
"$@" || fatal "$@ failed"
|
||||
}
|
||||
|
||||
do_without_error() {
|
||||
"$@" 2>/dev/null || log debug "$@ failed"
|
||||
}
|
||||
|
||||
sigerr() {
|
||||
fatal "$0 failed; error detected."
|
||||
}
|
||||
@@ -121,7 +125,7 @@ _claim_lock()
|
||||
|
||||
while [ $retries -lt $LOCK_RETRIES ]
|
||||
do
|
||||
mkdir "$lockdir" && trap "release_lock $1; sigerr" ERR &&
|
||||
mkdir "$lockdir" 2>/dev/null && trap "release_lock $1; sigerr" ERR &&
|
||||
_update_lock_info "$lockdir" && return
|
||||
|
||||
local new_owner=$(_lock_owner "$lockdir")
|
||||
|
||||
@@ -23,73 +23,37 @@ import relocate
|
||||
from params import *
|
||||
|
||||
|
||||
XEND_PROCESS_NAME = 'xend'
|
||||
|
||||
|
||||
class Daemon:
|
||||
"""The xend daemon.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.shutdown = 0
|
||||
self.traceon = 0
|
||||
self.traceon = False
|
||||
self.tracefile = None
|
||||
self.traceindent = 0
|
||||
self.child = 0
|
||||
|
||||
def read_pid(self, pidfile):
|
||||
"""Read process id from a file.
|
||||
|
||||
@param pidfile: file to read
|
||||
@return pid or 0
|
||||
"""
|
||||
if os.path.isfile(pidfile) and os.path.getsize(pidfile):
|
||||
try:
|
||||
f = open(pidfile, 'r')
|
||||
try:
|
||||
return int(f.read())
|
||||
finally:
|
||||
f.close()
|
||||
except:
|
||||
return 0
|
||||
else:
|
||||
return 0
|
||||
|
||||
def find_process(self, pid, name):
|
||||
"""Search for a process.
|
||||
|
||||
@param pid: process id
|
||||
@param name: process name
|
||||
@return: pid if found, 0 otherwise
|
||||
"""
|
||||
running = 0
|
||||
if pid:
|
||||
lines = os.popen('ps %d 2>/dev/null' % pid).readlines()
|
||||
exp = '^ *%d.+%s' % (pid, name)
|
||||
for line in lines:
|
||||
if re.search(exp, line):
|
||||
running = pid
|
||||
break
|
||||
return running
|
||||
|
||||
def cleanup_process(self, pidfile, name, kill):
|
||||
"""Clean up the pidfile for a process.
|
||||
def cleanup_xend(self, kill):
|
||||
"""Clean up the Xend pidfile.
|
||||
If a running process is found, kills it if 'kill' is true.
|
||||
|
||||
@param pidfile: pid file
|
||||
@param name: process name
|
||||
@param kill: whether to kill the process
|
||||
@return running process id or 0
|
||||
"""
|
||||
running = 0
|
||||
pid = self.read_pid(pidfile)
|
||||
if self.find_process(pid, name):
|
||||
pid = read_pid(XEND_PID_FILE)
|
||||
if find_process(pid, XEND_PROCESS_NAME):
|
||||
if kill:
|
||||
os.kill(pid, 1)
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
else:
|
||||
running = pid
|
||||
if running == 0 and os.path.isfile(pidfile):
|
||||
os.remove(pidfile)
|
||||
if running == 0 and os.path.isfile(XEND_PID_FILE):
|
||||
os.remove(XEND_PID_FILE)
|
||||
return running
|
||||
|
||||
def cleanup_xend(self, kill):
|
||||
return self.cleanup_process(XEND_PID_FILE, "xend", kill)
|
||||
|
||||
def status(self):
|
||||
"""Returns the status of the xend daemon.
|
||||
@@ -97,15 +61,15 @@ class Daemon:
|
||||
0 Running
|
||||
3 Not running
|
||||
"""
|
||||
if self.cleanup_process(XEND_PID_FILE, "xend", False) == 0:
|
||||
if self.cleanup_xend(False) == 0:
|
||||
return 3
|
||||
else:
|
||||
return 0
|
||||
|
||||
def fork_pid(self, pidfile):
|
||||
"""Fork and write the pid of the child to 'pidfile'.
|
||||
|
||||
@param pidfile: pid file
|
||||
def fork_pid(self):
|
||||
"""Fork and write the pid of the child to XEND_PID_FILE.
|
||||
|
||||
@return: pid of child in parent, 0 in child
|
||||
"""
|
||||
|
||||
@@ -113,7 +77,7 @@ class Daemon:
|
||||
|
||||
if self.child:
|
||||
# Parent
|
||||
pidfile = open(pidfile, 'w')
|
||||
pidfile = open(XEND_PID_FILE, 'w')
|
||||
try:
|
||||
pidfile.write(str(self.child))
|
||||
finally:
|
||||
@@ -121,11 +85,21 @@ class Daemon:
|
||||
|
||||
return self.child
|
||||
|
||||
|
||||
def daemonize(self):
|
||||
if not XEND_DAEMONIZE: return
|
||||
|
||||
# Detach from TTY.
|
||||
|
||||
# Become the group leader (already a child process)
|
||||
os.setsid()
|
||||
|
||||
# Fork, this allows the group leader to exit,
|
||||
# which means the child can never again regain control of the
|
||||
# terminal
|
||||
if os.fork():
|
||||
os._exit(0)
|
||||
|
||||
# Detach from standard file descriptors, and redirect them to
|
||||
# /dev/null or the log as appropriate.
|
||||
os.close(0)
|
||||
@@ -164,7 +138,7 @@ class Daemon:
|
||||
# we can avoid a race condition during startup
|
||||
|
||||
r,w = os.pipe()
|
||||
if self.fork_pid(XEND_PID_FILE):
|
||||
if os.fork():
|
||||
os.close(w)
|
||||
r = os.fdopen(r, 'r')
|
||||
try:
|
||||
@@ -178,8 +152,43 @@ class Daemon:
|
||||
else:
|
||||
os.close(r)
|
||||
# Child
|
||||
self.daemonize()
|
||||
self.tracing(trace)
|
||||
self.run(os.fdopen(w, 'w'))
|
||||
|
||||
# If Xend proper segfaults, then we want to restart it. Thus,
|
||||
# we fork a child for running Xend itself, and if it segfaults
|
||||
# (or exits any way other than cleanly) then we run it again.
|
||||
# The first time through we want the server to write to the (r,w)
|
||||
# pipe created above, so that we do not exit until the server is
|
||||
# ready to receive requests. All subsequent restarts we don't
|
||||
# want this behaviour, or the pipe will eventually fill up, so
|
||||
# we just pass None into run in subsequent cases (by clearing w
|
||||
# in the parent of the first fork).
|
||||
while True:
|
||||
pid = self.fork_pid()
|
||||
if pid:
|
||||
os.close(w)
|
||||
w = False
|
||||
|
||||
(_, status) = os.waitpid(pid, 0)
|
||||
|
||||
if os.WIFEXITED(status):
|
||||
code = os.WEXITSTATUS(status)
|
||||
log.info('Xend exited with status %d.', code)
|
||||
sys.exit(code)
|
||||
|
||||
if os.WIFSIGNALED(status):
|
||||
sig = os.WTERMSIG(status)
|
||||
|
||||
if sig in (signal.SIGINT, signal.SIGTERM):
|
||||
log.info('Xend stopped due to signal %d.', sig)
|
||||
sys.exit(0)
|
||||
else:
|
||||
log.fatal(
|
||||
'Xend died due to signal %d! Restarting it.',
|
||||
sig)
|
||||
else:
|
||||
self.run(w and os.fdopen(w, 'w') or None)
|
||||
|
||||
return ret
|
||||
|
||||
@@ -274,25 +283,17 @@ class Daemon:
|
||||
|
||||
relocate.listenRelocation()
|
||||
servers = SrvServer.create()
|
||||
self.daemonize()
|
||||
servers.start(status)
|
||||
except Exception, ex:
|
||||
print >>sys.stderr, 'Exception starting xend:', ex
|
||||
if XEND_DEBUG:
|
||||
traceback.print_exc()
|
||||
log.exception("Exception starting xend (%s)" % ex)
|
||||
status.write('1')
|
||||
status.close()
|
||||
self.exit(1)
|
||||
if status:
|
||||
status.write('1')
|
||||
status.close()
|
||||
sys.exit(1)
|
||||
|
||||
def exit(self, rc=0):
|
||||
# Calling sys.exit() raises a SystemExit exception, which only
|
||||
# kills the current thread. Calling os._exit() makes the whole
|
||||
# Python process exit immediately. There doesn't seem to be another
|
||||
# way to exit a Python with running threads.
|
||||
#sys.exit(rc)
|
||||
os._exit(rc)
|
||||
|
||||
def instance():
|
||||
global inst
|
||||
try:
|
||||
@@ -302,10 +303,47 @@ def instance():
|
||||
return inst
|
||||
|
||||
|
||||
def read_pid(pidfile):
|
||||
"""Read process id from a file.
|
||||
|
||||
@param pidfile: file to read
|
||||
@return pid or 0
|
||||
"""
|
||||
if os.path.isfile(pidfile) and os.path.getsize(pidfile):
|
||||
try:
|
||||
f = open(pidfile, 'r')
|
||||
try:
|
||||
return int(f.read())
|
||||
finally:
|
||||
f.close()
|
||||
except:
|
||||
return 0
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def find_process(pid, name):
|
||||
"""Search for a process.
|
||||
|
||||
@param pid: process id
|
||||
@param name: process name
|
||||
@return: pid if found, 0 otherwise
|
||||
"""
|
||||
running = 0
|
||||
if pid:
|
||||
lines = os.popen('ps %d 2>/dev/null' % pid).readlines()
|
||||
exp = '^ *%d.+%s' % (pid, name)
|
||||
for line in lines:
|
||||
if re.search(exp, line):
|
||||
running = pid
|
||||
break
|
||||
return running
|
||||
|
||||
|
||||
def main(argv = None):
|
||||
global XEND_DAEMONIZE
|
||||
|
||||
XEND_DAEMONIZE = 0
|
||||
XEND_DAEMONIZE = False
|
||||
if argv is None:
|
||||
argv = sys.argv
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ class XendServers:
|
||||
# Running the network script will spawn another process, which takes
|
||||
# the status fd with it unless we set FD_CLOEXEC. Failing to do this
|
||||
# causes the read in SrvDaemon to hang even when we have written here.
|
||||
fcntl.fcntl(status, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
|
||||
if status:
|
||||
fcntl.fcntl(status, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
|
||||
|
||||
Vifctl.network('start')
|
||||
threads = []
|
||||
@@ -93,8 +94,9 @@ class XendServers:
|
||||
if threads_left:
|
||||
time.sleep(.5)
|
||||
|
||||
status.write('0')
|
||||
status.close()
|
||||
if status:
|
||||
status.write('0')
|
||||
status.close()
|
||||
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||