@@ -16,9 +16,11 @@ import (
1616 "go.opentelemetry.io/otel/trace"
1717 "go.uber.org/zap"
1818 "go.uber.org/zap/zapio"
19+ "golang.org/x/sync/errgroup"
1920
2021 "github.com/e2b-dev/infra/packages/orchestrator/internal/cfg"
2122 "github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/network"
23+ "github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/rootfs"
2224 "github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/socket"
2325 "github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/template"
2426 "github.com/e2b-dev/infra/packages/shared/pkg/logger"
@@ -62,11 +64,11 @@ type Process struct {
6264 config cfg.BuilderConfig
6365 firecrackerSocketPath string
6466
65- slot * network.Slot
66- providerRootfsPath string
67- rootfsPath string
68- kernelPath string
69- files * storage.SandboxFiles
67+ slot * network.Slot
68+ rootfsProvider rootfs. Provider
69+ rootfsPath string
70+ kernelPath string
71+ files * storage.SandboxFiles
7072
7173 Exit * utils.ErrorOnce
7274
@@ -80,7 +82,7 @@ func NewProcess(
8082 slot * network.Slot ,
8183 files * storage.SandboxFiles ,
8284 versions Config ,
83- rootfsProviderPath string ,
85+ rootfsProvider rootfs. Provider ,
8486 rootfsPaths RootfsPaths ,
8587) (* Process , error ) {
8688 ctx , childSpan := tracer .Start (ctx , "initialize-fc" , trace .WithAttributes (
@@ -129,7 +131,7 @@ func NewProcess(
129131 firecrackerSocketPath : files .SandboxFirecrackerSocketPath (),
130132 config : config ,
131133 client : newApiClient (files .SandboxFirecrackerSocketPath ()),
132- providerRootfsPath : rootfsProviderPath ,
134+ rootfsProvider : rootfsProvider ,
133135 files : files ,
134136 slot : slot ,
135137
@@ -161,12 +163,7 @@ func (p *Process) configure(
161163 }
162164 p .cmd .Stderr = io .MultiWriter (stderrWriters ... )
163165
164- err := utils .SymlinkForce ("/dev/null" , p .files .SandboxCacheRootfsLinkPath (p .config .StorageConfig ))
165- if err != nil {
166- return fmt .Errorf ("error symlinking rootfs: %w" , err )
167- }
168-
169- err = p .cmd .Start ()
166+ err := p .cmd .Start ()
170167 if err != nil {
171168 return fmt .Errorf ("error starting fc process: %w" , err )
172169 }
@@ -227,7 +224,13 @@ func (p *Process) Create(
227224 ctx , childSpan := tracer .Start (ctx , "create-fc" )
228225 defer childSpan .End ()
229226
230- err := p .configure (
227+ // Symlink /dev/null to the rootfs link path, so we can start the FC process without the rootfs and then symlink the real rootfs.
228+ err := utils .SymlinkForce ("/dev/null" , p .files .SandboxCacheRootfsLinkPath (p .config .StorageConfig ))
229+ if err != nil {
230+ return fmt .Errorf ("error symlinking rootfs: %w" , err )
231+ }
232+
233+ err = p .configure (
231234 ctx ,
232235 sbxMetadata ,
233236 options .Stdout ,
@@ -290,10 +293,21 @@ func (p *Process) Create(
290293 telemetry .ReportEvent (ctx , "set fc boot source config" )
291294
292295 // Rootfs
293- err = utils . SymlinkForce ( p . providerRootfsPath , p . files . SandboxCacheRootfsLinkPath ( p . config . StorageConfig ) )
296+ rootfsPath , err := p . rootfsProvider . Path ( )
294297 if err != nil {
295- return fmt .Errorf ("error symlinking rootfs: %w" , err )
298+ fcStopErr := p .Stop (ctx )
299+
300+ return errors .Join (fmt .Errorf ("error getting rootfs path: %w" , err ), fcStopErr )
296301 }
302+ telemetry .ReportEvent (ctx , "got rootfs path" )
303+
304+ err = utils .SymlinkForce (rootfsPath , p .files .SandboxCacheRootfsLinkPath (p .config .StorageConfig ))
305+ if err != nil {
306+ fcStopErr := p .Stop (ctx )
307+
308+ return errors .Join (fmt .Errorf ("error symlinking rootfs: %w" , err ), fcStopErr )
309+ }
310+ telemetry .ReportEvent (ctx , "symlinked rootfs" )
297311
298312 err = p .client .setRootfsDrive (ctx , p .rootfsPath , options .IoEngine )
299313 if err != nil {
@@ -351,24 +365,64 @@ func (p *Process) Resume(
351365 ctx , span := tracer .Start (ctx , "resume-fc" )
352366 defer span .End ()
353367
354- err := p .configure (
355- ctx ,
356- sbxMetadata ,
357- nil ,
358- nil ,
359- )
368+ // Symlink /dev/null to the rootfs link path, so we can start the FC process without the rootfs and then symlink the real rootfs.
369+ err := utils .SymlinkForce ("/dev/null" , p .files .SandboxCacheRootfsLinkPath (p .config .StorageConfig ))
360370 if err != nil {
361- fcStopErr := p .Stop (ctx )
362-
363- return errors .Join (fmt .Errorf ("error starting fc process: %w" , err ), fcStopErr )
371+ return fmt .Errorf ("error symlinking rootfs: %w" , err )
364372 }
365373
366- err = utils .SymlinkForce (p .providerRootfsPath , p .files .SandboxCacheRootfsLinkPath (p .config .StorageConfig ))
374+ // create errgroup with context that handled socket wait + rootfs symlink
375+ eg , egCtx := errgroup .WithContext (ctx )
376+
377+ eg .Go (func () error {
378+ err := p .configure (
379+ egCtx ,
380+ sbxMetadata ,
381+ nil ,
382+ nil ,
383+ )
384+ if err != nil {
385+ return fmt .Errorf ("error starting fc process: %w" , err )
386+ }
387+
388+ telemetry .ReportEvent (egCtx , "configured fc" )
389+
390+ return nil
391+ })
392+
393+ eg .Go (func () error {
394+ err := socket .Wait (egCtx , uffdSocketPath )
395+ if err != nil {
396+ return fmt .Errorf ("error waiting for uffd socket: %w" , err )
397+ }
398+
399+ telemetry .ReportEvent (egCtx , "uffd socket ready" )
400+
401+ return nil
402+ })
403+
404+ eg .Go (func () error {
405+ rootfsPath , err := p .rootfsProvider .Path ()
406+ if err != nil {
407+ return fmt .Errorf ("error getting rootfs path: %w" , err )
408+ }
409+
410+ err = utils .SymlinkForce (rootfsPath , p .files .SandboxCacheRootfsLinkPath (p .config .StorageConfig ))
411+ if err != nil {
412+ return fmt .Errorf ("error symlinking rootfs: %w" , err )
413+ }
414+
415+ telemetry .ReportEvent (egCtx , "symlinked rootfs" )
416+
417+ return nil
418+ })
419+
420+ err = eg .Wait ()
367421 if err != nil {
368- return fmt .Errorf ("error symlinking rootfs: %w" , err )
369- }
422+ fcStopErr := p .Stop (ctx )
370423
371- telemetry .ReportEvent (ctx , "symlinked rootfs" )
424+ return errors .Join (fmt .Errorf ("error waiting for uffd socket or symlinking rootfs: %w" , err ), fcStopErr )
425+ }
372426
373427 err = p .client .loadSnapshot (
374428 ctx ,
0 commit comments