Add synchronization around endpoint modification on RS1 - RS4

Server versions before 2019 (RS5), including Server 2016 (RS1) do not
support concurrent add/delete of endpoints. Therefore, we need to use
a mutex to serialize the add/delete of endpoints on those versions.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2019-04-08 13:58:14 +02:00
Родитель fcf074dcb6
Коммит f1eb7b70e8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 76698F39D527CE8C
1 изменённых файлов: 53 добавлений и 1 удалений

Просмотреть файл

@ -6,7 +6,9 @@ import (
"encoding/json"
"net"
"strings"
"sync"
"github.com/Microsoft/hcsshim/osversion"
"github.com/sirupsen/logrus"
)
@ -36,7 +38,7 @@ type HNSEndpoint struct {
SharedContainers []string `json:",omitempty"`
}
//SystemType represents the type of the system on which actions are done
// SystemType represents the type of the system on which actions are done
type SystemType string
// SystemType const
@ -46,6 +48,14 @@ const (
HostType SystemType = "Host"
)
var (
// Server versions before 2019 (RS5), including Server 2016 (RS1) do not
// support concurrent add/delete of endpoints. Therefore, we need to use
// this mutex and serialize the add/delete of endpoints on those versions.
endpointMu sync.RWMutex
windowsBuild = osversion.Build()
)
// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
// Supported resource types are Network and Request Types are Add/Remove
type EndpointAttachDetachRequest struct {
@ -76,6 +86,16 @@ type EndpointStats struct {
// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
endpoint := &HNSEndpoint{}
if windowsBuild < osversion.RS5 {
switch method {
case "GET":
endpointMu.RLock()
defer endpointMu.RUnlock()
case "DELETE", "POST":
endpointMu.Lock()
defer endpointMu.Unlock()
}
}
err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
if err != nil {
return nil, err
@ -87,6 +107,10 @@ func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
func HNSListEndpointRequest() ([]HNSEndpoint, error) {
var endpoint []HNSEndpoint
if windowsBuild < osversion.RS5 {
endpointMu.RLock()
defer endpointMu.RUnlock()
}
err := hnsCall("GET", "/endpoints/", "", &endpoint)
if err != nil {
return nil, err
@ -181,6 +205,10 @@ func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
if err != nil {
return nil, err
}
if windowsBuild < osversion.RS5 {
endpointMu.Lock()
defer endpointMu.Unlock()
}
err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
return endpoint, err
@ -244,6 +272,10 @@ func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID u
if err != nil {
return err
}
if windowsBuild < osversion.RS5 {
endpointMu.Lock()
defer endpointMu.Unlock()
}
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
}
@ -263,6 +295,10 @@ func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
if err != nil {
return err
}
if windowsBuild < osversion.RS5 {
endpointMu.Lock()
defer endpointMu.Unlock()
}
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
}
@ -281,6 +317,10 @@ func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
if err != nil {
return err
}
if windowsBuild < osversion.RS5 {
endpointMu.Lock()
defer endpointMu.Unlock()
}
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
}
@ -298,6 +338,10 @@ func (endpoint *HNSEndpoint) HostDetach() error {
if err != nil {
return err
}
if windowsBuild < osversion.RS5 {
endpointMu.Lock()
defer endpointMu.Unlock()
}
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
}
@ -316,6 +360,10 @@ func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName strin
if err != nil {
return err
}
if windowsBuild < osversion.RS5 {
endpointMu.Lock()
defer endpointMu.Unlock()
}
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
}
@ -334,5 +382,9 @@ func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
if err != nil {
return err
}
if windowsBuild < osversion.RS5 {
endpointMu.Lock()
defer endpointMu.Unlock()
}
return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
}