Add monitor command to hot-add PCI devices (nic and drive).

Save QEMUMachine necessary for drive_init.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug/qemu/Makefile.target
===================================================================
--- kvm-userspace.hotplug.orig/qemu/Makefile.target
+++ kvm-userspace.hotplug/qemu/Makefile.target
@@ -576,6 +576,8 @@ OBJS+= hypercall.o
 # virtio devices
 OBJS += virtio.o virtio-net.o virtio-blk.o
 
+OBJS += device-hotplug.o
+
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
 OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
Index: kvm-userspace.hotplug/qemu/hw/device-hotplug.c
===================================================================
--- /dev/null
+++ kvm-userspace.hotplug/qemu/hw/device-hotplug.c
@@ -0,0 +1,92 @@
+#include "hw.h"
+#include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sysemu.h"
+#include "pc.h"
+#include "console.h"
+
+static PCIDevice *qemu_system_hot_add_nic(const char *opts, int bus_nr)
+{
+   int ret;
+   char buf[4096];
+   PCIBus *pci_bus;
+
+   pci_bus = pci_find_bus (bus_nr);
+   if (!pci_bus) {
+      term_printf ("Can't find pci_bus %d\n", bus_nr);
+      return NULL;
+   }
+
+   memset (buf, 0, sizeof (buf));
+
+   strcpy (buf, "nic,");
+   strncat (buf, opts, sizeof (buf) - strlen (buf) - 1);
+
+   ret = net_client_init (buf);
+   if (ret < 0 || !nd_table[ret].model)
+      return NULL;
+   return pci_nic_init (pci_bus, &nd_table[ret], -1);
+}
+
+static PCIDevice *qemu_system_hot_add_drive(const char *opts, int bus_nr)
+{
+    int drive_opt_idx, drive_idx;
+    int type = 0;
+    int bus = 0;
+    void *opaque = NULL;
+    PCIBus *pci_bus;
+
+    pci_bus = pci_find_bus(bus_nr);
+    if (!pci_bus) {
+        term_printf("Can't find pci_bus %d\n", bus_nr);
+        return NULL;
+    }
+
+    drive_opt_idx = drive_add(NULL, "%s", opts);
+    if (!drive_opt_idx)
+        return NULL;
+
+    drive_idx = drive_init(&drives_opt[drive_opt_idx], 0, current_machine);
+    if (drive_idx == -1) {
+        drive_remove(drive_opt_idx);
+        return NULL;
+    }
+
+    type = drives_table[drive_idx].type;
+    bus = drive_get_max_bus (type);
+
+    switch (type) {
+    case IF_SCSI:
+      /* XXX: additional unit on existing device? */
+      opaque = lsi_scsi_init (pci_bus, -1);
+      lsi_scsi_attach (opaque, drives_table[drive_idx].bdrv,
+                       drives_table[drive_idx].unit);
+      break;
+    case IF_VIRTIO:
+      opaque = virtio_blk_init (pci_bus, 0x1AF4, 0x1001,
+                                drives_table[drive_idx].bdrv);
+      break;
+    default:
+      term_printf ("type %d not a PCI device!\n", type);
+    }
+
+    return opaque;
+}
+
+void device_hot_add(const char *type, const char *opts)
+{
+    PCIDevice *dev = NULL;
+
+    if (strcmp(type, "nic") == 0)
+        dev = qemu_system_hot_add_nic(opts, 0);
+    else if (strcmp(type, "drive") == 0)
+        dev = qemu_system_hot_add_drive(opts, 0);
+    else
+        term_printf("invalid type: %s\n", type);
+
+    if (dev)
+        qemu_system_device_hot_add(PCI_SLOT(dev->devfn), 1);
+    else
+        term_printf("failed to add %s\n", opts);
+}
Index: kvm-userspace.hotplug/qemu/monitor.c
===================================================================
--- kvm-userspace.hotplug.orig/qemu/monitor.c
+++ kvm-userspace.hotplug/qemu/monitor.c
@@ -1354,6 +1354,7 @@ static term_cmd_t term_cmds[] = {
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
     { "cpu_set", "is", do_cpu_set_nr, "cpu [online|offline]", "change cpu 
state" },
+    { "pci_add", "ss", device_hot_add, "nic|drive 
[vlan=n][,macaddr=addr][,model=type] 
[[file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]]", "hotadd PCI 
device" },
     { NULL, NULL, },
 };
 
Index: kvm-userspace.hotplug/qemu/hw/boards.h
===================================================================
--- kvm-userspace.hotplug.orig/qemu/hw/boards.h
+++ kvm-userspace.hotplug/qemu/hw/boards.h
@@ -19,6 +19,8 @@ typedef struct QEMUMachine {
 
 int qemu_register_machine(QEMUMachine *m);
 
+extern QEMUMachine *current_machine;
+
 /* Axis ETRAX.  */
 extern QEMUMachine bareetraxfs_machine;
 
Index: kvm-userspace.hotplug/qemu/sysemu.h
===================================================================
--- kvm-userspace.hotplug.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug/qemu/sysemu.h
@@ -174,6 +174,10 @@ extern int drive_init(struct drive_opt *
 /* acpi */
 void qemu_system_cpu_hot_add(int cpu, int state);
 void qemu_system_hot_add_init(char *cpu_model);
+void qemu_system_device_hot_add(int slot, int state);
+
+/* device-hotplug */
+void device_hot_add(const char *type, const char *opts);
 
 /* vmchannel devices */
 
Index: kvm-userspace.hotplug/qemu/vl.c
===================================================================
--- kvm-userspace.hotplug.orig/qemu/vl.c
+++ kvm-userspace.hotplug/qemu/vl.c
@@ -7573,6 +7573,7 @@ void qemu_bh_delete(QEMUBH *bh)
 /* machine registration */
 
 QEMUMachine *first_machine = NULL;
+QEMUMachine *current_machine = NULL;
 
 int qemu_register_machine(QEMUMachine *m)
 {
@@ -9703,6 +9704,8 @@ int main(int argc, char **argv)
     machine->init(ram_size, vga_ram_size, boot_devices, ds,
                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
 
+    current_machine = machine;
+
     /* init USB devices */
     if (usb_enabled) {
         for(i = 0; i < usb_devices_index; i++) {

-- 


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to