debuggers.hg

changeset 20012:9ced12c28e05

tools: xenbackendd for NetBSD

Attached patch introduces xenbackendd. It is used on NetBSD
to launch the hotplug scripts. Later xenbackendd can be improved to
also launch qemu-dm as child process and will notice when qemu-dm
crashes.

The changes the patch makes:
- rename hotplug scripts as xenbackendd expects them
(current names were taken from pkgsrc)
- install hotplug scripts as executable scripts
- introduce xenbackendd
- build/install/launch on NetBSD only

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 22 14:37:30 2009 +0100 (2009-07-22)
parents 5adc108c0085
children fcd0878dfa3e
files tools/Makefile tools/hotplug/NetBSD/Makefile tools/hotplug/NetBSD/block tools/hotplug/NetBSD/block-nbsd tools/hotplug/NetBSD/vif-bridge tools/hotplug/NetBSD/vif-bridge-nbsd tools/hotplug/NetBSD/vif-ip tools/hotplug/NetBSD/vif-ip-nbsd tools/misc/xend tools/xenbackendd/Makefile tools/xenbackendd/xenbackendd.c
line diff
     1.1 --- a/tools/Makefile	Wed Jul 22 14:06:21 2009 +0100
     1.2 +++ b/tools/Makefile	Wed Jul 22 14:37:30 2009 +0100
     1.3 @@ -25,6 +25,7 @@ SUBDIRS-$(CONFIG_Linux) += blktap
     1.4  SUBDIRS-$(CONFIG_Linux) += blktap2
     1.5  SUBDIRS-$(CONFIG_NetBSD) += libaio
     1.6  SUBDIRS-$(CONFIG_NetBSD) += blktap2
     1.7 +SUBDIRS-$(CONFIG_NetBSD) += xenbackendd
     1.8  SUBDIRS-y += libfsimage
     1.9  SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
    1.10  SUBDIRS-$(CONFIG_Linux) += fs-back
     2.1 --- a/tools/hotplug/NetBSD/Makefile	Wed Jul 22 14:06:21 2009 +0100
     2.2 +++ b/tools/hotplug/NetBSD/Makefile	Wed Jul 22 14:37:30 2009 +0100
     2.3 @@ -3,9 +3,9 @@ include $(XEN_ROOT)/tools/Rules.mk
     2.4  
     2.5  # Xen script dir and scripts to go there.
     2.6  XEN_SCRIPTS =
     2.7 -XEN_SCRIPTS += block-nbsd
     2.8 -XEN_SCRIPTS += vif-bridge-nbsd
     2.9 -XEN_SCRIPTS += vif-ip-nbsd
    2.10 +XEN_SCRIPTS += block
    2.11 +XEN_SCRIPTS += vif-bridge
    2.12 +XEN_SCRIPTS += vif-ip
    2.13  
    2.14  XEN_SCRIPT_DATA =
    2.15  
    2.16 @@ -23,7 +23,7 @@ install-scripts:
    2.17  	$(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
    2.18  	set -e; for i in $(XEN_SCRIPTS); \
    2.19  	   do \
    2.20 -	   $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
    2.21 +	   $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
    2.22  	done
    2.23  	set -e; for i in $(XEN_SCRIPT_DATA); \
    2.24  	   do \
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/hotplug/NetBSD/block	Wed Jul 22 14:37:30 2009 +0100
     3.3 @@ -0,0 +1,91 @@
     3.4 +#!/bin/sh -e
     3.5 +
     3.6 +# $NetBSD: block-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
     3.7 +# Called by xenbackendd
     3.8 +# Usage: block xsdir_backend_path state
     3.9 +
    3.10 +DIR=$(dirname "$0")
    3.11 +. "${DIR}/hotplugpath.sh"
    3.12 +
    3.13 +PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
    3.14 +export PATH
    3.15 +
    3.16 +error() {
    3.17 +	echo "$@" >&2
    3.18 +	xenstore_write $xpath/hotplug-status error
    3.19 +	exit 1
    3.20 +}
    3.21 +	
    3.22 +
    3.23 +xpath=$1
    3.24 +xstatus=$2
    3.25 +xtype=$(xenstore-read "$xpath/type")
    3.26 +xparams=$(xenstore-read "$xpath/params")
    3.27 +
    3.28 +case $xstatus in
    3.29 +6)
    3.30 +	# device removed
    3.31 +	case $xtype in
    3.32 +	file)
    3.33 +		vnd=$(xenstore-read "$xpath/vnd" || echo none)
    3.34 +		if [ $vnd != none ]; then
    3.35 +			vnconfig -u $vnd
    3.36 +		fi
    3.37 +		;;
    3.38 +	phy)
    3.39 +		;;
    3.40 +	*)
    3.41 +		echo "unknown type $xtype" >&2
    3.42 +		;;
    3.43 +	esac
    3.44 +	xenstore-rm $xpath
    3.45 +	exit 0
    3.46 +	;;
    3.47 +2)
    3.48 +	case $xtype in
    3.49 +	file)
    3.50 +		# Store the list of available vnd(4) devices in
    3.51 +		#``available_disks'', and mark them as ``free''.
    3.52 +		list=`ls -1 /dev/vnd[0-9]*d | sed "s,/dev/vnd,,;s,d,," | sort -n`
    3.53 +		for i in $list; do
    3.54 +			disk="vnd$i"
    3.55 +			available_disks="$available_disks $disk"
    3.56 +			eval $disk=free
    3.57 +		done
    3.58 +		# Mark the used vnd(4) devices as ``used''.
    3.59 +		for disk in `sysctl hw.disknames`; do
    3.60 +			case $disk in
    3.61 +			vnd[0-9]*) eval $disk=used ;;
    3.62 +			esac
    3.63 +		done
    3.64 +		# Configure the first free vnd(4) device.
    3.65 +		for disk in $available_disks; do
    3.66 +			eval status=\$$disk
    3.67 +			if [ "$status" = "free" ] && \
    3.68 +			    vnconfig /dev/${disk}d $xparams >/dev/null; then
    3.69 +				device=/dev/${disk}d
    3.70 +				echo vnconfig /dev/${disk}d $xparams
    3.71 +				break	
    3.72 +			fi
    3.73 +		done
    3.74 +		if [ x$device = x ] ; then
    3.75 +			error "no available vnd device"
    3.76 +		fi
    3.77 +		echo xenstore-write $xpath/vnd $device
    3.78 +		xenstore-write $xpath/vnd $device
    3.79 +		;;
    3.80 +	phy)
    3.81 +		device=$xparams
    3.82 +		;;
    3.83 +	esac
    3.84 +	physical_device=$(stat -f '%r' "$device")
    3.85 +	echo xenstore-write $xpath/physical-device $physical_device
    3.86 +	xenstore-write $xpath/physical-device $physical_device
    3.87 +	echo xenstore-write $xpath/hotplug-status connected
    3.88 +	xenstore-write $xpath/hotplug-status connected
    3.89 +	exit 0
    3.90 +	;;
    3.91 +*)
    3.92 +	exit 0
    3.93 +	;;
    3.94 +esac
     4.1 --- a/tools/hotplug/NetBSD/block-nbsd	Wed Jul 22 14:06:21 2009 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,91 +0,0 @@
     4.4 -#!/bin/sh -e
     4.5 -
     4.6 -# $NetBSD: block-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
     4.7 -# Called by xenbackendd
     4.8 -# Usage: block xsdir_backend_path state
     4.9 -
    4.10 -DIR=$(dirname "$0")
    4.11 -. "${DIR}/hotplugpath.sh"
    4.12 -
    4.13 -PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
    4.14 -export PATH
    4.15 -
    4.16 -error() {
    4.17 -	echo "$@" >&2
    4.18 -	xenstore_write $xpath/hotplug-status error
    4.19 -	exit 1
    4.20 -}
    4.21 -	
    4.22 -
    4.23 -xpath=$1
    4.24 -xstatus=$2
    4.25 -xtype=$(xenstore-read "$xpath/type")
    4.26 -xparams=$(xenstore-read "$xpath/params")
    4.27 -
    4.28 -case $xstatus in
    4.29 -6)
    4.30 -	# device removed
    4.31 -	case $xtype in
    4.32 -	file)
    4.33 -		vnd=$(xenstore-read "$xpath/vnd" || echo none)
    4.34 -		if [ $vnd != none ]; then
    4.35 -			vnconfig -u $vnd
    4.36 -		fi
    4.37 -		;;
    4.38 -	phy)
    4.39 -		;;
    4.40 -	*)
    4.41 -		echo "unknown type $xtype" >&2
    4.42 -		;;
    4.43 -	esac
    4.44 -	xenstore-rm $xpath
    4.45 -	exit 0
    4.46 -	;;
    4.47 -2)
    4.48 -	case $xtype in
    4.49 -	file)
    4.50 -		# Store the list of available vnd(4) devices in
    4.51 -		#``available_disks'', and mark them as ``free''.
    4.52 -		list=`ls -1 /dev/vnd[0-9]*d | sed "s,/dev/vnd,,;s,d,," | sort -n`
    4.53 -		for i in $list; do
    4.54 -			disk="vnd$i"
    4.55 -			available_disks="$available_disks $disk"
    4.56 -			eval $disk=free
    4.57 -		done
    4.58 -		# Mark the used vnd(4) devices as ``used''.
    4.59 -		for disk in `sysctl hw.disknames`; do
    4.60 -			case $disk in
    4.61 -			vnd[0-9]*) eval $disk=used ;;
    4.62 -			esac
    4.63 -		done
    4.64 -		# Configure the first free vnd(4) device.
    4.65 -		for disk in $available_disks; do
    4.66 -			eval status=\$$disk
    4.67 -			if [ "$status" = "free" ] && \
    4.68 -			    vnconfig /dev/${disk}d $xparams >/dev/null; then
    4.69 -				device=/dev/${disk}d
    4.70 -				echo vnconfig /dev/${disk}d $xparams
    4.71 -				break	
    4.72 -			fi
    4.73 -		done
    4.74 -		if [ x$device = x ] ; then
    4.75 -			error "no available vnd device"
    4.76 -		fi
    4.77 -		echo xenstore-write $xpath/vnd $device
    4.78 -		xenstore-write $xpath/vnd $device
    4.79 -		;;
    4.80 -	phy)
    4.81 -		device=$xparams
    4.82 -		;;
    4.83 -	esac
    4.84 -	physical_device=$(stat -f '%r' "$device")
    4.85 -	echo xenstore-write $xpath/physical-device $physical_device
    4.86 -	xenstore-write $xpath/physical-device $physical_device
    4.87 -	echo xenstore-write $xpath/hotplug-status connected
    4.88 -	xenstore-write $xpath/hotplug-status connected
    4.89 -	exit 0
    4.90 -	;;
    4.91 -*)
    4.92 -	exit 0
    4.93 -	;;
    4.94 -esac
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/hotplug/NetBSD/vif-bridge	Wed Jul 22 14:37:30 2009 +0100
     5.3 @@ -0,0 +1,38 @@
     5.4 +#!/bin/sh -e
     5.5 +
     5.6 +# $NetBSD: vif-bridge-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
     5.7 +# Called by xenbackendd
     5.8 +# Usage: vif-bridge xsdir_backend_path state
     5.9 +
    5.10 +DIR=$(dirname "$0")
    5.11 +. "${DIR}/hotplugpath.sh"
    5.12 +
    5.13 +PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
    5.14 +export PATH
    5.15 +
    5.16 +xpath=$1
    5.17 +xstatus=$2
    5.18 +
    5.19 +case $xstatus in
    5.20 +6)
    5.21 +	# device removed
    5.22 +	xenstore-rm $xpath
    5.23 +	exit 0
    5.24 +	;;
    5.25 +2)
    5.26 +	xbridge=$(xenstore-read "$xpath/bridge")
    5.27 +	xfid=$(xenstore-read "$xpath/frontend-id")
    5.28 +	xhandle=$(xenstore-read "$xpath/handle")
    5.29 +	iface=xvif$xfid.$xhandle
    5.30 +	echo ifconfig $iface up
    5.31 +	ifconfig $iface up
    5.32 +	brconfig $xbridge add $iface
    5.33 +	echo brconfig $xbridge add $iface
    5.34 +	xenstore-write $xpath/hotplug-status connected
    5.35 +	echo xenstore-write $xpath/hotplug-status connected
    5.36 +	exit 0
    5.37 +	;;
    5.38 +*)
    5.39 +	exit 0
    5.40 +	;;
    5.41 +esac
     6.1 --- a/tools/hotplug/NetBSD/vif-bridge-nbsd	Wed Jul 22 14:06:21 2009 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,38 +0,0 @@
     6.4 -#!/bin/sh -e
     6.5 -
     6.6 -# $NetBSD: vif-bridge-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
     6.7 -# Called by xenbackendd
     6.8 -# Usage: vif-bridge xsdir_backend_path state
     6.9 -
    6.10 -DIR=$(dirname "$0")
    6.11 -. "${DIR}/hotplugpath.sh"
    6.12 -
    6.13 -PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
    6.14 -export PATH
    6.15 -
    6.16 -xpath=$1
    6.17 -xstatus=$2
    6.18 -
    6.19 -case $xstatus in
    6.20 -6)
    6.21 -	# device removed
    6.22 -	xenstore-rm $xpath
    6.23 -	exit 0
    6.24 -	;;
    6.25 -2)
    6.26 -	xbridge=$(xenstore-read "$xpath/bridge")
    6.27 -	xfid=$(xenstore-read "$xpath/frontend-id")
    6.28 -	xhandle=$(xenstore-read "$xpath/handle")
    6.29 -	iface=xvif$xfid.$xhandle
    6.30 -	echo ifconfig $iface up
    6.31 -	ifconfig $iface up
    6.32 -	brconfig $xbridge add $iface
    6.33 -	echo brconfig $xbridge add $iface
    6.34 -	xenstore-write $xpath/hotplug-status connected
    6.35 -	echo xenstore-write $xpath/hotplug-status connected
    6.36 -	exit 0
    6.37 -	;;
    6.38 -*)
    6.39 -	exit 0
    6.40 -	;;
    6.41 -esac
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/hotplug/NetBSD/vif-ip	Wed Jul 22 14:37:30 2009 +0100
     7.3 @@ -0,0 +1,36 @@
     7.4 +#!/bin/sh -e
     7.5 +
     7.6 +# $NetBSD: vif-ip-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
     7.7 +# Called by xenbackendd
     7.8 +# Usage: vif-ip xsdir_backend_path state
     7.9 +
    7.10 +DIR=$(dirname "$0")
    7.11 +. "${DIR}/hotplugpath.sh"
    7.12 +
    7.13 +PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
    7.14 +export PATH
    7.15 +
    7.16 +xpath=$1
    7.17 +xstatus=$2
    7.18 +
    7.19 +case $xstatus in
    7.20 +6)
    7.21 +	# device removed
    7.22 +	xenstore-rm $xpath
    7.23 +	exit 0
    7.24 +	;;
    7.25 +2)
    7.26 +	xip=$(xenstore-read "$xpath/ip")
    7.27 +	xfid=$(xenstore-read "$xpath/frontend-id")
    7.28 +	xhandle=$(xenstore-read "$xpath/handle")
    7.29 +	iface=xvif$xfid.$xhandle
    7.30 +	echo ifconfig $iface $xip up
    7.31 +	ifconfig $iface $xip up
    7.32 +	xenstore-write $xpath/hotplug-status connected
    7.33 +	echo xenstore-write $xpath/hotplug-status connected
    7.34 +	exit 0
    7.35 +	;;
    7.36 +*)
    7.37 +	exit 0
    7.38 +	;;
    7.39 +esac
     8.1 --- a/tools/hotplug/NetBSD/vif-ip-nbsd	Wed Jul 22 14:06:21 2009 +0100
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,36 +0,0 @@
     8.4 -#!/bin/sh -e
     8.5 -
     8.6 -# $NetBSD: vif-ip-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
     8.7 -# Called by xenbackendd
     8.8 -# Usage: vif-ip xsdir_backend_path state
     8.9 -
    8.10 -DIR=$(dirname "$0")
    8.11 -. "${DIR}/hotplugpath.sh"
    8.12 -
    8.13 -PATH=${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/bin:/usr/bin:/sbin:/usr/sbin
    8.14 -export PATH
    8.15 -
    8.16 -xpath=$1
    8.17 -xstatus=$2
    8.18 -
    8.19 -case $xstatus in
    8.20 -6)
    8.21 -	# device removed
    8.22 -	xenstore-rm $xpath
    8.23 -	exit 0
    8.24 -	;;
    8.25 -2)
    8.26 -	xip=$(xenstore-read "$xpath/ip")
    8.27 -	xfid=$(xenstore-read "$xpath/frontend-id")
    8.28 -	xhandle=$(xenstore-read "$xpath/handle")
    8.29 -	iface=xvif$xfid.$xhandle
    8.30 -	echo ifconfig $iface $xip up
    8.31 -	ifconfig $iface $xip up
    8.32 -	xenstore-write $xpath/hotplug-status connected
    8.33 -	echo xenstore-write $xpath/hotplug-status connected
    8.34 -	exit 0
    8.35 -	;;
    8.36 -*)
    8.37 -	exit 0
    8.38 -	;;
    8.39 -esac
     9.1 --- a/tools/misc/xend	Wed Jul 22 14:06:21 2009 +0100
     9.2 +++ b/tools/misc/xend	Wed Jul 22 14:37:30 2009 +0100
     9.3 @@ -107,6 +107,14 @@ def start_consoled():
     9.4  def start_blktapctrl():
     9.5      start_daemon("blktapctrl", "")
     9.6  
     9.7 +def start_xenbackendd():
     9.8 +    XENBACKENDD_DEBUG = os.getenv("XENBACKENDD_DEBUG")
     9.9 +    args = ""
    9.10 +    if XENBACKENDD_DEBUG:
    9.11 +        args += "-d"
    9.12 +    if os.uname()[0] == 'NetBSD':
    9.13 +        start_daemon("xenbackendd", args)
    9.14 +
    9.15  def main():
    9.16      try:
    9.17          check_logging()
    9.18 @@ -121,11 +129,13 @@ def main():
    9.19          if os.uname()[0] != "SunOS":
    9.20              start_xenstored()
    9.21              start_consoled()
    9.22 +            start_xenbackendd()
    9.23              start_blktapctrl()
    9.24          return daemon.start()
    9.25      elif sys.argv[1] == 'trace_start':
    9.26          start_xenstored()
    9.27          start_consoled()
    9.28 +        start_xenbackendd()
    9.29          start_blktapctrl()
    9.30          return daemon.start(trace=1)
    9.31      elif sys.argv[1] == 'stop':
    9.32 @@ -135,6 +145,7 @@ def main():
    9.33      elif sys.argv[1] == 'restart':
    9.34          start_xenstored()
    9.35          start_consoled()
    9.36 +        start_xenbackendd()
    9.37          start_blktapctrl()
    9.38          return daemon.stop() or daemon.start()
    9.39      elif sys.argv[1] == 'status':
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/xenbackendd/Makefile	Wed Jul 22 14:37:30 2009 +0100
    10.3 @@ -0,0 +1,41 @@
    10.4 +# Copyright (c) 2009 Advanced Micro Devices, Inc.
    10.5 +#
    10.6 +# This program is free software; you can redistribute it and/or modify
    10.7 +# it under the terms of the GNU General Public License as published by
    10.8 +# the Free Software Foundation; under version 2 of the License.
    10.9 +#
   10.10 +# This program is distributed in the hope that it will be useful,
   10.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.13 +# GNU General Public License for more details.
   10.14 +
   10.15 +XEN_ROOT=../..
   10.16 +include $(XEN_ROOT)/tools/Rules.mk
   10.17 +
   10.18 +CFLAGS  += -Werror
   10.19 +CFLAGS  += $(CFLAGS_libxenstore)
   10.20 +CPPFLAGS += -DXEN_SCRIPT_DIR="\"$(XEN_SCRIPT_DIR)\""
   10.21 +LDFLAGS += $(LDFLAGS_libxenstore)
   10.22 +
   10.23 +SBIN = xenbackendd
   10.24 +
   10.25 +.PHONY: all
   10.26 +all: build
   10.27 +
   10.28 +.PHONY: build
   10.29 +build: $(SBIN)
   10.30 +
   10.31 +.PHONY: install
   10.32 +install: build
   10.33 +	$(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
   10.34 +	$(INSTALL_PROG) xenbackendd $(DESTDIR)$(SBINDIR)
   10.35 +
   10.36 +.PHONY: clean
   10.37 +clean:
   10.38 +	rm -f $(SBIN) $(DEPS)
   10.39 +
   10.40 +
   10.41 +%: %.c Makefile
   10.42 +	$(CC) $(CFLAGS) $(CPPFLAGS) $< $(LDFLAGS) -o $@
   10.43 +
   10.44 +-include $(DEPS)
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/xenbackendd/xenbackendd.c	Wed Jul 22 14:37:30 2009 +0100
    11.3 @@ -0,0 +1,319 @@
    11.4 +/* $NetBSD: xenbackendd.c,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $ */
    11.5 +/*
    11.6 + * Copyright (C) 2006 Manuel Bouyer <bouyer@netbsd.org>
    11.7 + * Copyright (C) 2009 Christoph Egger <Christoph.Egger@amd.com>
    11.8 + *
    11.9 + *  This program is free software; you can redistribute it and/or modify
   11.10 + *  it under the terms of the GNU General Public License as published by
   11.11 + *  the Free Software Foundation; under version 2 of the License.
   11.12 + * 
   11.13 + *  This program is distributed in the hope that it will be useful,
   11.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 + *  GNU General Public License for more details.
   11.17 + * 
   11.18 + *  You should have received a copy of the GNU General Public License
   11.19 + *  along with this program; if not, write to the Free Software
   11.20 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   11.21 + */
   11.22 +
   11.23 +#include <sys/types.h>
   11.24 +#include <sys/stat.h>
   11.25 +#include <sys/wait.h>
   11.26 +#include <unistd.h>
   11.27 +#include <fcntl.h>
   11.28 +#include <stdlib.h>
   11.29 +#include <stdio.h>
   11.30 +#include <stdarg.h>
   11.31 +#include <string.h>
   11.32 +#include <syslog.h>
   11.33 +
   11.34 +#include <xs.h>
   11.35 +
   11.36 +#define DEVTYPE_UNKNOWN 0
   11.37 +#define DEVTYPE_VIF 1
   11.38 +#define DEVTYPE_VBD 2
   11.39 +
   11.40 +#define DOMAIN_PATH "/local/domain/0"
   11.41 +
   11.42 +#ifndef XEN_SCRIPT_DIR
   11.43 +#error XEN_SCRIPT_DIR not defined
   11.44 +#endif
   11.45 +
   11.46 +#ifndef VBD_SCRIPT
   11.47 +#define VBD_SCRIPT XEN_SCRIPT_DIR"/block"
   11.48 +#endif
   11.49 +#ifndef LOG_FILE
   11.50 +#define LOG_FILE "/var/log/xen/xenbackendd.log"
   11.51 +#endif
   11.52 +#ifndef PID_FILE
   11.53 +#define PID_FILE "/var/run/xenbackendd.pid"
   11.54 +#endif
   11.55 +
   11.56 +
   11.57 +struct xs_handle *xs;
   11.58 +
   11.59 +int fflag = 0;
   11.60 +int dflag = 0;
   11.61 +
   11.62 +const char *vbd_script = NULL;
   11.63 +const char *log_file = NULL;
   11.64 +const char *pidfile = NULL;
   11.65 +
   11.66 +static void
   11.67 +dolog(int pri, const char *fmt, ...)
   11.68 +{
   11.69 +	va_list ap;
   11.70 +	va_start(ap, fmt);
   11.71 +	vfprintf(stderr, fmt, ap);
   11.72 +	va_end(ap);
   11.73 +	fprintf(stderr, "\n");
   11.74 +	fflush(stderr);
   11.75 +	va_start(ap, fmt);
   11.76 +	vsyslog(pri, fmt, ap);
   11.77 +	va_end(ap);
   11.78 +}
   11.79 +
   11.80 +static void
   11.81 +dodebug(const char *fmt, ...)
   11.82 +{
   11.83 +	va_list ap;
   11.84 +
   11.85 +	if (dflag == 0)
   11.86 +		return;
   11.87 +	va_start(ap, fmt);
   11.88 +	vfprintf(stdout, fmt, ap);
   11.89 +	va_end(ap);
   11.90 +	printf("\n");
   11.91 +	fflush(stdout);
   11.92 +}
   11.93 +
   11.94 +static void
   11.95 +doexec(const char *cmd, const char *arg1, const char *arg2)
   11.96 +{
   11.97 +	dodebug("exec %s %s %s", cmd, arg1, arg2);
   11.98 +	switch(vfork()) {
   11.99 +	case -1:
  11.100 +		dolog(LOG_ERR, "can't vfork: %s", strerror(errno));
  11.101 +		break;
  11.102 +	case 0:
  11.103 +		execl(cmd, cmd, arg1, arg2, NULL);
  11.104 +		dolog(LOG_ERR, "can't exec %s: %s", cmd, strerror(errno));
  11.105 +		exit(EXIT_FAILURE);
  11.106 +		/* NOTREACHED */
  11.107 +		break;
  11.108 +	default:
  11.109 +		wait(NULL);
  11.110 +		break;
  11.111 +	}
  11.112 +}
  11.113 +
  11.114 +static void
  11.115 +usage(void)
  11.116 +{
  11.117 +	fprintf(stderr,
  11.118 +	    "usage: %s [-d] [-f] [-l log_file] [-p pif_file] [-s vbd_script]\n",
  11.119 +	    getprogname());
  11.120 +	exit(EXIT_FAILURE);
  11.121 +}
  11.122 +
  11.123 +static int
  11.124 +xen_setup(void)
  11.125 +{
  11.126 +	xs = xs_daemon_open();
  11.127 +	if (xs == NULL) {
  11.128 +		dolog(LOG_ERR,
  11.129 +		    "Failed to contact xenstore (%s).  Is it running?",
  11.130 +		    strerror(errno));
  11.131 +		goto out;
  11.132 +	}
  11.133 +
  11.134 +	if (!xs_watch(xs, DOMAIN_PATH, "backend")) {
  11.135 +		dolog(LOG_ERR, "xenstore watch on backend fails.");
  11.136 +		goto out;
  11.137 +	}
  11.138 +	return 0;
  11.139 +
  11.140 + out:
  11.141 +	if (xs) {
  11.142 +		xs_daemon_close(xs);
  11.143 +		xs = NULL;
  11.144 +	}
  11.145 +	return -1;
  11.146 +}
  11.147 +
  11.148 +int
  11.149 +main(int argc, char * const argv[])
  11.150 +{
  11.151 +	char **vec;
  11.152 +	unsigned int num;
  11.153 +	char *s;
  11.154 +	int state;
  11.155 +	char *sstate;
  11.156 +	char *p;
  11.157 +	char buf[80];
  11.158 +	int type = DEVTYPE_UNKNOWN;
  11.159 +	int ch;
  11.160 +	int debug_fd;
  11.161 +	FILE *pidfile_f;
  11.162 +
  11.163 +	while ((ch = getopt(argc, argv, "dfl:p:s:")) != -1) {
  11.164 +		switch (ch) {
  11.165 +		case 'd':
  11.166 +			dflag = 1;
  11.167 +			break;
  11.168 +		case 'f':
  11.169 +			fflag = 1;
  11.170 +			break;
  11.171 +		case 'l':
  11.172 +			log_file = optarg;
  11.173 +			break;
  11.174 +		case 'p':
  11.175 +			pidfile = pidfile;
  11.176 +		case 's':
  11.177 +			vbd_script = optarg;
  11.178 +			break;
  11.179 +		default:
  11.180 +			usage();
  11.181 +		}
  11.182 +	}
  11.183 +
  11.184 +	if (vbd_script == NULL)
  11.185 +		vbd_script = VBD_SCRIPT;
  11.186 +	if (pidfile == NULL)
  11.187 +		pidfile = PID_FILE;
  11.188 +	if (log_file == NULL)
  11.189 +		log_file = LOG_FILE;
  11.190 +
  11.191 +	openlog("xenbackendd", LOG_PID | LOG_NDELAY, LOG_DAEMON);
  11.192 +
  11.193 +	if (fflag == 0) {
  11.194 +		/* open log file */
  11.195 +		debug_fd = open(log_file, O_RDWR | O_CREAT | O_TRUNC, 0644);
  11.196 +		if (debug_fd == -1) {
  11.197 +			dolog(LOG_ERR, "can't open %s: %s",
  11.198 +			    log_file, strerror(errno));
  11.199 +			exit(EXIT_FAILURE);
  11.200 +		}
  11.201 +	}
  11.202 +
  11.203 +	if (fflag == 0) {
  11.204 +		/* daemonize */
  11.205 +		pidfile_f = fopen(pidfile, "w");
  11.206 +		if (pidfile_f == NULL) {
  11.207 +			dolog(LOG_ERR, "can't open %s: %s",
  11.208 +			    pidfile, strerror(errno));
  11.209 +			exit(EXIT_FAILURE);
  11.210 +		}
  11.211 +		if (daemon(0, 0) < 0) {
  11.212 +			dolog(LOG_ERR, "can't daemonize: %s",
  11.213 +			    strerror(errno));
  11.214 +			exit(EXIT_FAILURE);
  11.215 +		}
  11.216 +		fprintf(pidfile_f, "%d\n", (int)getpid());
  11.217 +		fclose(pidfile_f);
  11.218 +
  11.219 +		/* redirect stderr to log file */
  11.220 +		if (dup2(debug_fd, STDERR_FILENO) < 0) {
  11.221 +			dolog(LOG_ERR, "can't redirect stderr to %s: %s\n",
  11.222 +			    log_file, strerror(errno));
  11.223 +			exit(EXIT_FAILURE);
  11.224 +		}
  11.225 +
  11.226 +		/* also redirect stdout if we're in debug mode */
  11.227 +		if (dflag) {
  11.228 +			if (dup2(debug_fd, STDOUT_FILENO) < 0) {
  11.229 +				dolog(LOG_ERR,
  11.230 +				    "can't redirect stdout to %s: %s\n",
  11.231 +				    log_file, strerror(errno));
  11.232 +				exit(EXIT_FAILURE);
  11.233 +			}
  11.234 +		}
  11.235 +
  11.236 +		close(debug_fd);
  11.237 +		debug_fd = -1;
  11.238 +	}
  11.239 +
  11.240 +	if (xen_setup() < 0)
  11.241 +		exit(EXIT_FAILURE);
  11.242 +
  11.243 +	for (;;) {
  11.244 +		vec = xs_read_watch(xs, &num);
  11.245 +		if (!vec) {
  11.246 +			dolog(LOG_ERR, "xs_read_watch: NULL\n");
  11.247 +			continue;
  11.248 +		}
  11.249 +
  11.250 +		if (strlen(vec[XS_WATCH_PATH]) < sizeof("state"))
  11.251 +			goto next1;
  11.252 +
  11.253 +		/* find last component of path, check if it's "state" */
  11.254 +		p = &vec[XS_WATCH_PATH][
  11.255 +		    strlen(vec[XS_WATCH_PATH]) - sizeof("state")];
  11.256 +		if (p[0] != '/')
  11.257 +			goto next1;
  11.258 +		p[0] = '\0';
  11.259 +		p++;
  11.260 +		if (strcmp(p, "state") != 0)
  11.261 +			goto next1;
  11.262 +
  11.263 +		snprintf(buf, sizeof(buf), "%s/state", vec[XS_WATCH_PATH]);
  11.264 +		sstate = xs_read(xs, XBT_NULL, buf, 0);
  11.265 +		if (sstate == NULL) {
  11.266 +			dolog(LOG_ERR,
  11.267 +			    "Failed to read %s (%s)", buf, strerror(errno));
  11.268 +			goto next1;
  11.269 +		}
  11.270 +
  11.271 +		state = atoi(sstate);
  11.272 +		snprintf(buf, sizeof(buf), "%s/hotplug-status",
  11.273 +		    vec[XS_WATCH_PATH]);
  11.274 +		s = xs_read(xs, XBT_NULL, buf, 0);
  11.275 +		if (s != NULL && state != 6 /* XenbusStateClosed */)
  11.276 +			goto next2;
  11.277 +
  11.278 +		if (strncmp(vec[XS_WATCH_PATH],
  11.279 +		    DOMAIN_PATH "/backend/vif",
  11.280 +		    strlen(DOMAIN_PATH "/backend/vif")) == 0)
  11.281 +			type = DEVTYPE_VIF;
  11.282 +
  11.283 +		if (strncmp(vec[XS_WATCH_PATH],
  11.284 +		    DOMAIN_PATH "/backend/vbd",
  11.285 +		    strlen(DOMAIN_PATH "/backend/vbd")) == 0)
  11.286 +			type = DEVTYPE_VBD;
  11.287 +
  11.288 +		switch(type) {
  11.289 +		case DEVTYPE_VIF:
  11.290 +			if (s)
  11.291 +				free(s);
  11.292 +			snprintf(buf, sizeof(buf), "%s/script",
  11.293 +			    vec[XS_WATCH_PATH]);
  11.294 +			s = xs_read(xs, XBT_NULL, buf, 0);
  11.295 +			if (s == NULL) {
  11.296 +				dolog(LOG_ERR,
  11.297 +				    "Failed to read %s (%s)", buf,
  11.298 +				    strerror(errno));
  11.299 +				goto next2;
  11.300 +			}
  11.301 +			doexec(s, vec[XS_WATCH_PATH], sstate);
  11.302 +			break;
  11.303 +
  11.304 +		case DEVTYPE_VBD:
  11.305 +			doexec(vbd_script, vec[XS_WATCH_PATH], sstate);
  11.306 +			break;
  11.307 +
  11.308 +		default:
  11.309 +			break;
  11.310 +		}
  11.311 +
  11.312 +next2:
  11.313 +		if (s)
  11.314 +			free(s);
  11.315 +		free(sstate);
  11.316 +
  11.317 +next1:
  11.318 +		free(vec);
  11.319 +	}
  11.320 +
  11.321 +	return 0;
  11.322 +}