MCPcopy
hub / github.com/containerd/containerd / mountWithHelper

Method mountWithHelper

core/mount/mount_linux.go:550–590  ·  view source on GitHub ↗
(helperBinary, typePrefix, target string)

Source from the content-addressed store, hash-verified

548}
549
550func (m *Mount) mountWithHelper(helperBinary, typePrefix, target string) error {
551 // helperBinary: "mount.fuse3"
552 // target: "/foo/merged"
553 // m.Type: "fuse3.fuse-overlayfs"
554 // command: "mount.fuse3 overlay /foo/merged -o lowerdir=/foo/lower2:/foo/lower1,upperdir=/foo/upper,workdir=/foo/work -t fuse-overlayfs"
555 args := []string{m.Source, target}
556 for _, o := range m.Options {
557 args = append(args, "-o", o)
558 }
559 args = append(args, "-t", strings.TrimPrefix(m.Type, typePrefix))
560
561 infoBeforeMount, err := Lookup(target)
562 if err != nil {
563 return err
564 }
565
566 // cmd.CombinedOutput() may intermittently return ECHILD because of our signal handling in shim.
567 // See #4387 and wait(2).
568 const retriesOnECHILD = 10
569 for range retriesOnECHILD {
570 cmd := exec.Command(helperBinary, args...)
571 out, err := cmd.CombinedOutput()
572 if err == nil {
573 return nil
574 }
575 if !errors.Is(err, unix.ECHILD) {
576 return fmt.Errorf("mount helper [%s %v] failed: %q: %w", helperBinary, args, string(out), err)
577 }
578 // We got ECHILD, we are not sure whether the mount was successful.
579 // If the mount ID has changed, we are sure we got some new mount, but still not sure it is fully completed.
580 // So we attempt to unmount the new mount before retrying.
581 infoAfterMount, err := Lookup(target)
582 if err != nil {
583 return err
584 }
585 if infoAfterMount.ID != infoBeforeMount.ID {
586 _ = unmount(target, 0)
587 }
588 }
589 return fmt.Errorf("mount helper [%s %v] failed with ECHILD (retried %d times)", helperBinary, args, retriesOnECHILD)
590}

Callers 1

mountMethod · 0.95

Calls 2

unmountFunction · 0.85
LookupFunction · 0.70

Tested by

no test coverage detected