mirror of
https://github.com/lxc/incus.git
synced 2026-02-05 09:46:19 +01:00
incusd/operations: Prevent concurrent access to metadata
Closes #2865 Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
This commit is contained in:
@@ -153,6 +153,7 @@ func OperationCreate(s *state.State, projectName string, opClass OperationClass,
|
|||||||
op.SetEventServer(s.Events)
|
op.SetEventServer(s.Events)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate and make a copy of the metadata to avoid concurrent reads/writes.
|
||||||
newMetadata, err := parseMetadata(opMetadata)
|
newMetadata, err := parseMetadata(opMetadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -506,7 +507,7 @@ func (op *Operation) Render() (string, *api.Operation, error) {
|
|||||||
|
|
||||||
op.lock.Lock()
|
op.lock.Lock()
|
||||||
|
|
||||||
// Make a copy of the metadata to avoid concurrent reads/writes.
|
// Make a read-only copy of the metadata to avoid concurrent reads/writes.
|
||||||
metadata := map[string]any{}
|
metadata := map[string]any{}
|
||||||
for k, v := range op.metadata {
|
for k, v := range op.metadata {
|
||||||
metadata[k] = v
|
metadata[k] = v
|
||||||
@@ -592,6 +593,7 @@ func (op *Operation) UpdateMetadata(opMetadata any) error {
|
|||||||
return errors.New("Read-only operations can't be updated")
|
return errors.New("Read-only operations can't be updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate and make a copy of the metadata to avoid concurrent reads/writes.
|
||||||
newMetadata, err := parseMetadata(opMetadata)
|
newMetadata, err := parseMetadata(opMetadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -635,7 +637,6 @@ func (op *Operation) ExtendMetadata(metadata any) error {
|
|||||||
|
|
||||||
// Get current metadata.
|
// Get current metadata.
|
||||||
newMetadata := op.metadata
|
newMetadata := op.metadata
|
||||||
op.lock.Unlock()
|
|
||||||
|
|
||||||
// Merge with current one.
|
// Merge with current one.
|
||||||
if op.metadata == nil {
|
if op.metadata == nil {
|
||||||
@@ -645,7 +646,6 @@ func (op *Operation) ExtendMetadata(metadata any) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the operation.
|
// Update the operation.
|
||||||
op.lock.Lock()
|
|
||||||
op.updatedAt = time.Now()
|
op.updatedAt = time.Now()
|
||||||
op.metadata = newMetadata
|
op.metadata = newMetadata
|
||||||
op.lock.Unlock()
|
op.lock.Unlock()
|
||||||
@@ -665,9 +665,18 @@ func (op *Operation) ID() string {
|
|||||||
return op.id
|
return op.id
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata returns the operation Metadata.
|
// Metadata returns a read-only copy of the operation metadata.
|
||||||
func (op *Operation) Metadata() map[string]any {
|
func (op *Operation) Metadata() map[string]any {
|
||||||
return op.metadata
|
op.lock.Lock()
|
||||||
|
defer op.lock.Unlock()
|
||||||
|
|
||||||
|
// Make a read-only copy of the metadata to avoid concurrent reads/writes.
|
||||||
|
metadata := map[string]any{}
|
||||||
|
for k, v := range op.metadata {
|
||||||
|
metadata[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL returns the operation URL.
|
// URL returns the operation URL.
|
||||||
|
|||||||
Reference in New Issue
Block a user