Skip to content

Commit

Permalink
[Windows] Improvement in cleanup script (#4722)
Browse files Browse the repository at this point in the history
The existing script would reset ovs-vswitchd when stuck in "starting" status. In some corner cases, ovsdb-server/ovs-ovswitchd services may be removed unexpectedly.

This change includes,
- add improvement to recover ovsdb-server/ovs-vswitched service if they do not exist when running the cleanup script.
- remove vNICs using Windows VMSwitch API rather than calling ovs-vsctl commands, this can remove the dependency on the running OVS userspace process (ovs-vswitchd).

Signed-off-by: wenyingd <wenyingd@vmware.com>
  • Loading branch information
wenyingd committed May 11, 2023
1 parent ca80de3 commit 7866681
Showing 1 changed file with 64 additions and 94 deletions.
158 changes: 64 additions & 94 deletions hack/windows/Clean-AntreaNetwork.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@
OVS installation directory. It is the path argument when using Install-OVS.ps1. The default path is "C:\openvswitch".
.PARAMETER RenewIPConfig
Renew the ipconfig on the host. The default value is $false.
.PARAMETER RemoveOVS
Remove ovsdb-server and ovs-vswitchd services fom the host. The default value is $false. If this argument is set
as true, this script would remove the two Windows services from the host. Otherwise, we consider that these
services are supposed to be running on the host, so the script would try to recover them if their statuses are
not as expected.
#>
Param(
[parameter(Mandatory = $false)] [string] $OVSInstallDir = "C:\openvswitch",
[parameter(Mandatory = $false)] [bool] $RenewIPConfig = $false
[parameter(Mandatory = $false)] [bool] $RenewIPConfig = $false,
[parameter(Mandatory = $false)] [bool] $RemoveOVS = $false
)

# Replace the path using the actual path where ovs-vswitchd.pid locates. It is always under path $OVSInstallDir\var\run\openvswitch.
Expand All @@ -19,53 +25,27 @@ $OVS_DB_SCHEMA_PATH = "$OVSInstallDir\usr\share\openvswitch\vswitch.ovsschema"
$OVSDB_CONF_DIR = "$OVSInstallDir\etc\openvswitch"
$OVS_DB_PATH = "$OVSDB_CONF_DIR\conf.db"
$OVS_BR_ADAPTER = "br-int"
$AntreaHnsNetworkName = "antrea-hnsnetwork"

function GetHnsnetworkId($NetName) {
$NetList= $(Get-HnsNetwork -ErrorAction SilentlyContinue)
if ($NetList -eq $null) {
return $null
}
foreach ($Net in $NetList) {
if ($Net.Name -eq $NetName) {
return $Net.Id
}
}
return $null
}

function ClearHyperVBinding($adapter) {
$status= $(Get-NetAdapterBinding -Name $adapter.Name -ComponentID vms_pp).Enabled
if ($status -EQ "False") {
Set-NetAdapterBinding -Name $adapter.Name -ComponentID vms_pp -Enabled $False
}
}

function ClearHyperVBindingOnAdapter($adapterName) {
if ($adapterName -NE "") {
$adapter = $(Get-NetAdapter -Name $adapterName)
if ($adapter -eq $null) {
return
}
ClearHyperVBinding($adapter)
} else {
$adapters= $(Get-NetAdapter | ? Virtual -EQ $false)
if ($adapters -eq $null) {
Write-Host "Physical network adapters not found"
return
}
foreach ($adapter in $adapters) {
ClearHyperVBinding($adapter)
}
}
function RemoveOVSService() {
stop-service ovs-vswitchd
sc.exe delete ovs-vswitchd
stop-service ovsdb-server
sc.exe delete ovsdb-server
}

function ResetOVSService() {
$ovsdbSvc = Get-Service ovsdb-server -ErrorAction Ignore
if ($ovsdbSvc -EQ $null) {
CreateStartOVSDB
}
$ovsVswitchdSvc = Get-Service ovs-vswitchd -ErrorAction Ignore
if ($ovsVswitchdSvc -EQ $null) {
CreateStartOVSvSwitchd
return
}
$ovsStatus = $(Get-Service ovs-vswitchd).Status
if ("$ovsStatus" -EQ "StartPending") {
if ("$ovsStatus" -ne "Running") {
sc.exe delete ovs-vswitchd
stop-service ovsdb-server

Expand All @@ -74,75 +54,65 @@ function ResetOVSService() {
ovsdb-tool create "$OVS_DB_PATH" "$OVS_DB_SCHEMA_PATH"

start-service ovsdb-server
sc.exe create ovs-vswitchd binpath="$OVSInstallDir\usr\sbin\ovs-vswitchd.exe --pidfile -vfile:info --log-file --service" start= auto depend= "ovsdb-server"
sc.exe failure ovs-vswitchd reset= 0 actions= restart/0/restart/0/restart/0
start-service ovs-vswitchd
CreateStartOVSvSwitchd
}
}

function RemoveNetworkAdapter($adapterName) {
$adapter = $(Get-NetAdapter "$adapterName" -ErrorAction Ignore)
if ($adapter -ne $null) {
Remove-NetIPAddress -IfAlias $adapterName -Confirm:$false
Write-Host "Network adapter $adapter.Name is left on the Windows host with status $adapter.Status, please remove it manually."
function CreateStartOVSDB() {
$OVS_DB_SCHEMA_PATH = "$OVSInstallDir\usr\share\openvswitch\vswitch.ovsschema"
$OVS_DB_PATH = "$OVSInstallDir\etc\openvswitch\conf.db"
if ($(Test-Path $OVS_DB_SCHEMA_PATH) -and !$(Test-Path $OVS_DB_PATH)) {
Log "Creating ovsdb file"
ovsdb-tool create "$OVS_DB_PATH" "$OVS_DB_SCHEMA_PATH"
}
sc.exe create ovsdb-server binPath= "$OVSInstallDir\usr\sbin\ovsdb-server.exe $OVSInstallDir\etc\openvswitch\conf.db -vfile:info --remote=punix:db.sock --remote=ptcp:6640 --log-file --pidfile --service" start= auto
sc.exe failure ovsdb-server reset= 0 actions= restart/0/restart/0/restart/0
Start-Service ovsdb-server
}

function RemoveHiddenNetDevices() {
$Devs = $(Get-PnpDevice -Class net | ? Status -eq Unknown | Select InstanceId)
foreach ($Dev in $Devs) {
$RemoveKey = "HKLM:\SYSTEM\CurrentControlSet\Enum\$($Dev.InstanceId)"
Get-Item $RemoveKey | Select-Object -ExpandProperty Property | %{Remove-ItemProperty -Path $RemoveKey -Name $_ -Verbose }
}
function CreateStartOVSvSwitchd() {
sc.exe create ovs-vswitchd binpath="$OVSInstallDir\usr\sbin\ovs-vswitchd.exe --pidfile -vfile:info --log-file --service" start= auto depend= "ovsdb-server"
sc.exe failure ovs-vswitchd reset= 0 actions= restart/0/restart/0/restart/0
start-service ovs-vswitchd
$OVS_VERSION=$(Get-Item $OVSInstallDir\driver\OVSExt.sys).VersionInfo.ProductVersion
ovs-vsctl --no-wait set Open_vSwitch . ovs_version=$OVS_VERSION
}

function clearOVSBridge() {
$ovsStatus = $(Get-Service ovs-vswitchd).Status
if ("$ovsStatus" -EQ "running") {
Write-Host "Delete OVS bridge: br-int"
ovs-vsctl.exe --no-wait --if-exists del-br br-int
$MaxRetryCount = 10
$RetryCountRange = 1..$MaxRetryCount
$BrIntDeleted = $false
foreach ($RetryCount in $RetryCountRange) {
Write-Host "Waiting for OVS bridge deletion complete ($RetryCount/$MaxRetryCount)..."
$BrIntAdapter = $(Get-NetAdapter "$OVS_BR_ADAPTER" -ErrorAction SilentlyContinue)
if ($BrIntAdapter -eq $null) {
$BrIntDeleted = $true
break
}
if ($RetryCount -eq $MaxRetryCount) {
break
}
Start-Sleep -Seconds 5
}
if (!$BrIntDeleted) {
Write-Host "Failed to delete OVS Bridge, please retry the script or delete the bridge and HNS network manually."
return
}
$ovsdbService = Get-Service ovsdb-server -ErrorAction SilentlyContinue
if ( $ovsdbService -ne $null -and $ovsdbService.Status -eq "Running") {
Write-Host "Delete OVS bridge from OVSDB: br-int"
ovs-vsctl.exe --no-wait --if-exists del-br $OVS_BR_ADAPTER
}
}

$BrIntDeleted = $(Get-NetAdapter "$OVS_BR_ADAPTER") -Eq $null
if ($BrIntDeleted -eq $false) {
clearOVSBridge
}
$uplink = ""
$AntreaHnsNetworkName = "antrea-hnsnetwork"
$NetId = GetHnsnetworkId($AntreaHnsNetworkName)
if ($NetId -ne $null) {
Write-Host "Remove HnsNetwork: $AntreaHnsNetworkName"
$uplink = $(Get-HnsNetwork -Id $NetId).NetworkAdapterName
Get-HnsNetwork -Id $NetId | Remove-HnsNetwork
function ClearHnsNetwork() {
$vmSwitch = Get-VMSwitch -Name $AntreaHnsNetworkName -ErrorAction SilentlyContinue
if ($vmSwitch -ne $null) {
Write-Host "Remove vNICs"
Remove-VMNetworkAdapter -SwitchName $AntreaHnsNetworkName -ManagementOS -Confirm:$false -ErrorAction SilentlyContinue
$hnsNetwork = Get-HnsNetwork | Where-Object {$_.Name -eq $AntreaHnsNetworkName}
if ($hnsNetwork -ne $null) {
Write-Host "Remove HnsNetwork: $AntreaHnsNetworkName"
$uplink = $hnsNetwork.NetworkAdapterName
Get-HnsNetwork -Id $hnsNetwork.Id | Remove-HnsNetwork -ErrorAction Continue
Set-NetAdapterBinding -Name $uplink -ComponentID vms_pp -Enabled $false
}
Remove-VMSwitch -Name $AntreaHnsNetworkName -Force -ErrorAction SilentlyContinue
}
}

# ResetOVSService is called if the Windows Service "ovs-vswitchd" is not running correctly (Service status is StartPending).
# This might happen after the Windows host is restarted abnormally, in which case some stale configurations block
# ovs-vswitchd running, like the pid file and the misconfigurations in OVSDB.
ResetOVSService "ovs-vswitchd"
RemoveNetworkAdapter $OVS_BR_ADAPTER
RemoveNetworkAdapter "antrea-gw0"
ClearHyperVBindingOnAdapter($uplink)
clearOVSBridge
ClearHnsNetwork
if ($RemoveOVS) {
RemoveOVSService
} else {
# ResetOVSService is called to recover Windows Services "ovsdb-server" and "ovs-vswitchd" if they are removed
# unexpectedly or their status is not correct, e.g., ovs-vswitchd fails to go into Running.
# This might happen after the Windows host is restarted abnormally, in which case some stale configurations
# can prevent ovs-vswitchd from running, like a stale pid file or misconfigurations in OVSDB.
ResetOVSService
}
if ($RenewIPConfig) {
ipconfig /renew
}

0 comments on commit 7866681

Please sign in to comment.