Revision ea2bcb82

b/lib/hypervisor/hv_kvm.py
80 80
  ])
81 81

  
82 82

  
83
def _ProbeTapVnetHdr(fd):
83
def _GetTunFeatures(fd, _ioctl=fcntl.ioctl):
84
  """Retrieves supported TUN features from file descriptor.
85

  
86
  @see: L{_ProbeTapVnetHdr}
87

  
88
  """
89
  req = struct.pack("I", 0)
90
  try:
91
    buf = _ioctl(fd, TUNGETFEATURES, req)
92
  except EnvironmentError, err:
93
    logging.warning("ioctl(TUNGETFEATURES) failed: %s" % err)
94
    return None
95
  else:
96
    (flags, ) = struct.unpack("I", buf)
97
    return flags
98

  
99

  
100
def _ProbeTapVnetHdr(fd, _features_fn=_GetTunFeatures):
84 101
  """Check whether to enable the IFF_VNET_HDR flag.
85 102

  
86 103
  To do this, _all_ of the following conditions must be met:
......
97 114
   @param fd: the file descriptor of /dev/net/tun
98 115

  
99 116
  """
100
  req = struct.pack("I", 0)
101
  try:
102
    res = fcntl.ioctl(fd, TUNGETFEATURES, req)
103
  except EnvironmentError:
104
    logging.warning("TUNGETFEATURES ioctl() not implemented")
105
    return False
117
  flags = _features_fn(fd)
106 118

  
107
  tunflags = struct.unpack("I", res)[0]
108
  if tunflags & IFF_VNET_HDR:
109
    return True
110
  else:
111
    logging.warning("Host does not support IFF_VNET_HDR, not enabling")
119
  if flags is None:
120
    # Not supported
112 121
    return False
113 122

  
123
  result = bool(flags & IFF_VNET_HDR)
124

  
125
  if not result:
126
    logging.warning("Kernel does not support IFF_VNET_HDR, not enabling")
127

  
128
  return result
129

  
114 130

  
115 131
def _OpenTap(vnet_hdr=True):
116 132
  """Open a new tap device and return its file descriptor.
b/test/py/ganeti.hypervisor.hv_kvm_unittest.py
26 26
import unittest
27 27
import socket
28 28
import os
29
import struct
29 30

  
30 31
from ganeti import serializer
31 32
from ganeti import constants
......
315 316
    self.assertFalse(boot_re.search(help_01590))
316 317

  
317 318

  
319
class TestGetTunFeatures(unittest.TestCase):
320
  def testWrongIoctl(self):
321
    tmpfile = tempfile.NamedTemporaryFile()
322
    # A file does not have the right ioctls, so this must always fail
323
    result = hv_kvm._GetTunFeatures(tmpfile.fileno())
324
    self.assertTrue(result is None)
325

  
326
  def _FakeIoctl(self, features, fd, request, buf):
327
    self.assertEqual(request, hv_kvm.TUNGETFEATURES)
328

  
329
    (reqno, ) = struct.unpack("I", buf)
330
    self.assertEqual(reqno, 0)
331

  
332
    return struct.pack("I", features)
333

  
334
  def test(self):
335
    tmpfile = tempfile.NamedTemporaryFile()
336
    fd = tmpfile.fileno()
337

  
338
    for features in [0, hv_kvm.IFF_VNET_HDR]:
339
      fn = compat.partial(self._FakeIoctl, features)
340
      result = hv_kvm._GetTunFeatures(fd, _ioctl=fn)
341
      self.assertEqual(result, features)
342

  
343

  
344
class TestProbeTapVnetHdr(unittest.TestCase):
345
  def _FakeTunFeatures(self, expected_fd, flags, fd):
346
    self.assertEqual(fd, expected_fd)
347
    return flags
348

  
349
  def test(self):
350
    tmpfile = tempfile.NamedTemporaryFile()
351
    fd = tmpfile.fileno()
352

  
353
    for flags in [0, hv_kvm.IFF_VNET_HDR]:
354
      fn = compat.partial(self._FakeTunFeatures, fd, flags)
355

  
356
      result = hv_kvm._ProbeTapVnetHdr(fd, _features_fn=fn)
357
      if flags == 0:
358
        self.assertFalse(result)
359
      else:
360
        self.assertTrue(result)
361

  
362
  def testUnsupported(self):
363
    tmpfile = tempfile.NamedTemporaryFile()
364
    fd = tmpfile.fileno()
365

  
366
    self.assertFalse(hv_kvm._ProbeTapVnetHdr(fd, _features_fn=lambda _: None))
367

  
368

  
318 369
if __name__ == "__main__":
319 370
  testutils.GanetiTestProgram()

Also available in: Unified diff