Virtio Devices Patch

Eric Shubert <[email protected]> Thu, 18 Apr 2013 13:29:03 -0700
Newsgroups gmane.comp.security.ipcop.devel
Organization Eric Shubert & Associates
Message-ID <[email protected]>
A fellow developer (Justin H) and I have successfully built the latest 
(7001) IPCop with support for Virtio (paravirtualized KVM) disk and 
network devices. These drivers are part of the kernel, and provide 
significant performance improvements for IPCop virtual hosts running 
under Linux KVM.

The svn diff patch file is attached. It's fairly simple. The code is 
replicated and tailored from existing IPCop code, and existing code is 
pretty much untouched.

I've tested the installation process, and it's working well. Unit 
testing has also been completed with promising results. I'll be 
installing and testing in a live environment in the next week or so.

I realize that some people aren't keen on running IPCop as a VM, but I 
think that's a personal judgment. For those of us choosing to do so, 
having the option to use virtio devices with IPCop is very desirable. 
While IPCop developers should rightly take pride in providing support 
for a wide array of devices, I think that virtual devices should not 
necessarily be excluded.

I might add that, while PFSense provides the ability to use virtio 
devices, the installation and configuration of them in PFSense is a 
little convoluted. With the attached patches, IPCop can be installed 
directly with virtio disk and network devices, all of which are 
automatically recognized by the installer. This gives IPCop somewhat of 
a leg up on the competition regarding installation as a VM. ;)

So my question is, what are the chances of getting these patches applied 
to the mainstream IPCop? Let me know what I might do to facilitate the 
process.

Thanks to everyone for all of their great work on IPCop!

-- 
-Eric 'shubes'

------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter

_______________________________________________
IPCop-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ipcop-devel
ipcop-virtio-7001.patch (text/x-patch, 7.5 KB)
Index: lfs/initramfs
===================================================================
--- lfs/initramfs	(revision 7001)
+++ lfs/initramfs	(working copy)
@@ -255,6 +255,10 @@
 	# a few of them are not needed there as configuration is later than initramfs/install
 	rm -rf $(INITRAMFS_DIR)/lib/modules/$(KVER)/kernel/drivers/net/{bonding,bsd_comp.ko.gz,ppp*,tun.ko,usb,wireless}
 
+	# Copy the VIRTIO modules
+	cp -af /lib/modules/$(KVER)/kernel/drivers/virtio       $(INITRAMFS_DIR)/lib/modules/$(KVER)/kernel/drivers
+	cp -af /lib/modules/$(KVER)/kernel/drivers/block        $(INITRAMFS_DIR)/lib/modules/$(KVER)/kernel/drivers
+
 	# Copy some additional modules and remove those not required by nics and blocks drivers
 	cp -af /lib/modules/$(KVER)/kernel/lib 			$(INITRAMFS_DIR)/lib/modules/$(KVER)/kernel
 	rm -f $(INITRAMFS_DIR)/lib/modules/$(KVER)/kernel/lib/{crc-itu-t,ts_*}.ko.gz
Index: config/kernel/kernel.config.i486
===================================================================
--- config/kernel/kernel.config.i486	(revision 7001)
+++ config/kernel/kernel.config.i486	(working copy)
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux/i386 3.0-1 Kernel Configuration
+# Linux/i386 3.0.0 Kernel Configuration
 #
 # CONFIG_64BIT is not set
 CONFIG_X86_32=y
@@ -1001,6 +1001,7 @@
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+CONFIG_VIRTIO_BLK=m
 # CONFIG_BLK_DEV_HD is not set
 # CONFIG_BLK_DEV_RBD is not set
 # CONFIG_SENSORS_LIS3LV02D is not set
@@ -1013,6 +1014,7 @@
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_CS5535_MFGPT is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_APDS9802ALS is not set
 # CONFIG_ISL29003 is not set
@@ -1801,6 +1803,7 @@
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+CONFIG_VIRTIO_NET=m
 # CONFIG_VMXNET3 is not set
 CONFIG_ISDN=y
 CONFIG_ISDN_I4L=m
@@ -2068,6 +2071,7 @@
 # CONFIG_SERIAL_XILINX_PS_UART is not set
 # CONFIG_PRINTER is not set
 CONFIG_PPDEV=m
+# CONFIG_VIRTIO_CONSOLE is not set
 CONFIG_IPMI_HANDLER=m
 CONFIG_IPMI_PANIC_EVENT=y
 # CONFIG_IPMI_PANIC_STRING is not set
@@ -2081,6 +2085,7 @@
 CONFIG_HW_RANDOM_AMD=m
 CONFIG_HW_RANDOM_GEODE=m
 CONFIG_HW_RANDOM_VIA=m
+# CONFIG_HW_RANDOM_VIRTIO is not set
 # CONFIG_NVRAM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -3076,7 +3081,14 @@
 CONFIG_CRYPTO_DEV_HIFN_795X=m
 CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
 CONFIG_HAVE_KVM=y
-# CONFIG_VIRTUALIZATION is not set
+CONFIG_VIRTUALIZATION=y
+# CONFIG_KVM is not set
+# CONFIG_VHOST_NET is not set
+# CONFIG_LGUEST is not set
+CONFIG_VIRTIO=m
+CONFIG_VIRTIO_RING=m
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
 # CONFIG_BINARY_PRINTF is not set
 
 #
Index: src/installer/partition.c
===================================================================
--- src/installer/partition.c	(revision 7001)
+++ src/installer/partition.c	(working copy)
@@ -622,6 +622,8 @@
     /* TODO be more specific which modules to include */
     fprintf(handle, "ext3\njbd\n");
     fprintf(handle, "ehci-hcd\nohci-hcd\nuhci-hcd\nhid\nusbhid\n");
+    // include virtio so se can boot from a virtio disk.
+    fprintf(handle, "virtio\nvirtio_pci\nvirtio_blk\n");
 
     //add each module to module-list
     for (i = 0; i < numhardwares; i++) {
Index: src/installer/networking.c
===================================================================
--- src/installer/networking.c	(revision 7001)
+++ src/installer/networking.c	(working copy)
@@ -327,6 +327,14 @@
                 }
 
                 /* Check for Vendor / Device ID first */
+                    /* shubes: WARNING - virtio network devices point to the subsystem_deviceid
+                       value when retrieving them from the /sys/class/net/<device> branch.
+                       This is due to the way that symlinks are set up for virtio_net devices.
+                       I don't know why that is.
+                       This means that the checks below will not match, as we store
+                       the primary deviceid (0x1000), not the subsystem_deviceid (0x0001)
+                       for virtio_net devices (vendor 0x1af4).
+                    */
                 getkernelmodule(device);
                 if ((strlen(vendorid_buffer) > 0) && (strlen(deviceid_buffer) > 0)) {
                     for (n = 0; !found && (n < numnetwork); n++) {
Index: src/installer/hardware.c
===================================================================
--- src/installer/hardware.c	(revision 7001)
+++ src/installer/hardware.c	(working copy)
@@ -315,6 +315,35 @@
         fclose(f);
     }
 
+
+    /* Look for VIRTIO devices */
+    for (deviceletter = 'a'; deviceletter <= 'z'; deviceletter++) {
+
+        char device[4];
+        sprintf(device, "vd%c", deviceletter);
+        snprintf(model, STRING_SIZE, "Virtio disk");
+        char description[STRING_SIZE] = "Unknown";
+
+        unsigned long drivesize;
+        snprintf(procname, STRING_SIZE, "/sys/block/%s/size", device);
+        drivesize = getdrivesize(procname, strsize);
+        if (drivesize > 0) {
+            snprintf(description, STRING_SIZE, "%-30.30s (%s)", model, strsize);
+            if (drivesize < 32) {
+                /* Discard if too small for installation and too small as target drive */
+                snprintf(logline, STRING_SIZE, "   discard vd%c %-30.30s (%s)\n", deviceletter, model, strsize);
+                fprintf(flog, "%s", logline);
+                fprintf(fhwdetect, "%s", logline);
+            }
+            else if (drivesize < DISK_MINIMUM)
+                /* Too small as target drive but could be installation USB stick */
+                hardwareadd(cdrom, NULL, device, NULL, description, 0, 0);
+            else
+                hardwareadd(harddisk, NULL, device, NULL, description, 0, 0);
+        }
+    }
+
+
     /* Look for SCSI, SATA, USB cdrom */
     for (deviceletter = '0'; deviceletter <= '9'; deviceletter++) {
         snprintf(procname, STRING_SIZE, "/sys/block/sr%c/device/model", deviceletter);
@@ -524,11 +553,23 @@
                 }
             }
             else {
-                /* There is little to add if there is no module */
-                snprintf(logline, STRING_SIZE, "  Skip (no module) %04x %04x:%04x\n",
-                        pcidev->device_class, pcidev->vendor_id, pcidev->device_id);
-                fprintf(flog, "%s", logline);
-                fprintf(fhwdetect, "%s", logline);
+                if ((type == network) && (pcidev->vendor_id == 0x1af4) && (pcidev->device_id == 0x1000)) {
+                    /* virtio_net device */
+                    snprintf(logline, STRING_SIZE, "  Add  %04x %04x:%04x, %s\n",
+                            pcidev->device_class, pcidev->vendor_id, pcidev->device_id, description);
+                    fprintf(flog, "%s", logline);
+                    fprintf(fhwdetect, "%s", logline);
+
+                    module = "virtio_net";
+                    hardwareadd(type, module, NULL, NULL, description, pcidev->vendor_id, pcidev->device_id);
+                }
+                else {
+                    /* There is little to add if there is no module */
+                    snprintf(logline, STRING_SIZE, "  Skip (no module) %04x %04x:%04x\n",
+                             pcidev->device_class, pcidev->vendor_id, pcidev->device_id);
+                    fprintf(flog, "%s", logline);
+                    fprintf(fhwdetect, "%s", logline);
+                }
             }
         }