mirror of https://github.com/apache/cloudstack.git
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:
parent
a04f436147
commit
d6cbd2b6bc
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = ''
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue