Last active 20 hours ago

Revision 4a2b1b7f4ec9ccc5d1d2d988eedd00b60599cc8f

zone.sh Raw
1#!/bin/bash
2
3# #############################################
4# SmartOS Zombie Zone Cleanup Script
5# Usage: ./nuke_zone.sh <UUID>
6# 20200112
7# Use as ./nuke_zone.sh ecc5d57a-3d90-44ca-a89b-8869a120487d
8# #############################################
9
10UUID=$1
11
12# 1. Validation
13if [[ -z "$UUID" ]]; then
14 echo "Error: No UUID provided."
15 echo "Usage: $0 <zone-uuid>"
16 exit 1
17fi
18
19if [[ "$UUID" == "global" ]]; then
20 echo "Error: Cannot delete the global zone."
21 exit 1
22fi
23
24# Basic check to see if the UUID string format looks roughly correct (simple check)
25if [[ ! "$UUID" =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ ]]; then
26 echo "Warning: Format of '$UUID' does not look like a standard UUID."
27 read -p "Are you sure you want to proceed? (y/n) " -n 1 -r
28 echo
29 if [[ ! $REPLY =~ ^[Yy]$ ]]; then
30 exit 1
31 fi
32fi
33
34echo "--- Starting cleanup for Zone: $UUID ---"
35
36# 2. Check current status
37STATE=$(zoneadm -z "$UUID" list -p 2>/dev/null | cut -d: -f3)
38
39if [[ -z "$STATE" ]]; then
40 echo "Zone currently not recognized by zoneadm. Checking ZFS leftovers..."
41else
42 echo "Current Zone State: $STATE"
43fi
44
45# 3. Analyze and Kill Suspicious Processes
46echo "Checking for stuck processes..."
47# We look for zoneadmd specifically, as it is the controller.
48# We also look for qemu/bhyve instances associated with the UUID.
49PIDS=$(pgrep -f "$UUID")
50
51if [[ -n "$PIDS" ]]; then
52 echo "Found the following processes associated with this UUID:"
53 pgrep -lf "$UUID"
54
55 echo "Attempting to kill these processes to release locks..."
56 # We use kill -9 (SIGKILL) because if we are here, the process is likely unresponsive to SIGTERM.
57 echo "$PIDS" | xargs kill -9
58 sleep 2
59
60 # Verify they are gone
61 REMAINING=$(pgrep -f "$UUID")
62 if [[ -n "$REMAINING" ]]; then
63 echo "WARNING: Some processes refused to die: $REMAINING"
64 echo "This may indicate a kernel-level hung task (zombie)."
65 else
66 echo "Processes cleared."
67 fi
68else
69 echo "No locking processes found."
70fi
71
72# 4. Force state to installed/halted if possible
73# If the zone is technically 'running' in the kernel, we must halt it before uninstalling.
74if [[ "$STATE" == "running" || "$STATE" == "shutting_down" ]]; then
75 echo "Forcing zone halt..."
76 zoneadm -z "$UUID" halt
77 sleep 2
78fi
79
80# 5. Force Uninstall
81echo "Attempting forced uninstall (zoneadm)..."
82zoneadm -z "$UUID" uninstall -F
83RET=$?
84
85if [[ $RET -eq 0 ]]; then
86 echo "zoneadm uninstall reported success."
87else
88 echo "zoneadm uninstall reported an error (exit code $RET)."
89 echo "Proceeding to ZFS cleanup anyway."
90fi
91
92# 6. ZFS Dataset Cleanup
93# vmadm requires the dataset 'zones/<UUID>' to be gone to consider the VM deleted.
94DATASET="zones/$UUID"
95if zfs list "$DATASET" > /dev/null 2>&1; then
96 echo "ZFS dataset $DATASET still exists. Destroying it..."
97
98 # Check if there are dependent snapshots or clones (unlikely for a deletion, but possible)
99 # -r recursively destroys children/snapshots
100 zfs destroy -r "$DATASET"
101
102 if [[ $? -eq 0 ]]; then
103 echo "Dataset destroyed."
104 else
105 echo "Failed to destroy dataset. Check 'zfs list' manually."
106 fi
107else
108 echo "ZFS dataset $DATASET is already gone."
109fi
110
111# 7. Final Verification
112echo "--- Final Status Check ---"
113if vmadm list | grep -q "$UUID"; then
114 echo "FAILURE: $UUID still appears in 'vmadm list'."
115 vmadm list | grep "$UUID"
116else
117 echo "SUCCESS: $UUID is no longer in 'vmadm list'."
118fi
119
120if zoneadm list -cv | grep -q "$UUID"; then
121 echo "WARNING: $UUID still appears in 'zoneadm list'."
122else
123 echo "SUCCESS: $UUID is no longer in 'zoneadm list'."
124fi
125
126# #############################################