New patch submitted by Federico Simoncelli (fsimonce@redhat.com)
You can review this change at: http://gerrit.usersys.redhat.com/704
commit 75f6afe98ffbd8b8e83f61e4d5b233e3fbd782eb Author: Federico Simoncelli fsimonce@redhat.com Date: Wed Jul 13 15:44:24 2011 +0000
[WIP] Move vdsm/hooks to vdsm_hooks
Change-Id: I2247df4e87edaac6979da30b17bbdeae299944b9
diff --git a/vdsm.spec.in b/vdsm.spec.in index e57ead5..9f526b9 100644 --- a/vdsm.spec.in +++ b/vdsm.spec.in @@ -70,12 +70,7 @@ make -C vdsm DESTDIR="%{buildroot}" \ install -dDm 1777 "%{buildroot}"%{_localstatedir}/log/core
# hook vhostmd -make -C vdsm/hooks/vhostmd DESTDIR="%{buildroot}" \ - LIBEXECDIR=%{_libexecdir}/%{vdsm_name} \ - install - -# hook faqemu -make -C vdsm/hooks/faqemu DESTDIR="%{buildroot}" \ +make -C vdsm_hooks DESTDIR="%{buildroot}" \ LIBEXECDIR=%{_libexecdir}/%{vdsm_name} \ install
diff --git a/vdsm/Makefile b/vdsm/Makefile index ef4137f..a0811af 100644 --- a/vdsm/Makefile +++ b/vdsm/Makefile @@ -10,8 +10,7 @@ INSTALL=install
FILES=define.py utils.py constants.py \ vm.py libvirtvm.py libvirtev.py \ - caps.py clientIF.py \ - hooks.py hooks/hooking.py \ + caps.py clientIF.py hooks.py hooking.py \ guestIF.py dsaversion.py \ configNetwork.py SecureXMLRPCServer.py ksm.py \ netinfo.py neterrors.py \ @@ -86,15 +85,6 @@ fixpaths: img_verifier vdsmd \ vdsm-store-net-config vdsm-restore-net-config
-HOOKS=before_vm_start after_vm_start before_vm_cont after_vm_cont \ - before_vm_pause after_vm_pause \ - before_vm_hibernate after_vm_hibernate \ - before_vm_dehibernate after_vm_dehibernate \ - before_vm_migrate_source after_vm_migrate_source \ - before_vm_migrate_destination after_vm_migrate_destination \ - after_vm_destroy \ - before_vdsm_start after_vdsm_stop - install: all sudoers.vdsm vdsm.conf.sample $(INSTALL) -Dd $(DESTDIR)$(VDSMDIR)/storage/protect $(INSTALL) -Dd $(DESTDIR)$(TRUSTSTORE)/{certs,keys} @@ -104,12 +94,10 @@ install: all sudoers.vdsm vdsm.conf.sample $(INSTALL) -Dd $(DESTDIR)$(POOLSDATADIR) $(INSTALL) -Dd $(DESTDIR)$(BACKUPDIR) $(INSTALL) -Dd $(DESTDIR)$(POOLDATADIR) + $(INSTALL) -Dd $(DESTDIR)$(LIBEXECDIR) $(INSTALL) -Dd $(DESTDIR)/etc/init.d $(INSTALL) -Dd $(DESTDIR)/etc/udev/rules.d $(INSTALL) -Dd -m 775 $(DESTDIR)/var/lib/libvirt/qemu/channels - (for hook in $(HOOKS); do \ - $(INSTALL) -Dd $(DESTDIR)$(LIBEXECDIR)/hooks/$$hook; \ - done) $(INSTALL) -Dm 644 $(FILES) $(DESTDIR)$(VDSMDIR) $(INSTALL) -Dm 755 $(SCRIPTFILES) $(DESTDIR)$(VDSMDIR) (cd storage; \ @@ -125,8 +113,6 @@ install: all sudoers.vdsm vdsm.conf.sample $(INSTALL) -Dm 644 vdsm-sosplugin.py $(DESTDIR)$(SOSPLUGINDIR)/vdsm.py $(INSTALL) -Dm 644 vdsmd.8 $(DESTDIR)$(MANDIR)/man8/vdsmd.8 $(INSTALL) -Dm 644 vdsm.rwtab $(DESTDIR)/etc/rwtab.d/vdsm - $(INSTALL) -Dm 755 hooks/persist-vdsm-hooks $(DESTDIR)$(LIBEXECDIR)/persist-vdsm-hooks - $(INSTALL) -Dm 755 hooks/unpersist-vdsm-hook $(DESTDIR)$(LIBEXECDIR)/unpersist-vdsm-hook
clean: $(RM) *~ *.pyc storage/protect/safelease vdsm.conf.sample diff --git a/vdsm/hooking.py b/vdsm/hooking.py new file mode 100644 index 0000000..e0ca856 --- /dev/null +++ b/vdsm/hooking.py @@ -0,0 +1,39 @@ +""" +hooking - various stuff useful when writing vdsm hooks + +A vm hook expects domain xml in a file named by an environment variable called +_hook_domxml. The hook may change the xml, but the "china store rule" applies - +if you break something, you own it. + +before_migration_destination hook receives the xml of the domain from the +source host. The xml of the domain at the destination will differ in various +details. + +Return codes: +0 - the hook ended successfully. +1 - the hook failed, other hooks should be processed. +2 - the hook failed, no further hooks should be processed. +>2 - reserverd +""" + +import os +from xml.dom import minidom + +def tobool(s): + """Convert the argument into a boolean""" + try: + if s == None: + return False + if type(s) == bool: + return s + if s.lower() == 'true': + return True + return bool(int(s)) + except: + return False + +def read_domxml(): + return minidom.parseString(file(os.environ['_hook_domxml']).read()) + +def write_domxml(domxml): + file(os.environ['_hook_domxml'], 'w').write(domxml.toxml(encoding='utf-8')) diff --git a/vdsm/hooks/faqemu/Makefile b/vdsm/hooks/faqemu/Makefile deleted file mode 100644 index 0ec2515..0000000 --- a/vdsm/hooks/faqemu/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -INSTALL=install -LN_S=ln -s -BINDIR=/usr/bin -LIBEXECDIR=/usr/libexec/vdsm -HOOKSDIR=$(LIBEXECDIR)/hooks - -install: - $(INSTALL) -Dm 755 qemu $(DESTDIR)$(BINDIR)/qemu - $(LN_S) qemu $(DESTDIR)$(BINDIR)/qemu-system-x86_64 - $(INSTALL) -Dm 755 before_vm_start.py $(DESTDIR)$(HOOKSDIR)/before_vm_start/10_faqemu - -clean: - $(RM) *~ *.pyc diff --git a/vdsm/hooks/faqemu/before_vm_start.py b/vdsm/hooks/faqemu/before_vm_start.py deleted file mode 100755 index bda1a71..0000000 --- a/vdsm/hooks/faqemu/before_vm_start.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/python - -import hooking -from config import config - -if config.getboolean('vars', 'fake_kvm_support'): - domxml = hooking.read_domxml() - - graphics = domxml.getElementsByTagName("graphics")[0] - graphics.removeAttribute("passwdValidTo") - - for memtag in ("memory", "currentMemory"): - memvalue = domxml.getElementsByTagName(memtag)[0] - while memvalue.firstChild: - memvalue.removeChild(memvalue.firstChild) - memvalue.appendChild(domxml.createTextNode("20480")) - - for cputag in domxml.getElementsByTagName("cpu"): - cputag.parentNode.removeChild(cputag) - - hooking.write_domxml(domxml) diff --git a/vdsm/hooks/faqemu/qemu b/vdsm/hooks/faqemu/qemu deleted file mode 100644 index b05ced0..0000000 --- a/vdsm/hooks/faqemu/qemu +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/python - -import os -import sys - -qemu_bin = "/usr/libexec/qemu-kvm" -qemu_argv = [ qemu_bin ] - -if not "-no-kvm" in sys.argv: - qemu_argv += [ "-no-kvm" ] - -qemu_argv += filter(lambda x: x != "-enable-kvm", sys.argv[1:]) -os.execv(qemu_bin, qemu_argv) diff --git a/vdsm/hooks/hooking.py b/vdsm/hooks/hooking.py deleted file mode 100644 index e0ca856..0000000 --- a/vdsm/hooks/hooking.py +++ /dev/null @@ -1,39 +0,0 @@ -""" -hooking - various stuff useful when writing vdsm hooks - -A vm hook expects domain xml in a file named by an environment variable called -_hook_domxml. The hook may change the xml, but the "china store rule" applies - -if you break something, you own it. - -before_migration_destination hook receives the xml of the domain from the -source host. The xml of the domain at the destination will differ in various -details. - -Return codes: -0 - the hook ended successfully. -1 - the hook failed, other hooks should be processed. -2 - the hook failed, no further hooks should be processed. ->2 - reserverd -""" - -import os -from xml.dom import minidom - -def tobool(s): - """Convert the argument into a boolean""" - try: - if s == None: - return False - if type(s) == bool: - return s - if s.lower() == 'true': - return True - return bool(int(s)) - except: - return False - -def read_domxml(): - return minidom.parseString(file(os.environ['_hook_domxml']).read()) - -def write_domxml(domxml): - file(os.environ['_hook_domxml'], 'w').write(domxml.toxml(encoding='utf-8')) diff --git a/vdsm/hooks/persist-vdsm-hooks b/vdsm/hooks/persist-vdsm-hooks deleted file mode 100755 index 2ac677a..0000000 --- a/vdsm/hooks/persist-vdsm-hooks +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -# -# Copyright 2009-2010 Red Hat, Inc. All rights reserved. -# Use is subject to license terms. -# -# Description: Persist all VDSM hooks -# - -HOOKS_DIR=/usr/libexec/vdsm/hooks - -if [[ -f /etc/rhev-hypervisor-release ]] -then - . /usr/libexec/ovirt-functions - for hook in "$HOOKS_DIR"/*/* - do - if [[ -f "$hook" ]] - then - ovirt_store_config "$hook" - fi - done -else - echo "Host is not RHEV-Hypervisor" - exit 1 -fi diff --git a/vdsm/hooks/unpersist-vdsm-hook b/vdsm/hooks/unpersist-vdsm-hook deleted file mode 100755 index af5af27..0000000 --- a/vdsm/hooks/unpersist-vdsm-hook +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -# -# Copyright 2009-2010 Red Hat, Inc. All rights reserved. -# Use is subject to license terms. -# -# Description: Unpersist VDSM Hook -# Input: VDSM Hook file full path -# - -HOOKS_DIR=/usr/libexec/vdsm/hooks -HOOK_TO_UNPERSIST="$1" - -if [[ -z "$HOOK_TO_UNPERSIST" ]]; then - echo "usage: $0 hook_file" - exit 1 -fi - -if [[ -f /etc/rhev-hypervisor-release ]] -then - . /usr/libexec/ovirt-functions - if [[ "$HOOK_TO_UNPERSIST" =~ ^"$HOOKS_DIR" ]] - then - # try to unpersist files only - if [[ -f "$HOOK_TO_UNPERSIST" ]] - then - ovirt_safe_delete_config "$HOOK_TO_UNPERSIST" - fi - fi -else - echo "Host is not RHEV-Hypervisor" - exit 1 -fi diff --git a/vdsm/hooks/vhostmd/Makefile b/vdsm/hooks/vhostmd/Makefile deleted file mode 100644 index 6f13033..0000000 --- a/vdsm/hooks/vhostmd/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -INSTALL=install -LN_S=ln -s -LIBEXECDIR=/usr/libexec/vdsm -HOOKSDIR=$(LIBEXECDIR)/hooks - -all: - -install: - $(INSTALL) -Dm 755 before_vm_start.py $(DESTDIR)$(HOOKSDIR)/before_vm_start/50_vhostmd - $(LN_S) ../before_vm_start/50_vhostmd $(DESTDIR)$(HOOKSDIR)/before_vm_migrate_destination/50_vhostmd - $(LN_S) ../before_vm_start/50_vhostmd $(DESTDIR)$(HOOKSDIR)/before_vm_dehibernate/50_vhostmd - $(INSTALL) -Dm 755 after_vm_destroy.py $(DESTDIR)$(HOOKSDIR)/after_vm_destroy/50_vhostmd - $(INSTALL) -Dm 440 sudoers.vdsm_hook_vhostmd $(DESTDIR)/etc/sudoers.d/50_vdsm_hook_vhostmd - -clean: - $(RM) *~ *.pyc diff --git a/vdsm/hooks/vhostmd/after_vm_destroy.py b/vdsm/hooks/vhostmd/after_vm_destroy.py deleted file mode 100644 index ae06ead..0000000 --- a/vdsm/hooks/vhostmd/after_vm_destroy.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/python - -import os -import subprocess -import hooking -import vdscli - -s = vdscli.connect() - -res = s.list(True) -if res['status']['code'] == 0: - if not [ v for v in res['vmList'] - if v.get('vmId') != os.environ.get('vmId') and - hooking.tobool(v.get('custom', {}).get('sap_agent', False)) ]: - subprocess.call(['/usr/bin/sudo', '-n', '/sbin/service', 'vhostmd', - 'stop']) diff --git a/vdsm/hooks/vhostmd/before_vm_start.py b/vdsm/hooks/vhostmd/before_vm_start.py deleted file mode 100644 index a76d19f..0000000 --- a/vdsm/hooks/vhostmd/before_vm_start.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python - -import os -import subprocess -import hooking - - -if hooking.tobool(os.environ.get('sap_agent', False)): - domxml = hooking.read_domxml() - - subprocess.call(['/usr/bin/sudo', '-n', '/sbin/service', 'vhostmd', - 'start']) - devs = domxml.getElementsByTagName('devices')[0] - diskelem = domxml.createElement('disk') - diskelem.setAttribute('device', 'disk') - - source = domxml.createElement('source') - diskelem.setAttribute('type', 'file') - source.setAttribute('file', '/dev/shm/vhostmd0') - diskelem.appendChild(source) - - target = domxml.createElement('target') - target.setAttribute('dev', 'vdzz') # FIXME do not use a static location - target.setAttribute('bus', 'virtio') - diskelem.appendChild(target) - - diskelem.appendChild(domxml.createElement('readonly')) - - devs.appendChild(diskelem) - - hooking.write_domxml(domxml) diff --git a/vdsm/hooks/vhostmd/sudoers.vdsm_hook_vhostmd b/vdsm/hooks/vhostmd/sudoers.vdsm_hook_vhostmd deleted file mode 100644 index ea34057..0000000 --- a/vdsm/hooks/vhostmd/sudoers.vdsm_hook_vhostmd +++ /dev/null @@ -1 +0,0 @@ -vdsm ALL=(ALL) NOPASSWD: /sbin/service vhostmd * diff --git a/vdsm_hooks/Makefile b/vdsm_hooks/Makefile new file mode 100644 index 0000000..64dd604 --- /dev/null +++ b/vdsm_hooks/Makefile @@ -0,0 +1,30 @@ +# Copyright 2008 Red Hat, Inc. and/or its affiliates. +# +# Licensed to you under the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. See the files README and +# LICENSE_GPL_v2 which accompany this distribution. +# + +INSTALL=install + +SUBDIRS=faqemu vhostmd + +HOOKS=before_vm_start after_vm_start before_vm_cont after_vm_cont \ + before_vm_pause after_vm_pause \ + before_vm_hibernate after_vm_hibernate \ + before_vm_dehibernate after_vm_dehibernate \ + before_vm_migrate_source after_vm_migrate_source \ + before_vm_migrate_destination after_vm_migrate_destination \ + after_vm_destroy \ + before_vdsm_start after_vdsm_stop + +install: + (for hook in $(HOOKS); do \ + $(INSTALL) -Dd $(DESTDIR)$(LIBEXECDIR)/hooks/$$hook; \ + done) + $(INSTALL) -Dm 755 persist-vdsm-hooks $(DESTDIR)$(LIBEXECDIR)/persist-vdsm-hooks + $(INSTALL) -Dm 755 unpersist-vdsm-hook $(DESTDIR)$(LIBEXECDIR)/unpersist-vdsm-hook + (for hook in $(SUBDIRS); do \ + make -C $$hook $@ \ + done) diff --git a/vdsm_hooks/faqemu/Makefile b/vdsm_hooks/faqemu/Makefile new file mode 100644 index 0000000..0ec2515 --- /dev/null +++ b/vdsm_hooks/faqemu/Makefile @@ -0,0 +1,13 @@ +INSTALL=install +LN_S=ln -s +BINDIR=/usr/bin +LIBEXECDIR=/usr/libexec/vdsm +HOOKSDIR=$(LIBEXECDIR)/hooks + +install: + $(INSTALL) -Dm 755 qemu $(DESTDIR)$(BINDIR)/qemu + $(LN_S) qemu $(DESTDIR)$(BINDIR)/qemu-system-x86_64 + $(INSTALL) -Dm 755 before_vm_start.py $(DESTDIR)$(HOOKSDIR)/before_vm_start/10_faqemu + +clean: + $(RM) *~ *.pyc diff --git a/vdsm_hooks/faqemu/before_vm_start.py b/vdsm_hooks/faqemu/before_vm_start.py new file mode 100755 index 0000000..bda1a71 --- /dev/null +++ b/vdsm_hooks/faqemu/before_vm_start.py @@ -0,0 +1,21 @@ +#!/usr/bin/python + +import hooking +from config import config + +if config.getboolean('vars', 'fake_kvm_support'): + domxml = hooking.read_domxml() + + graphics = domxml.getElementsByTagName("graphics")[0] + graphics.removeAttribute("passwdValidTo") + + for memtag in ("memory", "currentMemory"): + memvalue = domxml.getElementsByTagName(memtag)[0] + while memvalue.firstChild: + memvalue.removeChild(memvalue.firstChild) + memvalue.appendChild(domxml.createTextNode("20480")) + + for cputag in domxml.getElementsByTagName("cpu"): + cputag.parentNode.removeChild(cputag) + + hooking.write_domxml(domxml) diff --git a/vdsm_hooks/faqemu/qemu b/vdsm_hooks/faqemu/qemu new file mode 100644 index 0000000..b05ced0 --- /dev/null +++ b/vdsm_hooks/faqemu/qemu @@ -0,0 +1,13 @@ +#!/usr/bin/python + +import os +import sys + +qemu_bin = "/usr/libexec/qemu-kvm" +qemu_argv = [ qemu_bin ] + +if not "-no-kvm" in sys.argv: + qemu_argv += [ "-no-kvm" ] + +qemu_argv += filter(lambda x: x != "-enable-kvm", sys.argv[1:]) +os.execv(qemu_bin, qemu_argv) diff --git a/vdsm_hooks/persist-vdsm-hooks b/vdsm_hooks/persist-vdsm-hooks new file mode 100755 index 0000000..2ac677a --- /dev/null +++ b/vdsm_hooks/persist-vdsm-hooks @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Copyright 2009-2010 Red Hat, Inc. All rights reserved. +# Use is subject to license terms. +# +# Description: Persist all VDSM hooks +# + +HOOKS_DIR=/usr/libexec/vdsm/hooks + +if [[ -f /etc/rhev-hypervisor-release ]] +then + . /usr/libexec/ovirt-functions + for hook in "$HOOKS_DIR"/*/* + do + if [[ -f "$hook" ]] + then + ovirt_store_config "$hook" + fi + done +else + echo "Host is not RHEV-Hypervisor" + exit 1 +fi diff --git a/vdsm_hooks/unpersist-vdsm-hook b/vdsm_hooks/unpersist-vdsm-hook new file mode 100755 index 0000000..af5af27 --- /dev/null +++ b/vdsm_hooks/unpersist-vdsm-hook @@ -0,0 +1,32 @@ +#!/bin/bash +# +# Copyright 2009-2010 Red Hat, Inc. All rights reserved. +# Use is subject to license terms. +# +# Description: Unpersist VDSM Hook +# Input: VDSM Hook file full path +# + +HOOKS_DIR=/usr/libexec/vdsm/hooks +HOOK_TO_UNPERSIST="$1" + +if [[ -z "$HOOK_TO_UNPERSIST" ]]; then + echo "usage: $0 hook_file" + exit 1 +fi + +if [[ -f /etc/rhev-hypervisor-release ]] +then + . /usr/libexec/ovirt-functions + if [[ "$HOOK_TO_UNPERSIST" =~ ^"$HOOKS_DIR" ]] + then + # try to unpersist files only + if [[ -f "$HOOK_TO_UNPERSIST" ]] + then + ovirt_safe_delete_config "$HOOK_TO_UNPERSIST" + fi + fi +else + echo "Host is not RHEV-Hypervisor" + exit 1 +fi diff --git a/vdsm_hooks/vhostmd/Makefile b/vdsm_hooks/vhostmd/Makefile new file mode 100644 index 0000000..6f13033 --- /dev/null +++ b/vdsm_hooks/vhostmd/Makefile @@ -0,0 +1,16 @@ +INSTALL=install +LN_S=ln -s +LIBEXECDIR=/usr/libexec/vdsm +HOOKSDIR=$(LIBEXECDIR)/hooks + +all: + +install: + $(INSTALL) -Dm 755 before_vm_start.py $(DESTDIR)$(HOOKSDIR)/before_vm_start/50_vhostmd + $(LN_S) ../before_vm_start/50_vhostmd $(DESTDIR)$(HOOKSDIR)/before_vm_migrate_destination/50_vhostmd + $(LN_S) ../before_vm_start/50_vhostmd $(DESTDIR)$(HOOKSDIR)/before_vm_dehibernate/50_vhostmd + $(INSTALL) -Dm 755 after_vm_destroy.py $(DESTDIR)$(HOOKSDIR)/after_vm_destroy/50_vhostmd + $(INSTALL) -Dm 440 sudoers.vdsm_hook_vhostmd $(DESTDIR)/etc/sudoers.d/50_vdsm_hook_vhostmd + +clean: + $(RM) *~ *.pyc diff --git a/vdsm_hooks/vhostmd/after_vm_destroy.py b/vdsm_hooks/vhostmd/after_vm_destroy.py new file mode 100644 index 0000000..ae06ead --- /dev/null +++ b/vdsm_hooks/vhostmd/after_vm_destroy.py @@ -0,0 +1,16 @@ +#!/usr/bin/python + +import os +import subprocess +import hooking +import vdscli + +s = vdscli.connect() + +res = s.list(True) +if res['status']['code'] == 0: + if not [ v for v in res['vmList'] + if v.get('vmId') != os.environ.get('vmId') and + hooking.tobool(v.get('custom', {}).get('sap_agent', False)) ]: + subprocess.call(['/usr/bin/sudo', '-n', '/sbin/service', 'vhostmd', + 'stop']) diff --git a/vdsm_hooks/vhostmd/before_vm_start.py b/vdsm_hooks/vhostmd/before_vm_start.py new file mode 100644 index 0000000..a76d19f --- /dev/null +++ b/vdsm_hooks/vhostmd/before_vm_start.py @@ -0,0 +1,31 @@ +#!/usr/bin/python + +import os +import subprocess +import hooking + + +if hooking.tobool(os.environ.get('sap_agent', False)): + domxml = hooking.read_domxml() + + subprocess.call(['/usr/bin/sudo', '-n', '/sbin/service', 'vhostmd', + 'start']) + devs = domxml.getElementsByTagName('devices')[0] + diskelem = domxml.createElement('disk') + diskelem.setAttribute('device', 'disk') + + source = domxml.createElement('source') + diskelem.setAttribute('type', 'file') + source.setAttribute('file', '/dev/shm/vhostmd0') + diskelem.appendChild(source) + + target = domxml.createElement('target') + target.setAttribute('dev', 'vdzz') # FIXME do not use a static location + target.setAttribute('bus', 'virtio') + diskelem.appendChild(target) + + diskelem.appendChild(domxml.createElement('readonly')) + + devs.appendChild(diskelem) + + hooking.write_domxml(domxml) diff --git a/vdsm_hooks/vhostmd/sudoers.vdsm_hook_vhostmd b/vdsm_hooks/vhostmd/sudoers.vdsm_hook_vhostmd new file mode 100644 index 0000000..ea34057 --- /dev/null +++ b/vdsm_hooks/vhostmd/sudoers.vdsm_hook_vhostmd @@ -0,0 +1 @@ +vdsm ALL=(ALL) NOPASSWD: /sbin/service vhostmd *