@@ -36,15 +36,16 @@ const tmpfsSizeForBlockRootfs = "65536k"
3636var ErrMountpoint = errors .New ("no FS is mounted in this mountpoint" )
3737
3838type blockRootfs struct {
39- mounts []specs.Mount
40- monRootfs string
41- mountedPath string
42- path string
43- kernelPath string
44- initrdPath string
45- uruncJSONPath string
46- guestType string
47- guest types.Unikernel
39+ mounts []specs.Mount
40+ monRootfs string
41+ mountedPath string
42+ path string
43+ kernelPath string
44+ initrdPath string
45+ uruncJSONPath string
46+ guestType string
47+ guest types.Unikernel
48+ rootfsViewState * types.RootfsViewState
4849}
4950
5051// getMountInfo determines whether the provided path is a mount point
@@ -122,8 +123,6 @@ func getMountInfo(path string) (types.BlockDevParams, error) {
122123
123124// extractUnikernelFromBlock moves unikernel binary, initrd and urunc.json
124125// files from old rootfsPath to newRootfsPath
125- // FIXME: This approach fills up /run with unikernel binaries, initrds and urunc.json
126- // files for each unikernel we run
127126func extractBootFiles (rootfsPath string , newRootfsPath string , unikernel string , uruncJSON string , initrd string ) error {
128127 currentUnikernelPath := filepath .Join (rootfsPath , unikernel )
129128 targetUnikernelPath := filepath .Join (newRootfsPath , unikernel )
@@ -148,7 +147,6 @@ func extractBootFiles(rootfsPath string, newRootfsPath string, unikernel string,
148147 if err != nil {
149148 return fmt .Errorf ("could not move %s to %s: %w" , currentConfigPath , newRootfsPath , err )
150149 }
151-
152150 return nil
153151}
154152
@@ -226,24 +224,36 @@ func getBlockVolumes(monRootfs string, mounts []specs.Mount, ukernel types.Unike
226224}
227225
228226func (b blockRootfs ) preSetup () error {
227+ // Preserve main's propagation fix: consume boot artifacts and unmount the
228+ // container rootfs before prepareRoot() makes the mount tree private/slave.
229229 if b .mountedPath == "" {
230230 return nil
231231 }
232232
233- err := copyMountfiles (b .mountedPath , b .mounts )
234- if err != nil {
235- return fmt .Errorf ("failed to copy files from mount list: %w" , err )
233+ useViewPath := b .rootfsViewState != nil
234+ if useViewPath {
235+ // Probe only; the real bind must happen after prepareRoot.
236+ useView , err := probeRootfsViewBootArtifacts (b .rootfsViewState , b .kernelPath , b .initrdPath , b .uruncJSONPath )
237+ if err != nil {
238+ return err
239+ }
240+ if ! useView {
241+ useViewPath = false
242+ }
236243 }
237244
238- // FIXME: This approach fills up /run with unikernel binaries and
239- // urunc.json files for each unikernel instance we run
240- err = extractBootFiles ( b . mountedPath , b . monRootfs , b . kernelPath , b . uruncJSONPath , b . initrdPath )
241- if err != nil {
242- return fmt . Errorf ( "failed to extract boot files from rootfs: %w" , err )
245+ if ! useViewPath {
246+ err := extractBootFiles ( b . mountedPath , b . monRootfs , b . kernelPath , b . uruncJSONPath , b . initrdPath )
247+ if err != nil {
248+ return fmt . Errorf ( "failed to extract boot files from rootfs: %w" , err )
249+ }
243250 }
244251
245- err = mount .Unmount (b .mountedPath )
246- if err != nil {
252+ if err := copyMountfiles (b .mountedPath , b .mounts ); err != nil {
253+ return fmt .Errorf ("failed to copy files from mount list: %w" , err )
254+ }
255+
256+ if err := mount .Unmount (b .mountedPath ); err != nil {
247257 return fmt .Errorf ("failed to unmount rootfs: %w" , err )
248258 }
249259
@@ -262,10 +272,22 @@ func (b blockRootfs) postSetup() error {
262272 unix .MS_NOSUID | unix .MS_NOEXEC | unix .MS_STRICTATIME ,
263273 "1777" , tmpfsSizeForBlockRootfs )
264274 if err != nil {
265- err = fmt .Errorf ("failed to create tmpfs for monitor's execution environment: %w" , err )
275+ return fmt .Errorf ("failed to create tmpfs for monitor's execution environment: %w" , err )
276+ }
277+
278+ if b .rootfsViewState == nil {
279+ return nil
266280 }
267281
268- return err
282+ // Rootfs-view boot artifact binds must be created after prepareRoot()
283+ // has fixed the monitor rootfs propagation and self-bind. Keeping this in
284+ // postSetup() makes the ordering explicit while keeping the block-rootfs
285+ // specific setup inside the block rootfs implementation.
286+ if err := prepareRootfsViewBootBinds (b .rootfsViewState , b .monRootfs , b .kernelPath , b .initrdPath , b .uruncJSONPath ); err != nil {
287+ return fmt .Errorf ("boot artifact setup after prepareRoot failed: %w" , err )
288+ }
289+
290+ return nil
269291}
270292
271293func (b blockRootfs ) getBlockDevs () ([]types.BlockDevParams , error ) {
0 commit comments