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  }