qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/4] SCSI-Hotdel: Implement drive_hot_del


From: Wolfgang Mauerer
Subject: [Qemu-devel] [PATCH 3/4] SCSI-Hotdel: Implement drive_hot_del
Date: Fri, 18 Sep 2009 17:26:33 +0200

This commit implements the method drive_hot_del() that allows
for hot-removing drives. It also introduces a new
monitor command drive_del, which acts as counterpart
to drive_add.

Signed-off-by: Wolfgang Mauerer <address@hidden>
Signed-off-by: Jan Kiszka <address@hidden>
---
 hw/pci-hotplug.c |   92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-monitor.hx  |   14 +++++++-
 sysemu.h         |    1 +
 3 files changed, 106 insertions(+), 1 deletions(-)

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index b8ea9ae..4455f17 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -50,6 +50,98 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
     return pci_nic_init(&nd_table[ret], "rtl8139", devaddr);
 }
 
+void drive_hot_del(Monitor *mon, const QDict *qdict)
+{
+    int dom, pci_bus;
+    unsigned slot;
+    unsigned unit, bus; 
+    int type;
+    int success = 0;
+    PCIDevice *dev;
+    DriveInfo *dinfo;
+    BlockDriverState *bs;
+    char buf[128];
+    const char *strbuf;
+    QemuOpts *opts;
+
+    static const char * const params[] = { "bus", "unit", "if", NULL };
+    const char *pci_addr = qdict_get_str(qdict, "pci_addr");
+    const char *optstring = qdict_get_try_str(qdict, "opts");
+
+     /* strip legacy tag */
+    if (!strncmp(pci_addr, "pci_addr=", 9)) {
+        pci_addr += 9;
+    }
+
+    if (check_params(buf, sizeof(buf), params, optstring) < 0) {
+        monitor_printf(mon, "qemu: unknown parameter '%s' in '%s'\n",
+                         buf, optstring);
+       return;
+    }
+    opts = drive_add(NULL, "%s", optstring); // Just parses optstring
+
+    if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
+        monitor_printf(mon, "Invalid pci address\n");
+        return;
+    }
+
+    dev = pci_find_device(pci_bus, slot, 0);
+    if (!dev) {
+        monitor_printf(mon, "No pci device with address %s\n", pci_addr);
+        return;
+    }
+
+    bus = qemu_opt_get_number(opts, "bus", -1);
+    if (bus == -1) {
+        monitor_printf(mon, "Need to specify bus\n");
+        return;
+    }
+
+    unit = qemu_opt_get_number(opts, "unit", -1);
+    if (unit == -1) {
+        monitor_printf(mon, "Need to specify unit\n");
+        return;
+    }
+
+    if ((strbuf = qemu_opt_get(opts, "if")) != NULL) {
+        type = qemu_opt_get_if(strbuf);
+
+       if (type == IF_COUNT) {
+           monitor_printf(mon, "Trying to remove device on invalid bus\n");
+           return;
+       }
+     } else {
+         /* Assume SCSI for hot-remove per default */
+         type = IF_SCSI;
+     }
+
+     dinfo = drive_get(type, bus, unit);
+     if (!dinfo) {
+         monitor_printf(mon, "Trying to remove non-existent device\n");
+        return;
+     }
+
+    switch (type) {
+    case IF_SCSI:
+        success = 1;
+        lsi_scsi_detach(&dev->qdev, dinfo->bdrv, dinfo->unit);
+
+        bs = dinfo->bdrv;
+        drive_uninit(bs);
+        bdrv_delete(bs);
+        break;
+    default:
+        monitor_printf(mon, "Hot-remove unsupported for interface type %d\n", 
+                      type);
+    }
+
+    if (success) 
+        monitor_printf(mon, "OK bus %d, unit %d\n", bus, unit);
+
+    return;
+}
+
+
 void drive_hot_add(Monitor *mon, const QDict *qdict)
 {
     int dom, pci_bus;
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index a889fed..aee5ff9 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -510,7 +510,19 @@ Add drive to PCI storage controller.
 ETEXI
 
 #if defined(TARGET_I386)
-    { "pci_add", "pci_addr:s,type:s,opts:s?", pci_device_hot_add, 
"auto|[[<domain>:]<bus>:]<slot> nic|storage|host 
[[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]... 
[host=02:00.0[,name=string][,dma=none]", "hot-add PCI device" },
+    { "drive_del", "ss", drive_hot_del, "[[<domain>:]<bus>:]<slot>\n"
+                                         "bus=n,unit=m[,if=type]\n",
+                                         "Delete drive from PCI storage 
controller" },
+#endif
+STEXI
address@hidden drive_del
+Delete drive from PCI storage controller. The device must be identified
+by the bus and unit parameters. Currently, only the LSI SCSI driver
+supports drive removal.
+ETEXI
+
+#if defined(TARGET_I386)
+    { "pci_add", "sss?", pci_device_hot_add, "auto|[[<domain>:]<bus>:]<slot> 
nic|storage|host [[vlan=n][,macaddr=addr][,model=type]] 
[file=file][,if=type][,bus=nr]... [host=02:00.0[,name=string][,dma=none]", 
"hot-add PCI device" },
 #endif
 STEXI
 @item pci_add
diff --git a/sysemu.h b/sysemu.h
index 4fabb2a..0c08b48 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -218,6 +218,7 @@ void destroy_bdrvs(dev_match_fn *match_fn, void *arg);
 /* pci-hotplug */
 void pci_device_hot_add(Monitor *mon, const QDict *qdict);
 void drive_hot_add(Monitor *mon, const QDict *qdict);
+void drive_hot_del(Monitor *mon, const QDict *qdict);
 void pci_device_hot_remove(Monitor *mon, const char *pci_addr);
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
 void pci_device_hot_remove_success(int pcibus, int slot);
-- 
1.6.4





reply via email to

[Prev in Thread] Current Thread [Next in Thread]