github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/diskmanager/diskmanager.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package diskmanager 5 6 import ( 7 "reflect" 8 "sort" 9 "time" 10 11 "github.com/juju/loggo" 12 "gopkg.in/juju/worker.v1" 13 14 "github.com/juju/juju/storage" 15 jworker "github.com/juju/juju/worker" 16 ) 17 18 var logger = loggo.GetLogger("juju.worker.diskmanager") 19 20 const ( 21 // listBlockDevicesPeriod is the time period between block device listings. 22 // Unfortunately Linux's inotify does not work with virtual filesystems, so 23 // polling it is. 24 listBlockDevicesPeriod = time.Second * 30 25 26 // bytesInMiB is the number of bytes in a MiB. 27 bytesInMiB = 1024 * 1024 28 ) 29 30 // BlockDeviceSetter is an interface that is supplied to 31 // NewWorker for setting block devices for the local host. 32 type BlockDeviceSetter interface { 33 SetMachineBlockDevices([]storage.BlockDevice) error 34 } 35 36 // ListBlockDevicesFunc is the type of a function that is supplied to 37 // NewWorker for listing block devices available on the local host. 38 type ListBlockDevicesFunc func() ([]storage.BlockDevice, error) 39 40 // DefaultListBlockDevices is the default function for listing block 41 // devices for the operating system of the local host. 42 var DefaultListBlockDevices ListBlockDevicesFunc 43 44 // NewWorker returns a worker that lists block devices 45 // attached to the machine, and records them in state. 46 var NewWorker = func(l ListBlockDevicesFunc, b BlockDeviceSetter) worker.Worker { 47 var old []storage.BlockDevice 48 f := func(stop <-chan struct{}) error { 49 return doWork(l, b, &old) 50 } 51 return jworker.NewPeriodicWorker(f, listBlockDevicesPeriod, jworker.NewTimer) 52 } 53 54 func doWork(listf ListBlockDevicesFunc, b BlockDeviceSetter, old *[]storage.BlockDevice) error { 55 blockDevices, err := listf() 56 if err != nil { 57 return err 58 } 59 storage.SortBlockDevices(blockDevices) 60 for _, blockDevice := range blockDevices { 61 sort.Strings(blockDevice.DeviceLinks) 62 } 63 if reflect.DeepEqual(blockDevices, *old) { 64 logger.Tracef("no changes to block devices detected") 65 return nil 66 } 67 logger.Infof("block devices changed: %v", blockDevices) 68 if err := b.SetMachineBlockDevices(blockDevices); err != nil { 69 return err 70 } 71 *old = blockDevices 72 return nil 73 }