Skip to content

Commit 8c1b780

Browse files
feat: Implement early frequent polling for CSI snapshots
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat> Signed-off-by: Scott Seago <sseago@redhat.com>
1 parent 79f0e72 commit 8c1b780

4 files changed

Lines changed: 60 additions & 28 deletions

File tree

pkg/cmd/cli/install/install.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ type Options struct {
8181
DefaultVolumesToFsBackup bool
8282
UploaderType string
8383
DefaultSnapshotMoveData bool
84+
CSISnapshotEarlyFrequentPolling bool
8485
DisableInformerCache bool
8586
ScheduleSkipImmediately bool
8687
PodResources kubeutil.PodResources
@@ -141,6 +142,7 @@ func (o *Options) BindFlags(flags *pflag.FlagSet) {
141142
flags.BoolVar(&o.DefaultVolumesToFsBackup, "default-volumes-to-fs-backup", o.DefaultVolumesToFsBackup, "Bool flag to configure Velero server to use pod volume file system backup by default for all volumes on all backups. Optional.")
142143
flags.StringVar(&o.UploaderType, "uploader-type", o.UploaderType, fmt.Sprintf("The type of uploader to transfer the data of pod volumes, supported value: '%s'", uploader.KopiaType))
143144
flags.BoolVar(&o.DefaultSnapshotMoveData, "default-snapshot-move-data", o.DefaultSnapshotMoveData, "Bool flag to configure Velero server to move data by default for all snapshots supporting data movement. Optional.")
145+
flags.BoolVar(&o.CSISnapshotEarlyFrequentPolling, "csi-snapshot-early-frequent-polling", o.CSISnapshotEarlyFrequentPolling, "Bool flag to configure Velero server to use early frequent polling by default for all CSI snapshots. Optional.")
144146
flags.BoolVar(&o.DisableInformerCache, "disable-informer-cache", o.DisableInformerCache, "Disable informer cache for Get calls on restore. With this enabled, it will speed up restore in cases where there are backup resources which already exist in the cluster, but for very large clusters this will increase velero memory usage. Default is false (don't disable). Optional.")
145147
flags.BoolVar(&o.ScheduleSkipImmediately, "schedule-skip-immediately", o.ScheduleSkipImmediately, "Skip the first scheduled backup immediately after creating a schedule. Default is false (don't skip).")
146148
flags.BoolVar(&o.NodeAgentDisableHostPath, "node-agent-disable-host-path", o.NodeAgentDisableHostPath, "Don't mount the pod volume host path to node-agent. Optional. Pod volume host path mount is required by fs-backup but could be disabled for other backup methods.")
@@ -238,16 +240,17 @@ func NewInstallOptions() *Options {
238240
NodeAgentPodCPULimit: install.DefaultNodeAgentPodCPULimit,
239241
NodeAgentPodMemLimit: install.DefaultNodeAgentPodMemLimit,
240242
// Default to creating a VSL unless we're told otherwise
241-
UseVolumeSnapshots: true,
242-
NoDefaultBackupLocation: false,
243-
CRDsOnly: false,
244-
DefaultVolumesToFsBackup: false,
245-
UploaderType: uploader.KopiaType,
246-
DefaultSnapshotMoveData: false,
247-
DisableInformerCache: false,
248-
ScheduleSkipImmediately: false,
249-
kubeletRootDir: install.DefaultKubeletRootDir,
250-
NodeAgentDisableHostPath: false,
243+
UseVolumeSnapshots: true,
244+
NoDefaultBackupLocation: false,
245+
CRDsOnly: false,
246+
DefaultVolumesToFsBackup: false,
247+
UploaderType: uploader.KopiaType,
248+
DefaultSnapshotMoveData: false,
249+
CSISnapshotEarlyFrequentPolling: false,
250+
DisableInformerCache: false,
251+
ScheduleSkipImmediately: false,
252+
kubeletRootDir: install.DefaultKubeletRootDir,
253+
NodeAgentDisableHostPath: false,
251254
}
252255
}
253256

@@ -324,6 +327,7 @@ func (o *Options) AsVeleroOptions() (*install.VeleroOptions, error) {
324327
DefaultVolumesToFsBackup: o.DefaultVolumesToFsBackup,
325328
UploaderType: o.UploaderType,
326329
DefaultSnapshotMoveData: o.DefaultSnapshotMoveData,
330+
CSISnapshotEarlyFrequentPolling: o.CSISnapshotEarlyFrequentPolling,
327331
DisableInformerCache: o.DisableInformerCache,
328332
ScheduleSkipImmediately: o.ScheduleSkipImmediately,
329333
PodResources: o.PodResources,

pkg/install/deployment.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type podTemplateConfig struct {
5050
serviceAccountName string
5151
uploaderType string
5252
defaultSnapshotMoveData bool
53+
csiSnapshotEarlyFrequentPolling bool
5354
privilegedNodeAgent bool
5455
disableInformerCache bool
5556
scheduleSkipImmediately bool
@@ -166,6 +167,12 @@ func WithDefaultSnapshotMoveData(b bool) podTemplateOption {
166167
}
167168
}
168169

170+
func WithCSISnapshotEarlyFrequentPolling(b bool) podTemplateOption {
171+
return func(c *podTemplateConfig) {
172+
c.csiSnapshotEarlyFrequentPolling = b
173+
}
174+
}
175+
169176
func WithDisableInformerCache(b bool) podTemplateOption {
170177
return func(c *podTemplateConfig) {
171178
c.disableInformerCache = b
@@ -488,6 +495,15 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1api.Deployme
488495
}...)
489496
}
490497

498+
if c.csiSnapshotEarlyFrequentPolling {
499+
deployment.Spec.Template.Spec.Containers[0].Env = append(deployment.Spec.Template.Spec.Containers[0].Env, []corev1api.EnvVar{
500+
{
501+
Name: "CSI_SNAPSHOT_EARLY_FREQUENT_POLLING",
502+
Value: "true",
503+
},
504+
}...)
505+
}
506+
491507
deployment.Spec.Template.Spec.Containers[0].Env = append(deployment.Spec.Template.Spec.Containers[0].Env, c.envVars...)
492508

493509
if len(c.plugins) > 0 {

pkg/install/resources.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ type VeleroOptions struct {
263263
DefaultVolumesToFsBackup bool
264264
UploaderType string
265265
DefaultSnapshotMoveData bool
266+
CSISnapshotEarlyFrequentPolling bool
266267
DisableInformerCache bool
267268
ScheduleSkipImmediately bool
268269
PodResources kube.PodResources
@@ -390,6 +391,10 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList {
390391
deployOpts = append(deployOpts, WithDefaultSnapshotMoveData(true))
391392
}
392393

394+
if o.CSISnapshotEarlyFrequentPolling {
395+
deployOpts = append(deployOpts, WithCSISnapshotEarlyFrequentPolling(true))
396+
}
397+
393398
if o.DisableInformerCache {
394399
deployOpts = append(deployOpts, WithDisableInformerCache(true))
395400
}

pkg/util/csi/volume_snapshot.go

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121
"encoding/json"
2222
"fmt"
23+
"os"
24+
"strconv"
2325
"strings"
2426
"time"
2527

@@ -660,25 +662,30 @@ func WaitUntilVSCHandleIsReady(
660662
return true, nil
661663
}
662664

663-
// The short interval for the first ten seconds is due to the fact that
664-
// Microsoft VSS backups have a hard-coded unfreeze call after 10 seconds,
665-
// so we need to minimize waiting time during the first 10 seconds.
666-
// First poll with a short interval and timeout.
667-
interval = 1 * time.Second
668-
timeout := 10 * time.Second
669-
err := wait.PollUntilContextTimeout(
670-
context.Background(),
671-
interval,
672-
timeout,
673-
true,
674-
pollFunc,
675-
)
665+
var err error
666+
frequentPolling, err := strconv.ParseBool(os.Getenv("CSI_SNAPSHOT_EARLY_FREQUENT_POLLING"))
667+
668+
if err == nil && frequentPolling {
669+
// The short interval for the first ten seconds is due to the fact that
670+
// Microsoft VSS backups have a hard-coded unfreeze call after 10 seconds,
671+
// so we need to minimize waiting time during the first 10 seconds.
672+
// First poll with a short interval and timeout.
673+
interval = 1 * time.Second
674+
timeout := 10 * time.Second
675+
err = wait.PollUntilContextTimeout(
676+
context.Background(),
677+
interval,
678+
timeout,
679+
true,
680+
pollFunc,
681+
)
676682

677-
if err == nil {
678-
return vsc, nil
679-
}
680-
if !wait.Interrupted(err) {
681-
return nil, err
683+
if err == nil {
684+
return vsc, nil
685+
}
686+
if !wait.Interrupted(err) {
687+
return nil, err
688+
}
682689
}
683690

684691
// If the first poll timed out, poll with a longer interval and the full timeout.

0 commit comments

Comments
 (0)