bug 11275:

remove heartbeat entry for this Primary Storage, when put this Primary Storage into maintenance mode
create heartbeat entry for this Primary Storage, when cancal maintenance for this Primary Storage

status 11275: resolved fixed
This commit is contained in:
anthony 2011-09-13 22:07:54 -07:00
parent a04f436147
commit d6cbd2b6bc
6 changed files with 152 additions and 60 deletions

View File

@ -4551,7 +4551,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return callHostPlugin(conn, "vmopspremium", cmd, params);
}
protected String setupHeartbeatSr(Connection conn, SR sr, boolean force) throws XenAPIException, XmlRpcException {
SR.Record srRec = sr.getRecord(conn);
String srUuid = srRec.uuid;
@ -4584,7 +4583,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
host.setTags(conn, tags);
}
}
result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid);
result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid, "add", "true");
if (result == null || !result.split("#")[1].equals("0")) {
throw new CloudRuntimeException("Unable to setup heartbeat file entry on SR " + srUuid + " due to "
+ result);
@ -4595,27 +4594,49 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
protected Answer execute(ModifyStoragePoolCommand cmd) {
Connection conn = getConnection();
StorageFilerTO pool = cmd.getPool();
try {
SR sr = getStorageRepository(conn, pool);
setupHeartbeatSr(conn, sr, false);
long capacity = sr.getPhysicalSize(conn);
long available = capacity - sr.getPhysicalUtilisation(conn);
if (capacity == -1) {
String msg = "Pool capacity is -1! pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg);
boolean add = cmd.getAdd();
if( add ) {
try {
SR sr = getStorageRepository(conn, pool);
setupHeartbeatSr(conn, sr, false);
long capacity = sr.getPhysicalSize(conn);
long available = capacity - sr.getPhysicalUtilisation(conn);
if (capacity == -1) {
String msg = "Pool capacity is -1! pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg);
return new Answer(cmd, false, msg);
}
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
return answer;
} catch (XenAPIException e) {
String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.toString() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg, e);
return new Answer(cmd, false, msg);
} catch (Exception e) {
String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.getMessage() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg, e);
return new Answer(cmd, false, msg);
}
} else {
try {
SR sr = getStorageRepository(conn, pool);
String srUuid = sr.getUuid(conn);
String result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid, "add", "false");
if (result == null || !result.split("#")[1].equals("0")) {
throw new CloudRuntimeException("Unable to remove heartbeat file entry for SR " + srUuid + " due to "
+ result);
}
return new Answer(cmd, true , "seccuss");
} catch (XenAPIException e) {
String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.toString() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg, e);
return new Answer(cmd, false, msg);
} catch (Exception e) {
String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.getMessage() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg, e);
return new Answer(cmd, false, msg);
}
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
return answer;
} catch (XenAPIException e) {
String msg = "ModifyStoragePoolCommand XenAPIException:" + e.toString() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg, e);
return new Answer(cmd, false, msg);
} catch (Exception e) {
String msg = "ModifyStoragePoolCommand XenAPIException:" + e.getMessage() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath();
s_logger.warn(msg, e);
return new Answer(cmd, false, msg);
}
}

View File

@ -4,7 +4,7 @@
#set -x
usage() {
printf "Usage: %s [uuid of this host] [uuid of the sr to place the heartbeat]\n" $(basename $0)
printf "Usage: %s [uuid of this host] [uuid of the sr to place the heartbeat] [ add , true/false]\n" $(basename $0)
}
@ -21,6 +21,13 @@ if [ -z $2 ]; then
exit 0
fi
if [ -z $3 ]; then
usage
echo "#21# no add parameter"
exit 0
fi
if [ `xe host-list | grep $1 | wc -l` -ne 1 ]; then
echo "#3# Unable to find the host uuid: $1"
exit 0
@ -36,38 +43,47 @@ if [ `xe pbd-list sr-uuid=$2 | grep -B 1 $1 | wc -l` -eq 0 ]; then
exit 0
fi
srtype=`xe sr-param-get param-name=type uuid=$2`
if [ "$srtype" = "nfs" ];then
dir=/var/run/sr-mount/$2
filename=$dir/hb-$1
if [ ! -f "$filename" ]; then
echo "#6# heartbeat file $filename doesn't exist"
exit 0
fi
else
dir=/dev/VG_XenStorage-$2
link=$dir/hb-$1
lvchange -ay $link
if [ $? -ne 0 ]; then
echo "#7# Unable to make the heartbeat $link active"
exit 0
fi
fi
hbfile=/opt/xensource/bin/heartbeat
if [ -f $hbfile ]; then
grep $dir $hbfile >/dev/null
if [ $? -gt 0 ]
then
if [ "$3" = "true" ]; then
srtype=`xe sr-param-get param-name=type uuid=$2`
if [ "$srtype" = "nfs" ];then
dir=/var/run/sr-mount/$2
filename=$dir/hb-$1
if [ ! -f "$filename" ]; then
echo "#6# heartbeat file $filename doesn't exist"
exit 0
fi
else
dir=/dev/VG_XenStorage-$2
link=$dir/hb-$1
lvchange -ay $link
if [ $? -ne 0 ]; then
echo "#7# Unable to make the heartbeat $link active"
exit 0
fi
fi
if [ -f $hbfile ]; then
grep $dir $hbfile >/dev/null
if [ $? -gt 0 ]
then
echo $dir >> $hbfile
fi
else
echo $dir >> $hbfile
fi
else
echo $dir >> $hbfile
else
if [ -f $hbfile ]; then
sed -i /$2/d $hbfile
fi
fi
echo "#0#DONE"
exit 0

