blob: a2e01292d09ffd7df130af051f8d2ef6122a2172 [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 org.apache.cloudstack.storage.datastore.util;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import com.cloud.utils.UuidUtils;
import com.cloud.utils.script.Script;
import org.apache.commons.lang3.StringUtils;
public class ScaleIOUtil {
protected static Logger LOGGER = LogManager.getLogger(ScaleIOUtil.class);
public static final String PROVIDER_NAME = "PowerFlex";
// Use prefix for CloudStack resources
public static final String VOLUME_PREFIX = "vol";
public static final String TEMPLATE_PREFIX = "tmpl";
public static final String SNAPSHOT_PREFIX = "snap";
public static final String VMSNAPSHOT_PREFIX = "vmsnap";
public static final int IDENTIFIER_LENGTH = 16;
public static final Long MINIMUM_ALLOWED_IOPS_LIMIT = Long.valueOf(10);
public static final String DISK_PATH = "/dev/disk/by-id";
public static final String DISK_NAME_PREFIX = "emc-vol-";
public static final String DISK_NAME_PREFIX_FILTER = DISK_NAME_PREFIX + "*-";
private static final String AGENT_PROPERTIES_FILE = "/etc/cloudstack/agent/agent.properties";
private static final String DEFAULT_SDC_HOME_PATH = "/opt/emc/scaleio/sdc";
private static final String SDC_HOME_PARAMETER = "powerflex.sdc.home.dir";
private static final String SDC_HOME_PATH = getSdcHomePath();
private static final String RESCAN_CMD = "drv_cfg --rescan";
/**
* Cmd for querying volumes in SDC
* Sample output for cmd: drv_cfg --query_vols:
* Retrieved 2 volume(s)
* VOL-ID 6c33633100000009 MDM-ID 218ce1797566a00f
* VOL-ID 6c3362a30000000a MDM-ID 218ce1797566a00f
*/
private static final String QUERY_VOLUMES_CMD = "drv_cfg --query_vols";
/**
* Cmd for querying guid in SDC
* Sample output for cmd: drv_cfg --query_guid:
* B0E3BFB8-C20B-43BF-93C8-13339E85AA50
*/
private static final String QUERY_GUID_CMD = "drv_cfg --query_guid";
/**
* Cmd for querying MDMs in SDC
* Sample output for cmd: drv_cfg --query_mdms:
* Retrieved 2 mdm(s)
* MDM-ID 3ef46cbf2aaf5d0f SDC ID 6b18479c00000003 INSTALLATION ID 68ab55462cbb3ae4 IPs [0]-x.x.x.x [1]-x.x.x.x
* MDM-ID 2e706b2740ec200f SDC ID 301b852c00000003 INSTALLATION ID 33f8662e7a5c1e6c IPs [0]-x.x.x.x [1]-x.x.x.x
*/
private static final String QUERY_MDMS_CMD = "drv_cfg --query_mdms";
public static String getSdcHomePath() {
String sdcHomePath = DEFAULT_SDC_HOME_PATH;
String sdcHomePropertyCmdFormat = "sed -n '/%s/p' '%s' 2>/dev/null | sed 's/%s=//g' 2>/dev/null";
String sdcHomeCmd = String.format(sdcHomePropertyCmdFormat, SDC_HOME_PARAMETER, AGENT_PROPERTIES_FILE, SDC_HOME_PARAMETER);
String result = Script.runSimpleBashScript(sdcHomeCmd);
if (result == null) {
LOGGER.warn("Failed to get sdc home path from agent.properties, fallback to default path");
} else {
sdcHomePath = result;
}
return sdcHomePath;
}
public static final void rescanForNewVolumes() {
// Detecting new volumes
String rescanCmd = ScaleIOUtil.SDC_HOME_PATH + "/bin/" + ScaleIOUtil.RESCAN_CMD;
String result = Script.runSimpleBashScript(rescanCmd);
if (result == null) {
LOGGER.warn("Failed to rescan for new volumes");
}
}
public static final String getSystemIdForVolume(String volumeId) {
//query_vols outputs "VOL-ID <VolumeID> MDM-ID <SystemID>" for a volume with ID: <VolumeID>
String queryDiskCmd = SDC_HOME_PATH + "/bin/" + ScaleIOUtil.QUERY_VOLUMES_CMD;
queryDiskCmd += "|grep " + volumeId + "|awk '{print $4}'";
String result = Script.runSimpleBashScript(queryDiskCmd);
if (result == null) {
LOGGER.warn("Query volumes failed to get volume: " + volumeId + " details for system id");
return null;
}
if (result.isEmpty()) {
LOGGER.warn("Query volumes doesn't list volume: " + volumeId + ", probably volume is not mapped yet, or sdc not connected");
return null;
}
return result;
}
public static String getSdcGuid() {
String queryGuidCmd = ScaleIOUtil.SDC_HOME_PATH + "/bin/" + ScaleIOUtil.QUERY_GUID_CMD;
String result = Script.runSimpleBashScript(queryGuidCmd);
if (result == null) {
LOGGER.warn("Failed to get SDC guid");
return null;
}
if (result.isEmpty()) {
LOGGER.warn("No SDC guid retrieved");
return null;
}
if (!UuidUtils.isUuid(result)) {
LOGGER.warn("Invalid SDC guid: " + result);
return null;
}
return result;
}
public static String getSdcId(String mdmId) {
//query_mdms outputs "MDM-ID <System/MDM-Id> SDC ID <SDC-Id> INSTALLATION ID <Installation-Id> IPs [0]-x.x.x.x [1]-x.x.x.x" for a MDM with ID: <MDM-Id>
String queryMdmsCmd = ScaleIOUtil.SDC_HOME_PATH + "/bin/" + ScaleIOUtil.QUERY_MDMS_CMD;
queryMdmsCmd += "|grep " + mdmId + "|awk '{print $5}'";
String result = Script.runSimpleBashScript(queryMdmsCmd);
if (result == null) {
LOGGER.warn("Failed to get SDC Id, for the MDM: " + mdmId);
return null;
}
if (result.isEmpty()) {
LOGGER.warn("No SDC Id retrieved, for the MDM: " + mdmId);
return null;
}
String sdcIdRegEx = "^[0-9a-fA-F]{16}$";
if (!result.matches(sdcIdRegEx)) {
LOGGER.warn("Invalid SDC Id: " + result + " retrieved, for the MDM: " + mdmId);
return null;
}
return result;
}
public static final String getVolumePath(String volumePathWithName) {
if (StringUtils.isEmpty(volumePathWithName)) {
return volumePathWithName;
}
if (volumePathWithName.contains(":")) {
return volumePathWithName.substring(0, volumePathWithName.indexOf(':'));
}
return volumePathWithName;
}
public static final String updatedPathWithVolumeName(String volumePath, String volumeName) {
if (StringUtils.isAnyEmpty(volumePath, volumeName)) {
return volumePath;
}
return String.format("%s:%s", volumePath, volumeName);
}
}