| [aperi-dev] Patch for Aperi agent in XEN Virtual Machines |
Hi, The attached Eclipse patch implements support in the Aperi agent, for discovering paravirtualized block devices presented to guest Linux virtual machines via the XEN Hypervisor and XenBus. The code is Linux specific; brief summary of changes below: JavaNames.h - add JNI definition for ProbeXenDevice() ProbeLinux.c - add implementation of ProbeXenDevice() ProbeLinux.java - add implementation of findXenDisks() and call from platformSpecific() Controller.java - add XenBus controller to TYPES platformSpecific() now calls findXenDisks() in addition to findSCSIDisks(), findIDEDisks(), findVpaths() and findCompaqArrays() findXenDisks() inspects /sys/hypervisor/type and if contains "xen", then searches for XenBus presented virtual block devices (VBDs) in /sys/devices/xvd* findXenDisks() adds one instance of Controller to the model, and one instance of Device for each virtual disk attached to the (XenBus) Controller. Everything else works as for normal disks attached to a host; including capacity, disk partition and file system discovery. Attached also are a couple of screenshots showing the result of running the Aperi agent inside a Xen VM with four paravirtualized disks presented by the XenBus. As a committer I suppose I could commit this code, but since this is my first feature contribution, I wasn't sure of the process for code review and acceptance. The patch can be applied to head (there are no conflicts with current head file versions). In the future, it will be interesting to relate the view of storage resources that the guest has, with the VM host that is running the guest, and with SAN disks that have global identity regardless of which host is providing access at that moment (similar to what the code already does for HA clusters). But this will require changes to the model, and GUI, and is left for another day ... Comments welcome ;-) Thanks, Robert
### Eclipse Workspace Patch 1.0
#P org.eclipse.aperi.agent.data
Index: src/org/eclipse/aperi/agent/probe/ProbeLinux.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.aperi/org.eclipse.aperi.agent.data/src/org/eclipse/aperi/agent/probe/ProbeLinux.java,v
retrieving revision 1.2
diff -u -r1.2 ProbeLinux.java
--- src/org/eclipse/aperi/agent/probe/ProbeLinux.java 22 Mar 2007 23:34:06 -0000 1.2
+++ src/org/eclipse/aperi/agent/probe/ProbeLinux.java 6 Sep 2007 18:03:58 -0000
@@ -76,6 +76,9 @@
private native int probeIDEDevice(String path, Controller ctlr, int ID,
int deviceType);
+ private native int probeXenDevice(String path, Controller ctlr, int ID,
+ int deviceSize);
+
private native void probeDASD(Disk disk) throws LocalizableException;
private native int probeVpathDevice(String path, Controller ctlr, int ID);
@@ -748,6 +751,70 @@
/* end of loop over controllers */
}
+ private void findXenDisks() throws GeneralException
+ {
+ String hypervisorType = null;
+
+ try
+ {
+ Reader r = new FileReader("/sys/hypervisor/type");
+ BufferedReader br = new BufferedReader(r);
+ hypervisorType = br.readLine();
+ }
+ catch (IOException e)
+ {
+ }
+
+ if (hypervisorType == null)
+ {
+ return;
+ }
+ if (!hypervisorType.toLowerCase().equals("xen"))
+ {
+ return;
+ }
+
+ Controller ctlr = new Controller();
+ ctlr.ctlrNext = computer.cmpController;
+ computer.cmpController = ctlr;
+ ctlr.ctlrTarget = -1; /* meaningless for XENBUS */
+ ctlr.ctlrType = Controller.XENBUS;
+ ctlr.ctlrInstance = 0;
+ ctlr.ctlrDriverName = Controller.TYPES[Controller.XENBUS+1];
+ ctlr.ctlrDriverDescription = "XenBus Controller";
+
+ String[] dirEntries = new File("/sys/block").list();
+
+ if (dirEntries == null)
+ {
+ MessageLog.logMessage("STA0215I");
+ return;
+ }
+
+ int seqNo = 0;
+
+ for (int i = 0; i < dirEntries.length; i += 1)
+ {
+ if (!dirEntries[i].startsWith("xvd"))
+ continue;
+
+ int deviceSize = 0;
+
+ try
+ {
+ Reader r = new FileReader("/sys/block/" + dirEntries[i] + "/size");
+ BufferedReader br = new BufferedReader(r);
+ deviceSize = Integer.parseInt(br.readLine());
+ }
+ catch (IOException e)
+ {
+ }
+
+ probeXenDevice("/dev/" + dirEntries[i], ctlr, seqNo, deviceSize);
+ seqNo += 1;
+ }
+ }
+
private static String readLine(BufferedReader in, String fileName)
throws GeneralException
{
@@ -1749,6 +1816,7 @@
{
findSCSIDisks();
findIDEDisks();
+ findXenDisks();
findVpaths();
findCompaqArrays();
}
#P Aperi
Index: data/c/Common/JavaNames.h
===================================================================
RCS file: /cvsroot/technology/org.eclipse.aperi/Aperi/data/c/Common/JavaNames.h,v
retrieving revision 1.4
diff -u -r1.4 JavaNames.h
--- data/c/Common/JavaNames.h 9 Mar 2007 22:16:43 -0000 1.4
+++ data/c/Common/JavaNames.h 6 Sep 2007 18:03:59 -0000
@@ -570,6 +570,9 @@
#define JAVA_ORG_ECLIPSE_APERI_AGENT_PROBE_PROBELINUX_PROBEIDEDEVICE \
Java_org_eclipse_aperi_agent_probe_ProbeLinux_probeIDEDevice
+#define JAVA_ORG_ECLIPSE_APERI_AGENT_PROBE_PROBELINUX_PROBEXENDEVICE \
+ Java_org_eclipse_aperi_agent_probe_ProbeLinux_probeXenDevice
+
#define JAVA_ORG_ECLIPSE_APERI_AGENT_PROBE_PROBELINUX_PROBEVPATHDEVICE \
Java_org_eclipse_aperi_agent_probe_ProbeLinux_probeVpathDevice
Index: data/c/T-Storm/ProbeLinux.c
===================================================================
RCS file: /cvsroot/technology/org.eclipse.aperi/Aperi/data/c/T-Storm/ProbeLinux.c,v
retrieving revision 1.3
diff -u -r1.3 ProbeLinux.c
--- data/c/T-Storm/ProbeLinux.c 9 Mar 2007 22:15:13 -0000 1.3
+++ data/c/T-Storm/ProbeLinux.c 6 Sep 2007 18:03:59 -0000
@@ -1292,6 +1292,83 @@
return rc;
}
+/*
+ * Class: JAVA_ORG_ECLIPSE_APERI_AGENT_PROBE_ProbeLinux
+ * Method: probeXenDevice
+ * Signature: (Ljava/lang/String;Ljava_org_eclipse_aperi/TStorm/common/Controller;II)I
+ *
+ * Returns 0, 4, or 8.
+ */
+JNIEXPORT jint JNICALL
+JAVA_ORG_ECLIPSE_APERI_AGENT_PROBE_PROBELINUX_PROBEXENDEVICE
+ (JNIEnv *env, jobject self, jstring pPath, jobject pCtlr, int target,
+ int deviceSize)
+{
+ static const char functionName[] =
+ "JAVA_ORG_ECLIPSE_APERI_AGENT_PROBE_PROBELINUX_PROBEXENDEVICE";
+ int rc;
+ jobject computer;
+ const char *foo;
+ struct device devStruct;
+ struct controller ctlr;
+ unsigned int i;
+ int fd;
+ struct chunk *chunkList;
+/**/
+ TRC_ENTRY_MAX();
+ rc = 0;
+ computer = (*env)->GetObjectField(env, self, ProbeComputerField);
+ foo = GET_CHARS(env, pPath, NULL);
+ strcpy(devStruct.dvPath, foo);
+ RELEASE_CHARS(env, pPath, foo);
+ fd = open(devStruct.dvPath, O_RDONLY);
+ if(fd < 0)
+ {
+ /* IC42789 - Add tracing to failed open() call */
+ TRC_SI_MID ( "open() failed on device %s with errno = %d", devStruct.dvPath, errno );
+ MessageLogOSError(env, "STA0034W", devStruct.dvPath, NULL);
+ rc = 4;
+ TRC_EXIT_MAX();
+ return rc;
+ }
+ ctlr.ctSelf = pCtlr;
+ devStruct.dvController = &ctlr;
+ devStruct.dvType = DV_HARD_DISK;
+ devStruct.dvTarget = target;
+ devStruct.dvLUN = -1; /* not applicable to ATA */
+/*identifyIDE*/
+ devStruct.dvManufactureDate = 0;
+ devStruct.dvFlags = 0;
+ devStruct.dvMultiPort = 0;
+ devStruct.dvUnsupportedModel = 0;
+ memcpy(devStruct.dvManufacturer, "Xen", 4);
+ memcpy(devStruct.dvModel, "XVD", 4);
+ probeutilGenerateKey(env, &devStruct);
+ devStruct.dvFlags |= DV_GEN_SN;
+ devStruct.dvFirmwareRev[0] = ' ';
+ devStruct.dvFirmwareRev[1] = '\0';
+ devStruct.dvRemovableMedium = 0;
+ probeutilInvalidateDisk(&devStruct);
+ devStruct.dvSectorSize = 512; /* the structure is OBSOLETE */
+ devStruct.dvLogicalBlockSize = 512;
+ devStruct.dvSectorsPerAvgTrack = 63;
+ devStruct.dvHeads = 255;
+ devStruct.dvCylinders = deviceSize / (255 * 63);
+ devStruct.dvCapacity = deviceSize;
+/*identifyIDE*/
+ i = FindPartitions(env, &devStruct, &chunkList);
+ if(i != 0)
+ {
+ rc = i;
+ goto cleanup;
+ }
+ probeutilNewDevice(env, &devStruct, chunkList);
+cleanup:
+ close(fd);
+ TRC_EXIT_MAX();
+ return rc;
+}
+
#define UNKNOWN_LINE 0
#define PROCESSOR_LINE 1
#define VENDOR_LINE 2
#P org.eclipse.aperi.common
Index: src/org/eclipse/aperi/TStorm/common/Controller.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.aperi/org.eclipse.aperi.common/src/org/eclipse/aperi/TStorm/common/Controller.java,v
retrieving revision 1.2
diff -u -r1.2 Controller.java
--- src/org/eclipse/aperi/TStorm/common/Controller.java 16 Jan 2007 18:30:12 -0000 1.2
+++ src/org/eclipse/aperi/TStorm/common/Controller.java 6 Sep 2007 18:04:00 -0000
@@ -81,6 +81,7 @@
public static final short SSA = 11;
public static final short DASD = 12;
public static final short SQUADRON_AS = 13; /* Squadron Array Site */
+ public static final short XENBUS = 14; /* XenBus */
// reference via Controller.TYPES[ctlrType +1]
public static final String[] TYPES =
@@ -99,7 +100,8 @@
"VPATH",
"SSA",
"DASD",
- "Array Site" };
+ "Array Site",
+ "XenBus" };
/*
* Values for Array Site ctlrTarget
Attachment:
AperiXenBus.png
Description: Portable Network Graphics Format
Attachment:
AperiXenDisk.png
Description: Portable Network Graphics Format
Attachment:
AperiXenFs.png
Description: Portable Network Graphics Format