github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/hypervisor/checkVms.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/Cloud-Foundations/Dominator/lib/format"
     9  	"github.com/Cloud-Foundations/Dominator/lib/fsutil"
    10  	"github.com/Cloud-Foundations/Dominator/lib/json"
    11  	"github.com/Cloud-Foundations/Dominator/lib/log"
    12  	"github.com/Cloud-Foundations/Dominator/lib/wsyscall"
    13  	proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    14  )
    15  
    16  func checkVmsSubcommand(args []string, logger log.DebugLogger) error {
    17  	return checkVms(false)
    18  }
    19  
    20  func checkVms(repair bool) error {
    21  	dirname := filepath.Join(*stateDir, "VMs")
    22  	vms, err := fsutil.ReadDirnames(dirname, false)
    23  	if err != nil {
    24  		return err
    25  	}
    26  	var blocksAdded uint64
    27  	for _, vm := range vms {
    28  		filename := filepath.Join(dirname, vm, "info.json")
    29  		var vmInfo proto.LocalVmInfo
    30  		if err := json.ReadFromFile(filename, &vmInfo); err != nil {
    31  			return err
    32  		}
    33  		for index, volume := range vmInfo.VolumeLocations {
    34  			var statbuf wsyscall.Stat_t
    35  			if err := wsyscall.Stat(volume.Filename, &statbuf); err != nil {
    36  				return err
    37  			}
    38  			volumeSize := vmInfo.Volumes[index].Size
    39  			if volumeSize != uint64(statbuf.Size) {
    40  				fmt.Fprintf(os.Stderr, "%s size: %s should be: %s\n",
    41  					volume.Filename,
    42  					format.FormatBytes(uint64(statbuf.Size)),
    43  					format.FormatBytes(volumeSize))
    44  				continue
    45  			}
    46  			requiredBlocks := volumeSize >> 9
    47  			if requiredBlocks<<9 < volumeSize {
    48  				requiredBlocks++
    49  			}
    50  			if uint64(statbuf.Blocks) < requiredBlocks {
    51  				shift, unit := format.GetMiltiplier(uint64(statbuf.Blocks) << 9)
    52  				blocksAdded += requiredBlocks - uint64(statbuf.Blocks)
    53  				shiftRequired, unitRequired := format.GetMiltiplier(
    54  					requiredBlocks << 9)
    55  				if shiftRequired < shift {
    56  					shift = shiftRequired
    57  					unit = unitRequired
    58  				}
    59  				fmt.Fprintf(os.Stderr, "%s alloc: %d %sB should be: %d %sB\n",
    60  					volume.Filename,
    61  					(statbuf.Blocks<<9)>>shift, unit,
    62  					(requiredBlocks<<9)>>shift, unit)
    63  				if repair {
    64  					err := fsutil.Fallocate(volume.Filename, volumeSize)
    65  					if err != nil {
    66  						return fmt.Errorf("fallocate: %s: %s",
    67  							volume.Filename, err)
    68  					}
    69  				}
    70  			}
    71  		}
    72  	}
    73  	if blocksAdded < 1 {
    74  		return nil
    75  	}
    76  	if repair {
    77  		fmt.Fprintf(os.Stderr, "Total allocation increase: %s\n",
    78  			format.FormatBytes(blocksAdded<<9))
    79  	} else {
    80  		fmt.Fprintf(os.Stderr, "Total allocation increase required: %s\n",
    81  			format.FormatBytes(blocksAdded<<9))
    82  	}
    83  	return nil
    84  }