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)
|
||||
}
|
||||
|
||||
// Validate and make a copy of the metadata to avoid concurrent reads/writes.
|
||||
newMetadata, err := parseMetadata(opMetadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -506,7 +507,7 @@ func (op *Operation) Render() (string, *api.Operation, error) {
|
||||
|
||||
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{}
|
||||
for k, v := range op.metadata {
|
||||
metadata[k] = v
|
||||
@@ -592,6 +593,7 @@ func (op *Operation) UpdateMetadata(opMetadata any) error {
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -635,7 +637,6 @@ func (op *Operation) ExtendMetadata(metadata any) error {
|
||||
|
||||
// Get current metadata.
|
||||
newMetadata := op.metadata
|
||||
op.lock.Unlock()
|
||||
|
||||
// Merge with current one.
|
||||
if op.metadata == nil {
|
||||
@@ -645,7 +646,6 @@ func (op *Operation) ExtendMetadata(metadata any) error {
|
||||
}
|
||||
|
||||
// Update the operation.
|
||||
op.lock.Lock()
|
||||
op.updatedAt = time.Now()
|
||||
op.metadata = newMetadata
|
||||
op.lock.Unlock()
|
||||
@@ -665,9 +665,18 @@ func (op *Operation) ID() string {
|
||||
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 {
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user