// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.agent.resource.computing;
import java.io.File;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.libvirt.Connect;
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 long _timeout = 60000; /* 1 minutes */
protected static String _heartBeatPath;
protected long _heartBeatUpdateTimeout = 60000;
protected long _heartBeatUpdateFreq = 60000;
protected long _heartBeatUpdateMaxRetry = 3;
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) {
this._poolUUID = poolUUID;
this._poolIp = poolIp;
this._poolMountSourcePath = poolSourcePath;
this._mountDestPath = mountDestPath;
this._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) {
} finally {
try {
if (pool != null) {
pool.free();
}
} catch (LibvirtException 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 static void main(String[] args) {
NfsStoragePool pool = new KVMHAMonitor.NfsStoragePool(null, null, null,
null, PoolType.PrimaryStorage);
KVMHAMonitor haWritter = new KVMHAMonitor(pool, "192.168.1.163", null);
Thread ha = new Thread(haWritter);
ha.start();
KVMHAChecker haChecker = new KVMHAChecker(haWritter.getStoragePools(),
"192.168.1.163");
ExecutorService exe = Executors.newFixedThreadPool(1);
Future<Boolean> future = exe.submit((Callable<Boolean>) haChecker);
try {
for (int i = 0; i < 10; i++) {
System.out.println(future.get());
future = exe.submit((Callable<Boolean>) haChecker);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}