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