From 8a77d52515c5e90fc1f763cfd6381359176294f4 Mon Sep 17 00:00:00 2001 From: Amit Barve Date: Mon, 25 Aug 2025 15:58:37 -0400 Subject: [PATCH] Allow overriding UVM start timeout. Currently the uvm.Start() method hardcodes 2 minute timeout value in the context that gets used when making hvsocket connections to the UVM (for entropy, output handling & GCS) . This timeout is good enough for general scenario but is very restrictive when debugging uvm boot issues. This change allows overriding the default timeout via environment variables. Another option that was considered, was to use the deadline/timeout passed in the context instead of hardcoding it. However, there is code in the Start method that explicitly assumes that the parent context won't have a timeout(we could probably get around that problem by creating a new context without a deadline). Another problem is that there are lot of existing callers of the Start method who may or may not include a proper timeout/deadline in the context. If we suddenly start using that value, they might start seeing unexpected timeouts (for smaller context deadlines) or they may start noticing uvm start hanging (for longer deadlines). Signed-off-by: Amit Barve --- internal/timeout/timeout.go | 6 ++++++ internal/uvm/start.go | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/timeout/timeout.go b/internal/timeout/timeout.go index eaf39fa513..1c6e5fbb0d 100644 --- a/internal/timeout/timeout.go +++ b/internal/timeout/timeout.go @@ -47,6 +47,11 @@ var ( // TestDRetryLoop is the timeout for testd retry loop when onlining a SCSI disk in LCOW TestDRetryLoop = defaultTimeoutTestdRetry + + // This timeout is used for GCS connection after uvm boot as well as the entropy + // and log connection setup during uvm boot. This is different than the + // SystemStart timeout defined above. + GCSConnectionTimeout = 2 * time.Minute ) func init() { @@ -60,6 +65,7 @@ func init() { ExternalCommandToStart = durationFromEnvironment("HCSSHIM_TIMEOUT_EXTERNALCOMMANDSTART", ExternalCommandToStart) ExternalCommandToComplete = durationFromEnvironment("HCSSHIM_TIMEOUT_EXTERNALCOMMANDCOMPLETE", ExternalCommandToComplete) TestDRetryLoop = durationFromEnvironment("HCSSHIM_TIMEOUT_TESTDRETRYLOOP", TestDRetryLoop) + GCSConnectionTimeout = durationFromEnvironment("HCSSHIM_TIMEOUT_GCSCONNECTION", GCSConnectionTimeout) } func durationFromEnvironment(env string, defaultValue time.Duration) time.Duration { diff --git a/internal/uvm/start.go b/internal/uvm/start.go index 9ab8a9bdd5..b73143e0a9 100644 --- a/internal/uvm/start.go +++ b/internal/uvm/start.go @@ -26,6 +26,7 @@ import ( "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" + "github.com/Microsoft/hcsshim/internal/timeout" "github.com/Microsoft/hcsshim/internal/uvm/scsi" ) @@ -157,7 +158,9 @@ func (uvm *UtilityVM) configureHvSocketForGCS(ctx context.Context) (err error) { func (uvm *UtilityVM) Start(ctx context.Context) (err error) { // save parent context, without timeout to use in terminate pCtx := ctx - ctx, cancel := context.WithTimeout(pCtx, 2*time.Minute) + ctx, cancel := context.WithTimeout(pCtx, timeout.GCSConnectionTimeout) + log.G(ctx).Debugf("using gcs connection timeout: %s\n", timeout.GCSConnectionTimeout) + g, gctx := errgroup.WithContext(ctx) defer func() { _ = g.Wait()