This commit is contained in:
emellor@leeni.uk.xensource.com committed 2005-12-09 11:05:06 +00:00
commit 2fdffd69ae
7 files changed
+155 -101

No files matched your search

+36 -25
View File
@@ -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
+2 -3
View File
@@ -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
+1 -1
View File
@@ -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,/.*,,'
}
+1 -1
View File
@@ -155,7 +155,7 @@ case "$command" in
;;
offline)
[ "$dhcp" != 'no' ] && dhcp_down
ifconfig "$vif" down || true
do_without_error ifconfig "$vif" down
;;
esac
+5 -1
View File
@@ -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")
+105 -67
View File
@@ -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
+5 -3
View File
@@ -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()
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.