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