Skip to content

Commit f614b4c

Browse files
authored
Merge pull request #2569 from stgraber/storage
Fix panic on storage migration
2 parents 62c95e9 + 3e3ffdd commit f614b4c

8 files changed

Lines changed: 32 additions & 49 deletions

File tree

cmd/incusd/api_cluster.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,7 +2979,7 @@ func clusterNodeStatePost(d *Daemon, r *http.Request) response.Response {
29792979
return nil
29802980
}
29812981

2982-
migrateFunc := func(ctx context.Context, s *state.State, inst instance.Instance, sourceMemberInfo *db.NodeInfo, targetMemberInfo *db.NodeInfo, live bool, startInstance bool, metadata map[string]any, op *operations.Operation) error {
2982+
migrateFunc := func(ctx context.Context, s *state.State, inst instance.Instance, sourceMemberInfo *db.NodeInfo, targetMemberInfo *db.NodeInfo, live bool, startInstance bool, op *operations.Operation) error {
29832983
// Migrate the instance.
29842984
req := api.InstancePost{
29852985
Migration: true,
@@ -3003,9 +3003,8 @@ func clusterNodeStatePost(d *Daemon, r *http.Request) response.Response {
30033003

30043004
dest = dest.UseProject(inst.Project().Name)
30053005

3006-
if metadata != nil && op != nil {
3007-
metadata["evacuation_progress"] = fmt.Sprintf("Starting %q in project %q", inst.Name(), inst.Project().Name)
3008-
_ = op.UpdateMetadata(metadata)
3006+
if op != nil {
3007+
_ = op.ExtendMetadata(map[string]any{"evacuation_progress": fmt.Sprintf("Starting %q in project %q", inst.Name(), inst.Project().Name)})
30093008
}
30103009

30113010
startOp, err := dest.UpdateInstanceState(inst.Name(), api.InstanceStatePut{Action: "start"}, "")

cmd/incusd/api_cluster_evacuation.go

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import (
4040

4141
type (
4242
evacuateStopFunc func(inst instance.Instance, action string) error
43-
evacuateMigrateFunc func(ctx context.Context, s *state.State, inst instance.Instance, sourceMemberInfo *db.NodeInfo, targetMemberInfo *db.NodeInfo, live bool, startInstance bool, metadata map[string]any, op *operations.Operation) error
43+
evacuateMigrateFunc func(ctx context.Context, s *state.State, inst instance.Instance, sourceMemberInfo *db.NodeInfo, targetMemberInfo *db.NodeInfo, live bool, startInstance bool, op *operations.Operation) error
4444
)
4545

4646
type evacuateOpts struct {
@@ -185,8 +185,6 @@ func evacuateInstances(ctx context.Context, opts evacuateOpts) error {
185185
}
186186

187187
func evacuateInstancesFunc(ctx context.Context, inst instance.Instance, opts evacuateOpts) error {
188-
metadata := make(map[string]any)
189-
190188
instProject := inst.Project()
191189
l := logger.AddContext(logger.Ctx{"project": instProject.Name, "instance": inst.Name()})
192190

@@ -214,8 +212,7 @@ func evacuateInstancesFunc(ctx context.Context, inst instance.Instance, opts eva
214212
isRunning := inst.IsRunning()
215213
if action != "live-migrate" {
216214
if opts.stopInstance != nil && isRunning {
217-
metadata["evacuation_progress"] = fmt.Sprintf("Stopping %q in project %q", inst.Name(), instProject.Name)
218-
_ = opts.op.UpdateMetadata(metadata)
215+
_ = opts.op.ExtendMetadata(map[string]any{"evacuation_progress": fmt.Sprintf("Stopping %q in project %q", inst.Name(), instProject.Name)})
219216

220217
err := opts.stopInstance(inst, action)
221218
if err != nil {
@@ -245,16 +242,15 @@ func evacuateInstancesFunc(ctx context.Context, inst instance.Instance, opts eva
245242
}
246243

247244
// Start migrating the instance.
248-
metadata["evacuation_progress"] = fmt.Sprintf("Migrating %q in project %q to %q", inst.Name(), instProject.Name, targetMemberInfo.Name)
249-
_ = opts.op.UpdateMetadata(metadata)
245+
_ = opts.op.ExtendMetadata(map[string]any{"evacuation_progress": fmt.Sprintf("Migrating %q in project %q to %q", inst.Name(), instProject.Name, targetMemberInfo.Name)})
250246

251247
// Set origin server (but skip if already set as that suggests more than one server being evacuated).
252248
if inst.LocalConfig()["volatile.evacuate.origin"] == "" {
253249
_ = inst.VolatileSet(map[string]string{"volatile.evacuate.origin": opts.srcMemberName})
254250
}
255251

256252
start := isRunning || instanceShouldAutoStart(inst)
257-
err = opts.migrateInstance(ctx, opts.s, inst, sourceMemberInfo, targetMemberInfo, action == "live-migrate", start, metadata, opts.op)
253+
err = opts.migrateInstance(ctx, opts.s, inst, sourceMemberInfo, targetMemberInfo, action == "live-migrate", start, opts.op)
258254
if err != nil {
259255
return err
260256
}
@@ -342,9 +338,7 @@ func restoreClusterMember(d *Daemon, r *http.Request) response.Response {
342338
}
343339

344340
// Start the instance.
345-
metadata := make(map[string]any)
346-
metadata["evacuation_progress"] = fmt.Sprintf("Starting %q in project %q", inst.Name(), inst.Project().Name)
347-
_ = op.UpdateMetadata(metadata)
341+
_ = op.ExtendMetadata(map[string]any{"evacuation_progress": fmt.Sprintf("Starting %q in project %q", inst.Name(), inst.Project().Name)})
348342

349343
// If configured for stateful stop, try restoring its state.
350344
action := inst.CanMigrate()
@@ -396,15 +390,13 @@ func restoreClusterMemberFunc(inst instance.Instance, op *operations.Operation,
396390
var err error
397391
var source incus.InstanceServer
398392
var sourceNode db.NodeInfo
399-
metadata := make(map[string]any)
400393

401394
l := logger.AddContext(logger.Ctx{"project": inst.Project().Name, "instance": inst.Name()})
402395

403396
// Check the action.
404397
live := inst.CanMigrate() == "live-migrate"
405398

406-
metadata["evacuation_progress"] = fmt.Sprintf("Migrating %q in project %q from %q", inst.Name(), inst.Project().Name, inst.Location())
407-
_ = op.UpdateMetadata(metadata)
399+
_ = op.ExtendMetadata(map[string]any{"evacuation_progress": fmt.Sprintf("Migrating %q in project %q from %q", inst.Name(), inst.Project().Name, inst.Location())})
408400

409401
err = s.DB.Cluster.Transaction(context.Background(), func(ctx context.Context, tx *db.ClusterTx) error {
410402
sourceNode, err = tx.GetNodeByName(ctx, inst.Location())
@@ -432,8 +424,7 @@ func restoreClusterMemberFunc(inst instance.Instance, op *operations.Operation,
432424

433425
isRunning := apiInst.StatusCode == api.Running
434426
if isRunning && !live {
435-
metadata["evacuation_progress"] = fmt.Sprintf("Stopping %q in project %q", inst.Name(), inst.Project().Name)
436-
_ = op.UpdateMetadata(metadata)
427+
_ = op.ExtendMetadata(map[string]any{"evacuation_progress": fmt.Sprintf("Stopping %q in project %q", inst.Name(), inst.Project().Name)})
437428

438429
timeout := inst.ExpandedConfig()["boot.host_shutdown_timeout"]
439430
val, err := strconv.Atoi(timeout)
@@ -514,8 +505,7 @@ func restoreClusterMemberFunc(inst instance.Instance, op *operations.Operation,
514505
return nil
515506
}
516507

517-
metadata["evacuation_progress"] = fmt.Sprintf("Starting %q in project %q", inst.Name(), inst.Project().Name)
518-
_ = op.UpdateMetadata(metadata)
508+
_ = op.ExtendMetadata(map[string]any{"evacuation_progress": fmt.Sprintf("Starting %q in project %q", inst.Name(), inst.Project().Name)})
519509

520510
err = inst.Start(false)
521511
if err != nil {
@@ -728,7 +718,7 @@ func healClusterMember(d *Daemon, op *operations.Operation, name string) error {
728718
logger.Info("Starting cluster healing", logger.Ctx{"server": name})
729719
defer logger.Info("Completed cluster healing", logger.Ctx{"server": name})
730720

731-
migrateFunc := func(ctx context.Context, s *state.State, inst instance.Instance, sourceMemberInfo *db.NodeInfo, targetMemberInfo *db.NodeInfo, live bool, startInstance bool, metadata map[string]any, op *operations.Operation) error {
721+
migrateFunc := func(ctx context.Context, s *state.State, inst instance.Instance, sourceMemberInfo *db.NodeInfo, targetMemberInfo *db.NodeInfo, live bool, startInstance bool, op *operations.Operation) error {
732722
// This returns an error if the instance's storage pool is local.
733723
// Since we only care about remote backed instances, this can be ignored and return nil instead.
734724
poolName, err := inst.StoragePool()

cmd/incusd/backup.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,7 @@ func backupCreate(s *state.State, args db.InstanceBackup, sourceInst instance.In
152152
backupProgressWriter := &ioprogress.ProgressWriter{
153153
Tracker: &ioprogress.ProgressTracker{
154154
Handler: func(value, speed int64) {
155-
meta := op.Metadata()
156-
if meta == nil {
157-
meta = make(map[string]any)
158-
}
159-
160-
progressText := fmt.Sprintf("%s (%s/s)", units.GetByteSizeString(value, 2), units.GetByteSizeString(speed, 2))
161-
meta["create_backup_progress"] = progressText
162-
_ = op.UpdateMetadata(meta)
155+
_ = op.ExtendMetadata(map[string]any{"create_backup_progress": fmt.Sprintf("%s (%s/s)", units.GetByteSizeString(value, 2), units.GetByteSizeString(speed, 2))})
163156
},
164157
},
165158
}

cmd/incusd/daemon_images.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
341341
}
342342

343343
if meta["download_progress"] != progress.Text {
344-
meta["download_progress"] = progress.Text
345-
_ = op.UpdateMetadata(meta)
344+
_ = op.ExtendMetadata(map[string]any{"download_progress": progress.Text})
346345
}
347346
}
348347

cmd/incusd/images.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ func imgPostInstanceInfo(ctx context.Context, s *state.State, r *http.Request, r
278278
}
279279

280280
// Track progress creating image.
281-
metadata := make(map[string]any)
282281
metaProgressWriter := &ioprogress.ProgressWriter{
283282
Tracker: &ioprogress.ProgressTracker{
284283
Handler: func(value, speed int64) {
@@ -292,6 +291,7 @@ func imgPostInstanceInfo(ctx context.Context, s *state.State, r *http.Request, r
292291
processed = value
293292
}
294293

294+
metadata := make(map[string]any)
295295
operations.SetProgressMetadata(metadata, "create_image_from_container_pack", "Image pack", percent, processed, speed)
296296
_ = op.UpdateMetadata(metadata)
297297
},
@@ -312,6 +312,7 @@ func imgPostInstanceInfo(ctx context.Context, s *state.State, r *http.Request, r
312312
processed = value
313313
}
314314

315+
metadata := make(map[string]any)
315316
operations.SetProgressMetadata(metadata, "create_image_from_container_pack", "Image pack", percent, processed, speed)
316317
_ = op.UpdateMetadata(metadata)
317318
},
@@ -406,6 +407,7 @@ func imgPostInstanceInfo(ctx context.Context, s *state.State, r *http.Request, r
406407
// Tracker instance for the export phase.
407408
tracker := &ioprogress.ProgressTracker{
408409
Handler: func(value, speed int64) {
410+
metadata := make(map[string]any)
409411
operations.SetProgressMetadata(metadata, "create_image_from_container_pack", "Exporting", value, 0, 0)
410412
_ = op.UpdateMetadata(metadata)
411413
},

internal/server/instance/drivers/driver_common.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -857,8 +857,7 @@ func (d *common) updateProgress(progress string) {
857857
}
858858

859859
if meta["container_progress"] != progress {
860-
meta["container_progress"] = progress
861-
_ = d.op.UpdateMetadata(meta)
860+
_ = d.op.ExtendMetadata(map[string]any{"container_progress": progress})
862861
}
863862
}
864863

internal/server/instance/drivers/qmp/log.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ func (ql *qmpLog) open() error {
4747

4848
// Write writes len(b) bytes from b to the channel.
4949
func (ql *qmpLog) Write(p []byte) (n int, err error) {
50+
if ql == nil || ql.log == nil {
51+
return 0, nil
52+
}
53+
5054
ql.mu.Lock()
5155
defer ql.mu.Unlock()
5256

@@ -60,14 +64,14 @@ func (ql *qmpLog) Write(p []byte) (n int, err error) {
6064

6165
// Close closes the log and wait the channel clean.
6266
func (ql *qmpLog) Close() error {
63-
if ql.log != nil {
64-
ql.mu.Lock()
65-
defer ql.mu.Unlock()
66-
67-
err := ql.log.Close()
68-
ql.log = nil
69-
return err
67+
if ql == nil || ql.log == nil {
68+
return nil
7069
}
7170

72-
return nil
71+
ql.mu.Lock()
72+
defer ql.mu.Unlock()
73+
74+
err := ql.log.Close()
75+
ql.log = nil
76+
return err
7377
}

internal/server/migration/migration_volumes.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,7 @@ func MatchTypes(offer *migration.MigrationHeader, fallbackType migration.Migrati
248248
}
249249

250250
func progressWrapperRender(op *operations.Operation, key string, description string, progressInt int64, speedInt int64) {
251-
meta := op.Metadata()
252-
if meta == nil {
253-
meta = make(map[string]any)
254-
}
251+
meta := map[string]any{}
255252

256253
progress := fmt.Sprintf("%s (%s/s)", units.GetByteSizeString(progressInt, 2), units.GetByteSizeString(speedInt, 2))
257254
if description != "" {
@@ -260,7 +257,7 @@ func progressWrapperRender(op *operations.Operation, key string, description str
260257

261258
if meta[key] != progress {
262259
meta[key] = progress
263-
_ = op.UpdateMetadata(meta)
260+
_ = op.ExtendMetadata(meta)
264261
}
265262
}
266263

0 commit comments

Comments
 (0)