diff --git a/ovm/scripts/vm/hypervisor/ovm/OvmCommonModule.py b/ovm/scripts/vm/hypervisor/ovm/OvmCommonModule.py
index 7eb2454239e..511d8d30a53 100755
--- a/ovm/scripts/vm/hypervisor/ovm/OvmCommonModule.py
+++ b/ovm/scripts/vm/hypervisor/ovm/OvmCommonModule.py
@@ -18,12 +18,14 @@ from xmlrpclib import Fault as XmlRpcFault
from OVSCommons import *
from OvmLoggerModule import OvmLogger
from OVSXXenStore import xen_get_vm_path
+from OVSSiteRMServer import get_master_ip
HEARTBEAT_TIMESTAMP_FORMAT='%s'
HEARTBEAT_TIMESTAMP_PATTERN='(\\d+.\d+<\/timestamp\>)'
HEARTBEAT_DIR='heart_beat'
ETC_HOSTS='/etc/hosts'
HOSTNAME_FILE='/etc/sysconfig/network'
+OWNER_FILE_PREFIX='host_'
logger = OvmLogger('OvmCommon')
@@ -124,4 +126,9 @@ def getVmNameFromConfigureFile(cfgPath):
return value
fd.close()
raise Exception('Cannot find vm name in %s'%cfgPath)
+
+def makeOwnerFileName():
+ hostIp = successToMap(get_master_ip())['ip']
+ ownerFileName = OWNER_FILE_PREFIX + hostIp.replace('.', '_')
+ return ownerFileName
diff --git a/ovm/scripts/vm/hypervisor/ovm/OvmHostModule.py b/ovm/scripts/vm/hypervisor/ovm/OvmHostModule.py
index 983c50593f1..29a9f9ae393 100755
--- a/ovm/scripts/vm/hypervisor/ovm/OvmHostModule.py
+++ b/ovm/scripts/vm/hypervisor/ovm/OvmHostModule.py
@@ -176,6 +176,26 @@ class OvmHost(OvmObject):
@staticmethod
def getAllVms():
+ def scanStoppedVmOnPrimaryStorage(vms):
+ def isMyVmDirLink(path):
+ return (islink(path) and exists(join(path, 'vm.cfg')) and ('-' in basename(path)) and (exists(join(path, makeOwnerFileName()))))
+
+ mps = OvmStoragePool()._getAllMountPoints()
+ for mountPoint in mps:
+ runningPool = join(mountPoint, 'running_pool')
+ for dir in os.listdir(runningPool):
+ vmDir = join(runningPool, dir)
+ if not isMyVmDirLink(vmDir):
+ logger.debug(OvmHost.getAllVms, "%s is not our vm directory, skip it"%vmDir)
+ continue
+ if vms.has_key(dir):
+ logger.debug(OvmHost.getAllVms, "%s is already in running list, skip it"%dir)
+ continue
+
+ logger.debug(OvmHost.getAllVms, "Found a stopped vm %s on primary storage %s, report it to management server" % (dir, mountPoint))
+ vms[dir] = "DOWN"
+
+
try:
l = OvmHost()._getAllDomains()
dct = {}
@@ -184,6 +204,8 @@ class OvmHost(OvmObject):
vmPath = host._getVmPathFromPrimaryStorage(name)
vmStatus = db_get_vm(vmPath)
dct[name] = vmStatus['status']
+
+ scanStoppedVmOnPrimaryStorage(dct)
rs = toGson(dct)
logger.info(OvmHost.getAllVms, rs)
return rs
diff --git a/ovm/scripts/vm/hypervisor/ovm/OvmVmModule.py b/ovm/scripts/vm/hypervisor/ovm/OvmVmModule.py
index a804d9ccb48..b16c69fa809 100755
--- a/ovm/scripts/vm/hypervisor/ovm/OvmVmModule.py
+++ b/ovm/scripts/vm/hypervisor/ovm/OvmVmModule.py
@@ -16,7 +16,7 @@ from OVSXXenStore import xen_get_vm_path, xen_get_vnc_port
from OVSDB import db_get_vm
from OVSXMonitor import xen_get_vm_perf_metrics, xen_get_xm_info
from OVSXXenVM import xen_migrate_vm
-from OVSSiteRMVM import unregister_vm, register_vm
+from OVSSiteRMVM import unregister_vm, register_vm, set_vm_status
from OVSSiteVMInstall import install_vm_hvm
from OVSSiteRMServer import get_master_ip
from OVSXXenVMInstall import xen_change_vm_cdrom
@@ -115,6 +115,23 @@ class OvmVm(OvmObject):
vmType = successToMap(xen_get_vm_type(vmPath))['type']
return vmType.replace('hvm', 'HVM').replace('para', 'PV')
+ def _tapAOwnerFile(self, vmPath):
+ # Create a file with name convention 'host_ip_address' in vmPath
+ # Because xm list doesn't return vm that has been stopped, we scan
+ # primary storage for stopped vm. This file tells us which host it belongs
+ # to. The file is used in OvmHost.getAllVms()
+ self._cleanUpOwnerFile(vmPath)
+ ownerFileName = makeOwnerFileName()
+ fd = open(join(vmPath, ownerFileName), 'w')
+ fd.write(ownerFileName)
+ fd.close()
+
+ def _cleanUpOwnerFile(self, vmPath):
+ for f in os.listdir(vmPath):
+ fp = join(vmPath, f)
+ if isfile(fp) and f.startswith(OWNER_FILE_PREFIX):
+ os.remove(join(vmPath, fp))
+
@staticmethod
def create(jsonString):
def dumpCfg(vmName, cfgPath):
@@ -256,6 +273,9 @@ class OvmVm(OvmObject):
vmNameFile.write(vm.name)
vmNameFile.close()
+ OvmVm()._tapAOwnerFile(rootDiskDir)
+ # set the VM to DOWN before starting, OVS agent will check this status
+ set_vm_status(vmPath, 'DOWN')
if vm.bootDev == "HDD":
return hddBoot(vm, vmPath)
elif vm.bootDev == "CD":
@@ -279,6 +299,8 @@ class OvmVm(OvmObject):
logger.info(OvmVm.stop, "Stop vm %s"%vmName)
vmPath = OvmHost()._vmNameToPath(vmName)
+ # set the VM to DOWN before starting, OVS agent will check this status
+ set_vm_status(vmPath, 'RUNNING')
raiseExceptionIfFail(stop_vm(vmPath))
return SUCC()
except Exception, e:
@@ -429,6 +451,7 @@ class OvmVm(OvmObject):
vmPath = OvmHost()._vmNameToPath(vmName)
raiseExceptionIfFail(xen_migrate_vm(vmPath, targetHost))
unregister_vm(vmPath)
+ OvmVm()._cleanUpOwnerFile(vmPath)
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
@@ -440,6 +463,7 @@ class OvmVm(OvmObject):
try:
vmPath = OvmHost()._vmNameToPath(vmName)
raiseExceptionIfFail(register_vm(vmPath))
+ OvmVm()._tapAOwnerFile(vmPath)
vncPort= successToMap(xen_get_vnc_port(vmName))['vnc_port']
rs = toGson({"vncPort":str(vncPort)})
logger.debug(OvmVm.register, rs)