Skip to content

Support retrieve FDs #833

@keyingliu

Description

@keyingliu

There is such case: virtlet gets exited for some reasons, and during the restart, recover is executed without the TAP or other fds, everything is fine now. But later the qemu process may quit, kubelet will try to start a new one, but vmwrapper will fail to read the fds.

Can we extend the FDSource to add new method? If GetFDs is called, that means the VM is going to start, if FDServer found the fds is nil, it can call this method to retrieve the fds.

RetrieveFDs(key string) ([]int, error)

The code snippet look like:

// Retrieve retrieve the FDs
// It is only the case if VM exited but recover didn't populate the FDs
func (s *TapFDSource) RetrieveFDs(key string) ([]int, error) {
	var podNet *podNetwork
	func() {
		s.Lock()
		defer s.Unlock()
		podNet = s.fdMap[key]
	}()
	if podNet == nil {
		return nil, fmt.Errorf("bad key (%s) to retrieve FDs", key)
	}

	netNSPath := cni.PodNetNSPath(podNet.pnd.PodID)
	vmNS, err := ns.GetNS(netNSPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open network namespace at %q: %v", netNSPath, err)
	}

	if err := utils.CallInNetNSWithSysfsRemounted(vmNS, func(hostNS ns.NetNS) error {
		allLinks, err := netlink.LinkList()
		if err != nil {
			return fmt.Errorf("error listing the links: %v", err)
		}

		if err := nettools.RecoverContainerSideNetwork(podNet.csn, netNSPath, allLinks, hostNS, true); err != nil {
			return err
		}
		return nil
	}); err != nil {
		return nil, err
	}
	var fds []int
	s.Lock()
	defer s.Unlock()
	for _, ifDesc := range podNet.csn.Interfaces {
		fds = append(fds, int(ifDesc.Fo.Fd()))
	}
	return fds, nil
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions