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  }