~raharper/curtin/trunk.fix-bcache-sysfs-write-failures-on-remove

« back to all changes in this revision

Viewing changes to tools/find-tgt

  • Committer: Scott Moser
  • Date: 2017-08-03 16:46:08 UTC
  • mfrom: (508.2.20 trunk.tgt-cleanup)
  • Revision ID: smoser@ubuntu.com-20170803164608-4de4u4wlrm34ggbc
tools/jenkins-runner: improve tgtd cleanup logic

The previous tgtd cleanup logic was hard to follow at best. It was buggy
in that it would always kill the TGT_PID process even if it didn't start it.
both cleanup lines ended with:
  <condition> || [ -n "${TGT_PID}" ] && kill -9 ${TGT_PID}
which will always run the 'kill' if TGT_PID is non-empty.

Also:
 * clean up the output of tools/jenkins-runner by redirecting
   the find-tgt.d to a file so you don't see its debug messages.
 * use modulus to get a port in the right range.
 * improve the picking of a port and then checking to see if it was used.
   I believe a race condition where tgt wasn't listening on the port when
   netstat would run lead to false positives for failures where a
   sleep would have sufficed.
 * remove the tgt socket file(s) if it was created.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
    _RET=$addr
40
40
}
41
41
 
 
42
wait_for_tgtd() {
 
43
    local pid="$1" portal="$2"
 
44
    local tries=10 naplen=1 try=1
 
45
    local out="" pidstgt="" name="tgtd"
 
46
    while :; do
 
47
        # did we succesfully attach to the correct port?
 
48
        out=$(netstat --program --all --numeric 2>/dev/null) ||
 
49
            fail "failed to netstat --program --all --numeric"
 
50
        pidstgt=$(echo "$out" |
 
51
            awk '$4 == portal { print $7; exit(0); }' "portal=$portal")
 
52
        if [ "$pidstgt" = "$pid/$name" ]; then
 
53
            error "expected pid $pid is listening on $portal on try $try."
 
54
            return 0
 
55
        elif [ -n "$pidstgt" ]; then
 
56
            # something else listening.
 
57
            error "pid/process '$pidstgt' was listening on $portal." \
 
58
                "expected '$pid/$name'."
 
59
            return 1
 
60
        else
 
61
            # nothing listening. retry.
 
62
            :
 
63
        fi
 
64
        [ $try -le $tries ] || break
 
65
        try=$(($try+1))
 
66
        sleep $naplen
 
67
    done
 
68
    error "nothing listening on $portal after $tries tries"
 
69
    return 2
 
70
}
 
71
 
42
72
if [ "$1" = "--help" -o "$1" = "-h" ]; then
43
73
    Usage;
44
74
    exit 0;
77
107
# Racily try for a port. Annoyingly, tgtd doesn't fail when it's
78
108
# unable to use the requested portal, it just happily uses the default
79
109
tries=1
 
110
tried_ports=""
80
111
while [ $tries -le 100 ]; do
81
112
    # pick a port > 1024, and I think tgt needs one < 2^15 (32768)
82
 
    port=$((RANDOM+1024))
83
 
    [ "$port" -lt 32768 ] || continue
 
113
    port=$((($RANDOM%(32767-1024))+1024+1))
84
114
 
85
115
    portal="$ipv4addr:$port"
 
116
    tried_ports="${tried_ports:+${tried_ports} }${port}"
86
117
    error "going for $portal"
87
118
    TGT_IPC_SOCKET="$socket" \
88
119
        tgtd --foreground --iscsi "portal=$portal" >"$log" 2>&1 &
89
120
    TGT_PID=$!
90
121
    pid=$TGT_PID
91
122
 
92
 
    # did we succesfully attach to the correct port?
93
 
    out=$(netstat --program --all --numeric 2>/dev/null) ||
94
 
        fail "failed to netstat --program --all --numeric"
95
 
    pidstgt=$(echo "$out" |
96
 
        awk '$4 == portal { print $7; exit(0); }' "portal=$portal")
97
 
 
98
 
    if [ -n "$pidstgt" ]; then
99
 
        if [ "$pidstgt" != "$pid/tgtd" ]; then
100
 
            error "'$pidstgt' was listening on $portal, not $pid"
101
 
        else
102
 
            error "grabbed $port in $pid on try $tries"
103
 
            {
104
 
            echo "export TGT_PID=$pid"
105
 
            echo "export TGT_IPC_SOCKET=$socket"
106
 
            echo "export CURTIN_VMTEST_ISCSI_PORTAL=$portal"
107
 
            } > "$info"
108
 
            echo "$pid" > "$pidfile"
109
 
            error "To list targets on this tgt: "
110
 
            error "  TGT_IPC_SOCKET=$socket tgtadm --lld=iscsi --mode=target --op=show"
111
 
            error "For a client view of visible disks:"
112
 
            error "  iscsiadm --mode=discovery --type=sendtargets --portal=$portal"
113
 
            error "  iscsiadm --mode=node --portal=$portal --op=show"
114
 
            TGT_PID=""
115
 
            exit 0
116
 
        fi
117
 
    else
118
 
        error "nothing listening on $portal pid=$pid"
 
123
    if wait_for_tgtd $pid $portal; then
 
124
        error "grabbed $port in $pid on try $tries"
 
125
        cat >"$info" <<EOF
 
126
export TGT_PID=$pid
 
127
export TGT_IPC_SOCKET=$socket
 
128
export TGT_PORTAL=$portal
 
129
export CURTIN_VMTEST_ISCSI_PORTAL=\${TGT_PORTAL}
 
130
echo "To list targets on this tgt: " 1>&2
 
131
echo "  TGT_IPC_SOCKET=\${TGT_IPC_SOCKET} tgtadm --lld=iscsi --mode=target --op=show" 1>&2
 
132
echo "For a client view of visible disks:" 1>&2
 
133
echo "  iscsiadm --mode=discovery --type=sendtargets --portal=\${TGT_PORTAL}" 1>&2
 
134
echo "  iscsiadm --mode=node --portal=\${TGT_PORTAL} --op=show" 1>&2
 
135
EOF
 
136
        # unset to avoid cleanup
 
137
        TGT_PID=""
 
138
        exit
119
139
    fi
120
140
    kill -9 $pid >/dev/null 2>&1
121
141
    TGT_PID=""
122
142
    wait $pid
123
143
    tries=$(($tries+1))
124
144
done
 
145
error "gave up.  tried $tries times."
 
146
error "ports tried: ${tried_ports}"
 
147
exit 1
 
148
 
 
149
# vi: ts=4 expandtab