View File

@ -89,8 +89,9 @@ def setup_heartbeat_sr(session, args):
def setup_heartbeat_file(session, args):
host = args['host']
sr = args['sr']
add = args['add']
try:
cmd = ["bash", "/opt/xensource/bin/setup_heartbeat_file.sh", host, sr]
cmd = ["bash", "/opt/xensource/bin/setup_heartbeat_file.sh", host, sr, add]
txt = util.pread2(cmd)
except:
txt = ''

View File

@ -176,5 +176,7 @@ public interface HostDao extends GenericDao<HostVO, Long> {
List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId);
List<HostVO> listByInAllStatus(Type type, Long clusterId, Long podId, long dcId);
List<HostVO> listByInAllStatus(Type type, Long clusterId, Long podId, long dcId);
List<HostVO> listByClusterStatus(long clusterId, Status status);
}

View File

@ -89,7 +89,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected final SearchBuilder<HostVO> UnmanagedDirectConnectSearch;
protected final SearchBuilder<HostVO> UnmanagedApplianceSearch;
protected final SearchBuilder<HostVO> MaintenanceCountSearch;
protected final SearchBuilder<HostVO> ClusterSearch;
protected final SearchBuilder<HostVO> ClusterStatusSearch;
protected final SearchBuilder<HostVO> ConsoleProxyHostSearch;
protected final SearchBuilder<HostVO> AvailHypevisorInZone;
@ -177,9 +177,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
DcSearch.and("dc", DcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
DcSearch.done();
ClusterSearch = createSearchBuilder();
ClusterSearch.and("cluster", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
ClusterSearch.done();
ClusterStatusSearch = createSearchBuilder();
ClusterStatusSearch.and("cluster", ClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
ClusterStatusSearch.and("status", ClusterStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ);
ClusterStatusSearch.done();
ConsoleProxyHostSearch = createSearchBuilder();
ConsoleProxyHostSearch.and("name", ConsoleProxyHostSearch.entity().getName(), SearchCriteria.Op.EQ);
@ -515,12 +516,24 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
@Override
public List<HostVO> listByCluster(long clusterId) {
SearchCriteria<HostVO> sc = ClusterSearch.create();
SearchCriteria<HostVO> sc = ClusterStatusSearch.create();
sc.setParameters("cluster", clusterId);
return listBy(sc);
}
@Override
public List<HostVO> listByClusterStatus(long clusterId, Status status) {
SearchCriteria<HostVO> sc = ClusterStatusSearch.create();
sc.setParameters("cluster", clusterId);
sc.setParameters("status", status.toString());
return listBy(sc);
}
@Override
public List<HostVO> listBy(Host.Type type, long dcId) {

View File

@ -2066,10 +2066,31 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" + primaryStorage.getStatus().toString());
}
// set the pool state to prepare for maintenance
primaryStorage.setStatus(StoragePoolStatus.PrepareForMaintenance);
_storagePoolDao.update(primaryStorageId, primaryStorage);
List<HostVO> hosts = _hostDao.listByClusterStatus(primaryStorage.getClusterId(), Status.Up);
if( hosts == null || hosts.size() == 0 ) {
primaryStorage.setStatus(StoragePoolStatus.Maintenance);
_storagePoolDao.update(primaryStorageId, primaryStorage);
return _storagePoolDao.findById(primaryStorageId);
} else {
// set the pool state to prepare for maintenance
primaryStorage.setStatus(StoragePoolStatus.PrepareForMaintenance);
_storagePoolDao.update(primaryStorageId, primaryStorage);
}
// remove heartbeat
for ( HostVO host : hosts ) {
ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(false, primaryStorage);
final Answer answer = _agentMgr.easySend(host.getId(), cmd);
if (answer == null || !answer.getResult()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("ModifyStoragePool false failed due to " + ((answer == null) ? "answer null" : answer.getDetails()));
}
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("ModifyStoragePool false secceeded");
}
}
}
// check to see if other ps exist
// if they do, then we can migrate over the system vms to them
// if they dont, then just stop all vms on this one
@ -2278,6 +2299,24 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
primaryStorage.setStatus(StoragePoolStatus.Up);
_storagePoolDao.update(primaryStorageId, primaryStorage);
txn.commit();
List<HostVO> hosts = _hostDao.listByClusterStatus(primaryStorage.getClusterId(), Status.Up);
if( hosts == null || hosts.size() == 0 ) {
return _storagePoolDao.findById(primaryStorageId);
}
// add heartbeat
for ( HostVO host : hosts ) {
ModifyStoragePoolCommand msPoolCmd = new ModifyStoragePoolCommand(true, primaryStorage);
final Answer answer = _agentMgr.easySend(host.getId(), msPoolCmd);
if (answer == null || !answer.getResult()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("ModifyStoragePool add failed due to " + ((answer == null) ? "answer null" : answer.getDetails()));
}
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("ModifyStoragePool add secceeded");
}
}
}
// 2. Get a list of pending work for this queue
List<StoragePoolWorkVO> pendingWork = _storagePoolWorkDao.listPendingWorkForCancelMaintenanceByPoolId(primaryStorageId);