dom0: move network-attach logic to qubes.py

Main reason is to remove code duplication.
Also fixes #260 and workaround (by sleep...) some race at NetVM restart
(fronted driver does not noticed vif-detach+vif-attach).
This commit is contained in:
Marek Marczykowski 2011-09-03 16:07:10 +02:00
parent 5fe147729d
commit 58985193e7
3 changed files with 62 additions and 21 deletions

View File

@ -942,6 +942,44 @@ class QubesVm(object):
return conf
def attach_network(self, verbose = False, wait = True, netvm = None):
if dry_run:
return
if not self.is_running():
raise QubesException ("VM not running!")
if netvm is None:
netvm = self.netvm_vm
if netvm is None:
raise QubesException ("NetVM not set!")
if netvm.qid != 0:
if not netvm.is_running():
if verbose:
print "--> Starting NetVM {0}...".format(netvm.name)
netvm.start()
xs_path = '/local/domain/%d/device/vif/0/state' % (self.xid)
if xs.read('', xs_path) is not None:
# TODO: check its state and backend state (this can be stale vif after NetVM restart)
if verbose:
print "NOTICE: Network already attached"
return
xm_cmdline = ["/usr/sbin/xl", "network-attach", str(self.xid), "script=/etc/xen/scripts/vif-route-qubes", "ip="+self.ip, "backend="+netvm.name ]
retcode = subprocess.call (xm_cmdline)
if retcode != 0:
print ("WARNING: Cannot attach to network to '{0}'!".format(self.name))
if wait:
tries = 0
while xs.read('', xs_path) != '4':
tries += 1
if tries > 50:
raise QubesException ("Network attach timed out!")
time.sleep(0.2)
def start(self, debug_console = False, verbose = False, preparing_dvm = False):
if dry_run:
return
@ -1424,10 +1462,14 @@ class QubesNetVm(QubesVm):
# Cleanup stale VIFs
vm.cleanup_vifs()
xm_cmdline = ["/usr/sbin/xl", "network-attach", vm.name, "script=/etc/xen/scripts/vif-route-qubes", "ip="+vm.ip, "backend="+self.name ]
retcode = subprocess.call (xm_cmdline)
if retcode != 0:
print ("WARNING: Cannot attach to network to '{0}'!".format(vm.name))
# wait for frontend to forget about this device (UGLY HACK)
time.sleep(0.1)
try:
vm.attach_network(wait=False)
except QubesException as ex:
print ("WARNING: Cannot attach to network to '{0}': {1}".format(vm.name, ex))
return xid
def add_external_ip_permission(self, xid):
@ -1603,6 +1645,10 @@ class QubesDom0NetVm(QubesNetVm):
def get_private_img_sz(self):
return 0
@property
def ip(self):
return "10.137.0.1"
def start(self, debug_console = False, verbose = False):
raise QubesException ("Cannot start Dom0 fake domain!")

View File

@ -25,7 +25,10 @@ import os.path
import os
import sys
qvm_collection = None
def get_netvm():
global qvm_collection
qvm_collection = QubesVmCollection()
qvm_collection.lock_db_for_reading()
qvm_collection.load()
@ -59,12 +62,11 @@ def netup():
if os.path.isfile('/var/lock/subsys/NetworkManager'):
os.system('/etc/init.d/NetworkManager stop')
if not vif_eth0_exists():
cmd = 'modprobe xennet && xl network-attach 0 ip=10.137.0.1 backend='
cmd += netvm.name
cmd += ' script=/etc/xen/scripts/vif-route-qubes'
cmd = 'modprobe xennet'
if os.system(cmd) != 0:
print 'Error creating network device'
sys.exit(1)
qvm_collection[0].attach_network(verbose=True, netvm=netvm, wait=True)
if not bringup_eth0(netvm):
sys.exit(1)

View File

@ -128,22 +128,15 @@ def set_netvm(vms, vm, args):
vm.netvm_vm = netvm_vm
if not vm.is_running():
return
# this can fail if VM was not connected to any NetVM
subprocess.call(["xl", "network-detach", vm.name, "0"], stderr=subprocess.PIPE)
if vm.netvm_vm is None:
return
if not vm.netvm_vm.is_running():
subprocess.check_call(["qvm-start", vm.netvm_vm.name])
subprocess.check_call(["xl", "network-detach", vm.name, "0"])
domain_path="/local/domain/"+str(vm.get_xid())
subprocess.check_call(["xenstore-write",
domain_path+"/qubes_ip",
vm.ip])
subprocess.check_call(["xenstore-write",
domain_path+"/qubes_gateway",
vm.netvm_vm.gateway])
subprocess.check_call(["xenstore-write",
domain_path+"/qubes_secondary_dns",
vm.netvm_vm.secondary_dns])
subprocess.check_call(["xl", "network-attach", vm.name, "ip="+vm.ip,
"backend="+vm.netvm_vm.name,
"script=/etc/xen/scripts/vif-route-qubes"])
# refresh IP, DNS etc
vm.create_xenstore_entries()
vm.attach_network(verbose = True)
def set_updateable(vms, vm, args):
if vm.is_updateable():