github.com/mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/libvirttools/storage_utils.go (about)

     1  /*
     2  Copyright 2017 Mirantis
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package libvirttools
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"runtime"
    23  
    24  	libvirtxml "github.com/libvirt/libvirt-go-xml"
    25  
    26  	"github.com/Mirantis/virtlet/pkg/virt"
    27  )
    28  
    29  // diskPath contains paths that can be used to locate a device inside
    30  // the VM using Linux-specific /dev or /sys paths
    31  type diskPath struct {
    32  	// devPath denotes path to the device under /dev, e.g.
    33  	// /dev/disk/by-path/virtio-pci-0000:00:03.0-scsi-0:0:0:0 or
    34  	// /dev/disk/by-path/pci-0000:00:03.0-virtio-pci-0000:01:01.0
    35  	devPath string
    36  	// sysfsPath denotes a path to a directory in sysfs that
    37  	// contains a file with the same name as the device in /dev, e.g.
    38  	// /sys/devices/pci0000:00/0000:00:03.0/0000:01:01.0/virtio*/block/ or
    39  	// /sys/devices/pci0000:00/0000:00:03.0/virtio*/host*/target*:0:0/*:0:0:0/block/sda
    40  	// (note that in the latter case * is used instead of host because host number appear
    41  	// to be wrong in sysfs for some reason)
    42  	// The path needs to be globbed and the single file name from there
    43  	// should be used as device name, e.g.
    44  	// ls -l /dev/`ls /sys/devices/pci0000:00/0000:00:03.0/0000:01:01.0/virtio*/block/`
    45  	sysfsPath string
    46  }
    47  
    48  // diskPathMap maps volume uuids to diskPath items
    49  type diskPathMap map[string]diskPath
    50  
    51  var supportedStoragePools = map[string]string{
    52  	"volumes": "/var/lib/virtlet/volumes",
    53  }
    54  
    55  func ensureStoragePool(conn virt.StorageConnection, name string) (virt.StoragePool, error) {
    56  	poolDir, found := supportedStoragePools[name]
    57  	if !found {
    58  		return nil, fmt.Errorf("pool with name '%s' is unknown", name)
    59  	}
    60  
    61  	pool, err := conn.LookupStoragePoolByName(name)
    62  	if err == nil {
    63  		return pool, nil
    64  	}
    65  	return conn.CreateStoragePool(&libvirtxml.StoragePool{
    66  		Type:   "dir",
    67  		Name:   name,
    68  		Target: &libvirtxml.StoragePoolTarget{Path: poolDir},
    69  	})
    70  }
    71  
    72  func verifyRawDeviceAccess(path string) error {
    73  	// XXX: make tests pass on non-Linux systems
    74  	if runtime.GOOS != "linux" {
    75  		return nil
    76  	}
    77  
    78  	// TODO: verify access rights for qemu process to this path
    79  	pathInfo, err := os.Stat(path)
    80  	if err != nil {
    81  		return err
    82  	}
    83  
    84  	// is this device and not char device?
    85  	if pathInfo.Mode()&os.ModeDevice != 0 && pathInfo.Mode()&os.ModeCharDevice == 0 {
    86  		return nil
    87  	}
    88  
    89  	return fmt.Errorf("path '%s' points to something other than block device", path)
    90  }