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
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel