[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[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