Assaf Muller has uploaded a new change for review.

Change subject: Multiple Gateways[3/2]: Re-did communication between dhclient 
and vdsm
......................................................................

Multiple Gateways[3/2]: Re-did communication between dhclient and vdsm

SElinux disallows dhclient to change routing table information directly,
and so we needed a different way for dhclient to communicate with vdsm.
We did it via files and inotify.
dhclient writes to /var/run/vdsm/sourceRoutes with all of the info
of the DHCP response. supervdsm checks that folder upon startup
(in case dhclient operated while supervdsm was down) and registers
an inotify event handler on that folder on a separate thread.

Change-Id: Ib7a47a680bfbfe285f708290de97e8f08714695a
Signed-off-by: Assaf Muller <amul...@redhat.com>
---
M vdsm/sourceRoute.py
M vdsm/sourceRoute.sh
A vdsm/sourceRouteThread.py
M vdsm/supervdsmServer.py
4 files changed, 54 insertions(+), 59 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/61/16461/1

diff --git a/vdsm/sourceRoute.py b/vdsm/sourceRoute.py
index abae02f..7de484f 100644
--- a/vdsm/sourceRoute.py
+++ b/vdsm/sourceRoute.py
@@ -17,7 +17,6 @@
 # Refer to the README and COPYING files for full details of the license
 #
 
-from argparse import ArgumentParser
 from glob import iglob
 from libvirt import libvirtError
 import logging
@@ -175,58 +174,3 @@
                     self.configurator.removeSourceRoute(
                         self._getRoutes(table, self.device), rules,
                         self.device)
-
-
-def main():
-    parser = ArgumentParser()
-    subparsers = parser.add_subparsers(
-        title='actions', description='available source routing actions.',
-        help='configure will set the source routing and remove will unset it',
-        dest='action')
-
-    configure_parser = subparsers.add_parser('configure')
-    configure_parser.add_argument('bootproto',
-                                  choices=('none', 'dhcp'),
-                                  help='whether the IP information was '
-                                  'acquired statically or via DHCP')
-    configure_parser.add_argument('ip', help='base IP address of the network')
-    configure_parser.add_argument('mask', help='Mask of the network either in '
-                                  'prefix or in dot decimal notation')
-    configure_parser.add_argument('gateway', help='IP address of the gateway')
-    configure_parser.add_argument('device', help='Device to use for routing')
-
-    remove_parser = subparsers.add_parser('remove')
-    remove_parser.add_argument('bootproto', choices=('none', 'dhcp'),
-                               help='whether the IP information was acquired '
-                               'statically or via DHCP')
-    remove_parser.add_argument('device', help='Device for which to unset the '
-                               'routing')
-
-    args = parser.parse_args()
-    if args.bootproto == 'none':
-        configurator = Ifcfg(ConfigWriter())
-        sourceRoute = StaticSourceRoute(args.device, configurator)
-    else:
-        configurator = Iproute2()
-        sourceRoute = DynamicSourceRoute(args.device, configurator)
-
-    if not sourceRoute.isLibvirtInterface():
-        logging.info("interface %s is not a libvirt interface" %
-                     sourceRoute.device)
-        return
-
-    if args.action == 'configure':
-        sourceRoute.configure(args.ip, args.mask, args.gateway)
-    else:
-        sourceRoute.remove()
-
-
-if __name__ == "__main__":
-    # This imports are here due to the fact that we only need to create
-    # configurators if being used as a standalone script and because otherwise
-    # when importing SourceRoute from the configurators, we'd get a circular
-    # dependency.
-    from netconf.ifcfg import ConfigWriter
-    from netconf.ifcfg import Ifcfg
-    from netconf.iproute2 import Iproute2
-    main()
diff --git a/vdsm/sourceRoute.sh b/vdsm/sourceRoute.sh
index 2f65d46..6821e72 100755
--- a/vdsm/sourceRoute.sh
+++ b/vdsm/sourceRoute.sh
@@ -1,10 +1,10 @@
 #!/bin/bash
 
 sourceRoute_config() {
-    python /usr/share/vdsm/sourceRoute.pyc "configure" "dhcp" $new_ip_address \
-        $new_subnet_mask $new_routers $interface
+    echo "configure" $new_ip_address $new_subnet_mask $new_routers \
+        $interface > /var/run/vdsm/sourceRoutes/$interface
 }
 
 sourceRoute_restore() {
-    python /usr/share/vdsm/sourceRoute.pyc "remove" "dhcp" $interface
+    echo "remove" $interface > /var/run/vdsm/sourceRoutes/$interface
 }
diff --git a/vdsm/sourceRouteThread.py b/vdsm/sourceRouteThread.py
new file mode 100644
index 0000000..1a3d1ee
--- /dev/null
+++ b/vdsm/sourceRouteThread.py
@@ -0,0 +1,47 @@
+import logging
+import os
+
+import pyinotify
+
+from netconf.iproute2 import Iproute2
+from sourceRoute import DynamicSourceRoute
+
+
+SOURCE_ROUTES_FOLDER = os.path.join(os.sep, 'var', 'run', 'vdsm',
+                                    'sourceRoutes', '')
+configurator = Iproute2()
+
+
+class dhClientEventHandler(pyinotify.ProcessEvent):
+    def process_IN_CREATE(self, event):
+        with open(event.pathname, 'r') as sourceRouteFile:
+            sourceRouteContents = sourceRouteFile.read().split()
+            action = sourceRouteContents[0]
+            device = sourceRouteContents[-1]
+            sourceRoute = DynamicSourceRoute(device, configurator)
+
+            if action == 'configure':
+                ip = sourceRouteContents[1]
+                mask = sourceRouteContents[2]
+                gateway = sourceRouteContents[3]
+                sourceRoute.configure(ip, mask, gateway)
+            else:
+                sourceRoute.remove()
+
+        os.remove(event.pathname)
+
+
+def onSuperVDSMStart():
+    logging.debug("sourceRouteThread.onSuperVDSMStart fired")
+
+    # Subscribe to pyinotify event
+    watchManager = pyinotify.WatchManager()
+    handler = dhClientEventHandler()
+    notifier = pyinotify.Notifier(watchManager, handler)
+    watchManager.add_watch(SOURCE_ROUTES_FOLDER, pyinotify.IN_CREATE)
+
+    # Run once manually in case dhclient operated while supervdsm was down
+    for filePath in os.listdir(SOURCE_ROUTES_FOLDER):
+        handler.process_IN_CREATE(filePath)
+
+    notifier.loop()
diff --git a/vdsm/supervdsmServer.py b/vdsm/supervdsmServer.py
index 59aced6..9b6df34 100644
--- a/vdsm/supervdsmServer.py
+++ b/vdsm/supervdsmServer.py
@@ -53,6 +53,7 @@
 import ksm
 import mkimage
 from storage.multipath import MPATH_CONF
+import sourceRouteThread
 
 _UDEV_RULE_FILE_DIR = "/etc/udev/rules.d/"
 _UDEV_RULE_FILE_PREFIX = "99-vdsm-"
@@ -387,6 +388,9 @@
 
             log.debug("Started serving super vdsm object")
 
+            threading.Thread(target=sourceRouteThread.onSuperVDSMStart(),
+                             name='sourceRoute').start()
+
             # Python bug of thread.join() will block signal
             # http://bugs.python.org/issue1167930
             while servThread.isAlive():


-- 
To view, visit http://gerrit.ovirt.org/16461
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib7a47a680bfbfe285f708290de97e8f08714695a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Assaf Muller <amul...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to