zoukankan      html  css  js  c++  java
  • kata container mount and umount

    func setupStorages(sandbox *Sandbox) []*grpc.Storage {
            storages := []*grpc.Storage{}
            caps := sandbox.hypervisor.capabilities()
    
            // append 9p shared volume to storages only if filesystem sharing is supported
            if caps.IsFsSharingSupported() {
                    // We mount the shared directory in a predefined location
                    // in the guest.
                    // This is where at least some of the host config files
                    // (resolv.conf, etc...) and potentially all container
                    // rootfs will reside.
                    if sandbox.config.HypervisorConfig.SharedFS == config.VirtioFS {
                            // If virtio-fs uses either of the two cache options 'auto, always',
                            // the guest directory can be mounted with option 'dax' allowing it to
                            // directly map contents from the host. When set to 'none', the mount
                            // options should not contain 'dax' lest the virtio-fs daemon crashing
                            // with an invalid address reference.
                            if sandbox.config.HypervisorConfig.VirtioFSCache != typeVirtioFSNoCache {
                                    // If virtio_fs_cache_size = 0, dax should not be used.
                                    if sandbox.config.HypervisorConfig.VirtioFSCacheSize != 0 {
                                            sharedDirVirtioFSOptions = append(sharedDirVirtioFSOptions, sharedDirVirtioFSDaxOptions)
                                    }
                            }
                            sharedVolume := &grpc.Storage{
                                    Driver:     kataVirtioFSDevType,
                                    Source:     mountGuestTag,
                                    MountPoint: kataGuestSharedDir(),
                                    Fstype:     typeVirtioFS,
                                    Options:    sharedDirVirtioFSOptions,
                            }
    
                            storages = append(storages, sharedVolume)
                    }
    // handleEphemeralStorage handles ephemeral storages by
    // creating a Storage from corresponding source of the mount point
    func (k *kataAgent) handleEphemeralStorage(mounts []specs.Mount) []*grpc.Storage {
            var epheStorages []*grpc.Storage
            for idx, mnt := range mounts {
                    if mnt.Type == KataEphemeralDevType {
                            // Set the mount source path to a path that resides inside the VM
                            mounts[idx].Source = filepath.Join(ephemeralPath(), filepath.Base(mnt.Source))
                            // Set the mount type to "bind"
                            mounts[idx].Type = "bind"
    
                            // Create a storage struct so that kata agent is able to create
                            // tmpfs backed volume inside the VM
                            epheStorage := &grpc.Storage{
                                    Driver:     KataEphemeralDevType,
                                    Source:     "tmpfs",
                                    Fstype:     "tmpfs",
                                    MountPoint: mounts[idx].Source,
                            }
                            epheStorages = append(epheStorages, epheStorage)
                    }
            }
            return epheStorages
    }
                   // Add the block device to the list of container devices, to make sure the
                    // device is detached with detachDevices() for a container.
                    c.devices = append(c.devices, ContainerDevice{ID: id, ContainerPath: m.Destination})
    
                    var vol *grpc.Storage
    
                    device := c.sandbox.devManager.GetDeviceByID(id)
                    if device == nil {
                            k.Logger().WithField("device", id).Error("failed to find device by id")
                            return nil, fmt.Errorf("Failed to find device by id (id=%s)", id)
                    }
    
                    var err error
                    switch device.DeviceType() {
                    case config.DeviceBlock:
                            vol, err = k.handleDeviceBlockVolume(c, device)
                    case config.VhostUserBlk:
                            vol, err = k.handleVhostUserBlkVolume(c, device)
                    default:
                            k.Logger().Error("Unknown device type")
                            continue
                    }
    
                    if vol == nil || err != nil {
                            return nil, err
                    }
    
                    vol.MountPoint = m.Destination
                    if vol.Fstype == "" {
                            vol.Fstype = "bind"
                    }
                    if len(vol.Options) == 0 {
                            vol.Options = []string{"bind"}
                    }
    
                    volumeStorages = append(volumeStorages, vol)
            }
    
            return volumeStorages, nil
    }
    func ephemeralStorageHandler(_ context.Context, storage pb.Storage, s *sandbox) (string, error) {
            s.Lock()
            defer s.Unlock()
            newStorage := s.setSandboxStorage(storage.MountPoint)
    
            if newStorage {
                    var err error
                    if err = os.MkdirAll(storage.MountPoint, os.ModePerm); err == nil {
                            _, err = commonStorageHandler(storage)
                    }
                    return "", err
            }
            return "", nil
    }
    // mountStorage performs the mount described by the storage structure.
    func mountStorage(storage pb.Storage) error {
            flags, options := parseMountFlagsAndOptions(storage.Options)
    
            return mount(storage.Source, storage.MountPoint, storage.Fstype, flags, options)
    }
    // storageHandler is the type of callback to be defined to handle every
    // type of storage driver.
    type storageHandler func(ctx context.Context, storage pb.Storage, s *sandbox) (string, error)
    
    // storageHandlerList lists the supported drivers.
    var storageHandlerList = map[string]storageHandler{
            driver9pType:        virtio9pStorageHandler,
            driverVirtioFSType:  virtioFSStorageHandler,
            driverBlkType:       virtioBlkStorageHandler,
            driverBlkCCWType:    virtioBlkCCWStorageHandler,
            driverMmioBlkType:   virtioMmioBlkStorageHandler,
            driverSCSIType:      virtioSCSIStorageHandler,
            driverEphemeralType: ephemeralStorageHandler,
            driverLocalType:     localStorageHandler,
            driverNvdimmType:    nvdimmStorageHandler,
    }
    // virtioBlkStorageHandler handles the storage for blk driver.
    func virtioBlkStorageHandler(_ context.Context, storage pb.Storage, s *sandbox) (string, error) {
    
            // If hot-plugged, get the device node path based on the PCI address else
            // use the virt path provided in Storage Source
            if strings.HasPrefix(storage.Source, "/dev") {
    
                    FileInfo, err := os.Stat(storage.Source)
                    if err != nil {
                            return "", err
    
                    }
                    // Make sure the virt path is valid
                    if FileInfo.Mode()&os.ModeDevice == 0 {
                            return "", fmt.Errorf("invalid device %s", storage.Source)
                    }
    
            } else {
                    devPath, err := getPCIDeviceName(s, storage.Source)
                    if err != nil {
                            return "", err
                    }
    
                    storage.Source = devPath
            }
    
            return commonStorageHandler(storage)
    }
    func commonStorageHandler(storage pb.Storage) (string, error) {
            // Mount the storage device.
            if err := mountStorage(storage); err != nil {
                    return "", err
            }
    
            return storage.MountPoint, nil
    }
    // mountStorage performs the mount described by the storage structure.
    func mountStorage(storage pb.Storage) error {
            flags, options := parseMountFlagsAndOptions(storage.Options)
    
            return mount(storage.Source, storage.MountPoint, storage.Fstype, flags, options)
    }
         mountList, err := addStorages(ctx, req.Storages, a.sandbox)
            if err != nil {
                    return emptyResp, err
            }
    
            ctr := &container{
                    id:              req.ContainerId,
                    processes:       make(map[string]*process),
                    mounts:          mountList,   //保存在mounts,后续remove
                    useSandboxPidNs: req.SandboxPidns,
                    agentPidNs:      req.AgentPidns,
                    ctx:             ctx,
            }

    mounts

    func (a *agentGRPC) RemoveContainer(ctx context.Context, req *pb.RemoveContainerRequest) (*gpb.Empty, error) {
            ctr, err := a.sandbox.getContainer(req.ContainerId)
            if err != nil {
                    return emptyResp, err
            }
    
            timeout := int(req.Timeout)
    
            a.sandbox.Lock()
            defer a.sandbox.Unlock()
    
            if timeout == 0 {
                    if err := ctr.removeContainer(); err != nil {
                            return emptyResp, err
                    }
    
                    // Find the sandbox storage used by this container
                    for _, path := range ctr.mounts {
                            if _, ok := a.sandbox.storages[path]; ok {
                                    if err := a.sandbox.unsetAndRemoveSandboxStorage(path); err != nil {
                                            return emptyResp, err
                                    }
                            }
                    }
            }
    func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process, err error) {
            span, _ := k.trace("createContainer")
            defer span.Finish()
    
            var ctrStorages []*grpc.Storage
            var ctrDevices []*grpc.Device
            var rootfs *grpc.Storage
    
            // This is the guest absolute root path for that container.
            rootPathParent := filepath.Join(kataGuestSharedDir(), c.id)
            rootPath := filepath.Join(rootPathParent, c.rootfsSuffix)
    
            // In case the container creation fails, the following defer statement
            // takes care of rolling back actions previously performed.
            defer func() {
                    if err != nil {
                            k.Logger().WithError(err).Error("createContainer failed")
                            k.rollbackFailingContainerCreation(c)
                    }
            }()
    
            if rootfs, err = k.buildContainerRootfs(sandbox, c, rootPathParent); err != nil {
                    return nil, err
            } else if rootfs != nil {
                    // Add rootfs to the list of container storage.
                    // We only need to do this for block based rootfs, as we
                    // want the agent to mount it into the right location
                    // (kataGuestSharedDir/ctrID/
                    ctrStorages = append(ctrStorages, rootfs)
            }
    
            ociSpec := c.GetPatchedOCISpec()
            if ociSpec == nil {
                    return nil, errorMissingOCISpec
            }
    
            // Handle container mounts
            newMounts, ignoredMounts, err := c.mountSharedDirMounts(getMountPath(sandbox.id), kataGuestSharedDir())
        if err != nil {
                    return nil, err
            }
    
            k.handleShm(ociSpec.Mounts, sandbox)
    
            epheStorages := k.handleEphemeralStorage(ociSpec.Mounts)
            ctrStorages = append(ctrStorages, epheStorages...)
    
            localStorages := k.handleLocalStorage(ociSpec.Mounts, sandbox.id, c.rootfsSuffix)
            ctrStorages = append(ctrStorages, localStorages...)
    
            // We replace all OCI mount sources that match our container mount
            // with the right source path (The guest one).
            if err = k.replaceOCIMountSource(ociSpec, newMounts); err != nil {
                    return nil, err
            }
    
            // Remove all mounts that should be ignored from the spec
            if err = k.removeIgnoredOCIMount(ociSpec, ignoredMounts); err != nil {
                    return nil, err
            }
    
            // Append container devices for block devices passed with --device.
            ctrDevices = k.appendDevices(ctrDevices, c)
    
            // Handle all the volumes that are block device files.
            // Note this call modifies the list of container devices to make sure
            // all hotplugged devices are unplugged, so this needs be done
            // after devices passed with --device are handled.
            volumeStorages, err := k.handleBlockVolumes(c)
            if err != nil {
                    return nil, err
            }
            if err := k.replaceOCIMountsForStorages(ociSpec, volumeStorages); err != nil {
                    return nil, err
            }
  • 相关阅读:
    司马光 王安石
    辛弃疾
    伯仲叔季
    三国时代
    西汉 东汉 三国(曹魏 蜀汉 东吴)
    数量关系练习题
    为什么不推荐使用外键约束
    Google Map API申请
    Android传感器——加速度传感器
    第三届空间信息智能服务研讨会
  • 原文地址:https://www.cnblogs.com/dream397/p/14078683.html
Copyright © 2011-2022 走看看