Revision 5d94c034 lib/storage/filestorage.py

b/lib/storage/filestorage.py
23 23

  
24 24
"""
25 25

  
26
from ganeti import errors
27
from ganeti import utils
28

  
29
DF_M_UNIT = 'M'
30
DF_MIN_NUM_COLS = 4
31
DF_NUM_LINES = 2
32

  
33

  
34
def _ParseDfResult(dfresult):
35
  """Parses the output of the call of the 'df' tool.
26
import os
36 27

  
37
     @type dfresult: string
38
     @param dfresult: output of the 'df' call
39
     @return: tuple (size, free) of the total and free disk space in MebiBytes
40
  """
41
  df_lines = dfresult.splitlines()
42
  if len(df_lines) != DF_NUM_LINES:
43
    raise errors.CommandError("'df' output has wrong number of lines: %s" %
44
                              len(df_lines))
45
  df_values = df_lines[1].strip().split()
46
  if len(df_values) < DF_MIN_NUM_COLS:
47
    raise errors.CommandError("'df' output does not have enough columns: %s" %
48
                              len(df_values))
49
  size_str = df_values[1]
50
  if size_str[-1] != DF_M_UNIT:
51
    raise errors.CommandError("'df': 'size' not given in Mebibytes.")
52
  free_str = df_values[3]
53
  if free_str[-1] != DF_M_UNIT:
54
    raise errors.CommandError("'df': 'free' not given in Mebibytes.")
55
  size = int(size_str[:-1])
56
  free = int(free_str[:-1])
57
  return (size, free)
28
from ganeti import errors
58 29

  
59 30

  
60
def GetSpaceInfo(path, _parsefn=_ParseDfResult):
31
def GetSpaceInfo(path):
61 32
  """Retrieves the free and total space of the device where the file is
62 33
     located.
63 34

  
64 35
     @type path: string
65 36
     @param path: Path of the file whose embracing device's capacity is
66 37
       reported.
67
     @type _parsefn: function
68
     @param _parsefn: Function that parses the output of the 'df' command;
69
       given as parameter to make this code more testable.
70
     @return: a dictionary containing 'vg_size' and 'vg_free'
38
     @return: a dictionary containing 'vg_size' and 'vg_free' given in MebiBytes
39

  
71 40
  """
72
  cmd = ['df', '-BM', path]
73
  result = utils.RunCmd(cmd)
74
  if result.failed:
75
    raise errors.CommandError("Failed to run 'df' command: %s - %s" %
76
                              (result.fail_reason, result.output))
77
  (size, free) = _parsefn(result.stdout)
78
  return {"vg_size": size, "vg_free": free}
41
  try:
42
    result = os.statvfs(path)
43
    free = (result.f_frsize * result.f_bavail) / (1024 * 1024)
44
    size = (result.f_frsize * result.f_blocks) / (1024 * 1024)
45
    return {"vg_size": size, "vg_free": free}
46
  except OSError, e:
47
    raise errors.CommandError("Failed to retrieve file system information about"
48
                              " path: %s - %s" % (path, e.strerror))

Also available in: Unified diff