blob: fd1122f07ad327b9765b742b46c81f8ec3f722eb [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.kvm.resource;
import java.io.File;
import org.apache.log4j.Logger;
import org.libvirt.LibvirtException;
import org.libvirt.StoragePool;
import org.libvirt.StoragePoolInfo;
import org.libvirt.StoragePoolInfo.StoragePoolState;
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.OutputInterpreter.AllLinesParser;
import com.cloud.utils.script.Script;
public class KVMHABase {
private static final Logger s_logger = Logger.getLogger(KVMHABase.class);
private long _timeout = 60000; /* 1 minutes */
protected static String s_heartBeatPath;
protected long _heartBeatUpdateTimeout = 60000;
protected long _heartBeatUpdateFreq = 60000;
protected long _heartBeatUpdateMaxTries = 5;
protected long _heartBeatUpdateRetrySleep = 10000;
public static enum PoolType {
PrimaryStorage, SecondaryStorage
}
public static class NfsStoragePool {
String _poolUUID;
String _poolIp;
String _poolMountSourcePath;
String _mountDestPath;
PoolType _type;
public NfsStoragePool(String poolUUID, String poolIp, String poolSourcePath, String mountDestPath, PoolType type) {
_poolUUID = poolUUID;
_poolIp = poolIp;
_poolMountSourcePath = poolSourcePath;
_mountDestPath = mountDestPath;
_type = type;
}
}
protected String checkingMountPoint(NfsStoragePool pool, String poolName) {
String mountSource = pool._poolIp + ":" + pool._poolMountSourcePath;
String mountPaths = Script.runSimpleBashScript("cat /proc/mounts | grep " + mountSource);
String destPath = pool._mountDestPath;
if (mountPaths != null) {
String token[] = mountPaths.split(" ");
String mountType = token[2];
String mountDestPath = token[1];
if (mountType.equalsIgnoreCase("nfs")) {
if (poolName != null && !mountDestPath.startsWith(destPath)) {
/* we need to mount it under poolName */
Script mount = new Script("/bin/bash", 60000);
mount.add("-c");
mount.add("mount " + mountSource + " " + destPath);
String result = mount.execute();
if (result != null) {
destPath = null;
}
destroyVMs(destPath);
} else if (poolName == null) {
destPath = mountDestPath;
}
}
} else {
/* Can't find the mount point? */
/* we need to mount it under poolName */
if (poolName != null) {
Script mount = new Script("/bin/bash", 60000);
mount.add("-c");
mount.add("mount " + mountSource + " " + destPath);
String result = mount.execute();
if (result != null) {
destPath = null;
}
destroyVMs(destPath);
}
}
return destPath;
}
protected String getMountPoint(NfsStoragePool storagePool) {
StoragePool pool = null;
String poolName = null;
try {
pool = LibvirtConnection.getConnection().storagePoolLookupByUUIDString(storagePool._poolUUID);
if (pool != null) {
StoragePoolInfo spi = pool.getInfo();
if (spi.state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) {
pool.create(0);
} else {
/*
* Sometimes, the mount point is lost, even libvirt thinks
* the storage pool still running
*/
}
poolName = pool.getName();
}
} catch (LibvirtException e) {
s_logger.debug("Ignoring libvirt error.", e);
} finally {
try {
if (pool != null) {
pool.free();
}
} catch (LibvirtException e) {
s_logger.debug("Ignoring libvirt error.", e);
}
}
return checkingMountPoint(storagePool, poolName);
}
protected void destroyVMs(String mountPath) {
/* if there are VMs using disks under this mount path, destroy them */
Script cmd = new Script("/bin/bash", _timeout);
cmd.add("-c");
cmd.add("ps axu|grep qemu|grep " + mountPath + "* |awk '{print $2}'");
AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = cmd.execute(parser);
if (result != null) {
return;
}
String pids[] = parser.getLines().split("\n");
for (String pid : pids) {
Script.runSimpleBashScript("kill -9 " + pid);
}
}
protected String getHBFile(String mountPoint, String hostIP) {
return mountPoint + File.separator + "KVMHA" + File.separator + "hb-" + hostIP;
}
protected String getHBFolder(String mountPoint) {
return mountPoint + File.separator + "KVMHA" + File.separator;
}
protected String runScriptRetry(String cmdString, OutputInterpreter interpreter) {
String result = null;
for (int i = 0; i < 3; i++) {
Script cmd = new Script("/bin/bash", _timeout);
cmd.add("-c");
cmd.add(cmdString);
if (interpreter != null)
result = cmd.execute(interpreter);
else {
result = cmd.execute();
}
if (result == Script.ERR_TIMEOUT) {
continue;
} else if (result == null) {
break;
}
}
return result;
}
public Boolean checkingHeartBeat() {
// TODO Auto-generated method stub
return null;
}
}