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 }