1#!/bin/bash -e
2#
3# tapdisk Xen block device hotplug script
4#
5# Author George Dunlap <george.dunlap@eu.citrix.com>
6#
7# Based on block-iscsi by Roger Pau Monné <roger.pau@citrix.com>
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU Lesser General Public License as published
11# by the Free Software Foundation; version 2.1 only. with the special
12# exception on linking described in file LICENSE.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU Lesser General Public License for more details.
18#
19# Usage:
20#
21# Target should be specified using the following syntax:
22#
23# script=block-tap,vdev=xvda,target=<type>:<file>
24#
25# Type is either "aio" (for raw files), or "vhd"
26
27dir=$(dirname "$0")
28. "$dir/block-common.sh"
29
30remove_label()
31{
32    echo $1 | sed "s/^\("$2"\)//"
33}
34
35check_tools()
36{
37    if ! command -v tap-ctl > /dev/null 2>&1; then
38        fatal "Unable to find tap-ctl tool"
39    fi
40    modprobe blktap
41    if ! tap-ctl check >& /dev/null ; then
42	fatal "Blocktap kernel module not available"
43    fi
44}
45
46# Sets the following global variables based on the params field passed in as
47# a parameter: type file
48parse_target()
49{
50    params=($(echo "$1" | tr ":" "\n"))
51
52    type=${params[0]}
53    file=${params[1]}
54    if [ -z "$type" ] || [ -z "$file" ]; then
55        fatal "Cannot parse required parameters"
56    fi
57}
58
59# Sets $pid and $minor to point to the device associated with the target
60find_device()
61{
62    local info
63    local param
64
65    if [ -z "$type" ] || [ -z "$file" ]; then
66        fatal "required parameters not set"
67    fi
68
69    info=$(tap-ctl list -t $type -f $file)
70
71    for param in $(echo "$info" | tr "," "\n")
72    do
73        case $param in
74        pid=*)
75            pid=$(remove_label $param "pid=")
76            ;;
77        minor=*)
78            minor=$(remove_label $param "minor=")
79            ;;
80        esac
81    done
82
83    if [ -z "$pid" ] || [ -z "$minor" ]; then
84        fatal "cannot find required parameters"
85    fi
86}
87
88# Attaches the device and writes xenstore backend entries to connect
89# the device
90add()
91{
92    dev=$(tap-ctl create -a $target)
93    write_dev $dev
94}
95
96# Disconnects the device
97remove()
98{
99    find_device
100    do_or_die tap-ctl destroy -p ${pid} -m ${minor} > /dev/null
101}
102
103command=$1
104target=$(xenstore-read $XENBUS_PATH/params || true)
105if [ -z "$target" ]; then
106    fatal "No information about the target"
107fi
108
109parse_target "$target"
110
111check_tools || exit 1
112
113case $command in
114add)
115    add
116    ;;
117remove)
118    remove
119    ;;
120*)
121    exit 1
122    ;;
123esac
124