Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging

Pull request

# gpg: Signature made Thu 31 Oct 2019 15:55:44 GMT
# gpg:                using RSA key F9B7ABDBBCACDF95BE76CBD07DEF8106AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" [full]
# Primary key fingerprint: FAEB 9711 A12C F475 812F  18F2 88A9 064D 1835 61EB
#      Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76  CBD0 7DEF 8106 AAFC 390E

* remotes/jnsnow/tags/ide-pull-request:
  hd-geo-test: Add tests for lchs override
  bootdevice: FW_CFG interface for LCHS values
  bootdevice: Refactor get_boot_devices_list
  bootdevice: Gather LCHS from all relevant devices
  scsi: Propagate unrealize() callback to scsi-hd
  bootdevice: Add interface to gather LCHS
  block: Support providing LCHS from user
  block: Refactor macros - fix tabbing
  IDE: deprecate ide-drive

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2019-10-31 15:57:30 +00:00
13 changed files with 753 additions and 43 deletions
+120 -27
View File
@@ -202,6 +202,39 @@ DeviceState *get_boot_device(uint32_t position)
return res;
}
static char *get_boot_device_path(DeviceState *dev, bool ignore_suffixes,
const char *suffix)
{
char *devpath = NULL, *s = NULL, *d, *bootpath;
if (dev) {
devpath = qdev_get_fw_dev_path(dev);
assert(devpath);
}
if (!ignore_suffixes) {
if (dev) {
d = qdev_get_own_fw_dev_path_from_handler(dev->parent_bus, dev);
if (d) {
assert(!suffix);
s = d;
} else {
s = g_strdup(suffix);
}
} else {
s = g_strdup(suffix);
}
}
bootpath = g_strdup_printf("%s%s",
devpath ? devpath : "",
s ? s : "");
g_free(devpath);
g_free(s);
return bootpath;
}
/*
* This function returns null terminated string that consist of new line
* separated device paths.
@@ -218,36 +251,10 @@ char *get_boot_devices_list(size_t *size)
bool ignore_suffixes = mc->ignore_boot_device_suffixes;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
char *devpath = NULL, *suffix = NULL;
char *bootpath;
char *d;
size_t len;
if (i->dev) {
devpath = qdev_get_fw_dev_path(i->dev);
assert(devpath);
}
if (!ignore_suffixes) {
if (i->dev) {
d = qdev_get_own_fw_dev_path_from_handler(i->dev->parent_bus,
i->dev);
if (d) {
assert(!i->suffix);
suffix = d;
} else {
suffix = g_strdup(i->suffix);
}
} else {
suffix = g_strdup(i->suffix);
}
}
bootpath = g_strdup_printf("%s%s",
devpath ? devpath : "",
suffix ? suffix : "");
g_free(devpath);
g_free(suffix);
bootpath = get_boot_device_path(i->dev, ignore_suffixes, i->suffix);
if (total) {
list[total-1] = '\n';
@@ -343,3 +350,89 @@ void device_add_bootindex_property(Object *obj, int32_t *bootindex,
/* initialize devices' bootindex property to -1 */
object_property_set_int(obj, -1, name, NULL);
}
typedef struct FWLCHSEntry FWLCHSEntry;
struct FWLCHSEntry {
QTAILQ_ENTRY(FWLCHSEntry) link;
DeviceState *dev;
char *suffix;
uint32_t lcyls;
uint32_t lheads;
uint32_t lsecs;
};
static QTAILQ_HEAD(, FWLCHSEntry) fw_lchs =
QTAILQ_HEAD_INITIALIZER(fw_lchs);
void add_boot_device_lchs(DeviceState *dev, const char *suffix,
uint32_t lcyls, uint32_t lheads, uint32_t lsecs)
{
FWLCHSEntry *node;
if (!lcyls && !lheads && !lsecs) {
return;
}
assert(dev != NULL || suffix != NULL);
node = g_malloc0(sizeof(FWLCHSEntry));
node->suffix = g_strdup(suffix);
node->dev = dev;
node->lcyls = lcyls;
node->lheads = lheads;
node->lsecs = lsecs;
QTAILQ_INSERT_TAIL(&fw_lchs, node, link);
}
void del_boot_device_lchs(DeviceState *dev, const char *suffix)
{
FWLCHSEntry *i;
if (dev == NULL) {
return;
}
QTAILQ_FOREACH(i, &fw_lchs, link) {
if ((!suffix || !g_strcmp0(i->suffix, suffix)) &&
i->dev == dev) {
QTAILQ_REMOVE(&fw_lchs, i, link);
g_free(i->suffix);
g_free(i);
break;
}
}
}
char *get_boot_devices_lchs_list(size_t *size)
{
FWLCHSEntry *i;
size_t total = 0;
char *list = NULL;
QTAILQ_FOREACH(i, &fw_lchs, link) {
char *bootpath;
char *chs_string;
size_t len;
bootpath = get_boot_device_path(i->dev, false, i->suffix);
chs_string = g_strdup_printf("%s %" PRIu32 " %" PRIu32 " %" PRIu32,
bootpath, i->lcyls, i->lheads, i->lsecs);
if (total) {
list[total - 1] = '\n';
}
len = strlen(chs_string) + 1;
list = g_realloc(list, total + len);
memcpy(&list[total], chs_string, len);
total += len;
g_free(chs_string);
g_free(bootpath);
}
*size = total;
return list;
}
+6
View File
@@ -1200,6 +1200,11 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
blk_set_guest_block_size(s->blk, s->conf.conf.logical_block_size);
blk_iostatus_enable(s->blk);
add_boot_device_lchs(dev, "/disk@0,0",
conf->conf.lcyls,
conf->conf.lheads,
conf->conf.lsecs);
}
static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -1210,6 +1215,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
unsigned i;
blk_drain(s->blk);
del_boot_device_lchs(dev, "/disk@0,0");
virtio_blk_data_plane_destroy(s->dataplane);
s->dataplane = NULL;
for (i = 0; i < conf->num_queues; i++) {
+9 -1
View File
@@ -220,6 +220,11 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
add_boot_device_path(dev->conf.bootindex, &dev->qdev,
dev->unit ? "/disk@1" : "/disk@0");
add_boot_device_lchs(&dev->qdev, dev->unit ? "/disk@1" : "/disk@0",
dev->conf.lcyls,
dev->conf.lheads,
dev->conf.lsecs);
}
static void ide_dev_get_bootindex(Object *obj, Visitor *v, const char *name,
@@ -279,6 +284,9 @@ static void ide_drive_realize(IDEDevice *dev, Error **errp)
{
DriveInfo *dinfo = NULL;
warn_report("'ide-drive' is deprecated, "
"please use 'ide-hd' or 'ide-cd' instead");
if (dev->conf.blk) {
dinfo = blk_legacy_dinfo(dev->conf.blk);
}
@@ -290,7 +298,7 @@ static void ide_drive_realize(IDEDevice *dev, Error **errp)
DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \
DEFINE_BLOCK_ERROR_PROPERTIES(IDEDrive, dev.conf), \
DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \
DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \
DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \
DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\
DEFINE_PROP_STRING("model", IDEDrive, dev.model)
+11 -3
View File
@@ -949,13 +949,21 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
static void fw_cfg_machine_reset(void *opaque)
{
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
FWCfgState *s = opaque;
void *ptr;
size_t len;
FWCfgState *s = opaque;
char *bootindex = get_boot_devices_list(&len);
char *buf;
ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
buf = get_boot_devices_list(&len);
ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)buf, len);
g_free(ptr);
if (!mc->legacy_fw_cfg_order) {
buf = get_boot_devices_lchs_list(&len);
ptr = fw_cfg_modify_file(s, "bios-geometry", (uint8_t *)buf, len);
g_free(ptr);
}
}
static void fw_cfg_machine_ready(struct Notifier *n, void *data)
+16
View File
@@ -59,6 +59,14 @@ static void scsi_device_realize(SCSIDevice *s, Error **errp)
}
}
static void scsi_device_unrealize(SCSIDevice *s, Error **errp)
{
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
if (sc->unrealize) {
sc->unrealize(s, errp);
}
}
int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private)
{
@@ -217,12 +225,20 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
{
SCSIDevice *dev = SCSI_DEVICE(qdev);
Error *local_err = NULL;
if (dev->vmsentry) {
qemu_del_vm_change_state_handler(dev->vmsentry);
}
scsi_device_purge_requests(dev, SENSE_CODE(NO_SENSE));
scsi_device_unrealize(dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
blockdev_mark_auto_del(dev->conf.blk);
}
+12
View File
@@ -35,6 +35,7 @@
#include "hw/block/block.h"
#include "hw/qdev-properties.h"
#include "sysemu/dma.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
#include "trace.h"
@@ -2414,6 +2415,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize);
blk_iostatus_enable(s->qdev.conf.blk);
add_boot_device_lchs(&dev->qdev, NULL,
dev->conf.lcyls,
dev->conf.lheads,
dev->conf.lsecs);
}
static void scsi_unrealize(SCSIDevice *dev, Error **errp)
{
del_boot_device_lchs(&dev->qdev, NULL);
}
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
@@ -3018,6 +3029,7 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
sc->realize = scsi_hd_realize;
sc->unrealize = scsi_unrealize;
sc->alloc_req = scsi_new_request;
sc->unit_attention_reported = scsi_disk_unit_attention_reported;
dc->desc = "virtual SCSI disk";
+13 -9
View File
@@ -26,6 +26,7 @@ typedef struct BlockConf {
uint32_t discard_granularity;
/* geometry, not all devices use this */
uint32_t cyls, heads, secs;
uint32_t lcyls, lheads, lsecs;
OnOffAuto wce;
bool share_rw;
BlockdevOnError rerror;
@@ -50,22 +51,25 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
_conf.logical_block_size), \
DEFINE_PROP_BLOCKSIZE("physical_block_size", _state, \
_conf.physical_block_size), \
DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \
DEFINE_PROP_UINT32("discard_granularity", _state, \
_conf.discard_granularity, -1), \
DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, \
ON_OFF_AUTO_AUTO), \
DEFINE_PROP_UINT32("discard_granularity", _state, \
_conf.discard_granularity, -1), \
DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, \
ON_OFF_AUTO_AUTO), \
DEFINE_PROP_BOOL("share-rw", _state, _conf.share_rw, false)
#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
DEFINE_PROP_DRIVE("drive", _state, _conf.blk), \
DEFINE_BLOCK_PROPERTIES_BASE(_state, _conf)
#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0), \
DEFINE_PROP_UINT32("lcyls", _state, _conf.lcyls, 0), \
DEFINE_PROP_UINT32("lheads", _state, _conf.lheads, 0), \
DEFINE_PROP_UINT32("lsecs", _state, _conf.lsecs, 0)
#define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf) \
DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \
+1
View File
@@ -59,6 +59,7 @@ struct SCSIRequest {
typedef struct SCSIDeviceClass {
DeviceClass parent_class;
void (*realize)(SCSIDevice *dev, Error **errp);
void (*unrealize)(SCSIDevice *dev, Error **errp);
int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private);
SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
+4
View File
@@ -103,6 +103,10 @@ void device_add_bootindex_property(Object *obj, int32_t *bootindex,
DeviceState *dev, Error **errp);
void restore_boot_order(void *opaque);
void validate_bootdevices(const char *devices, Error **errp);
void add_boot_device_lchs(DeviceState *dev, const char *suffix,
uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
void del_boot_device_lchs(DeviceState *dev, const char *suffix);
char *get_boot_devices_lchs_list(size_t *size);
/* handler to set the boot_device order for a specific type of MachineClass */
typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
+5
View File
@@ -254,6 +254,11 @@ quite a bit. It will be removed without replacement unless some users speaks
up at the @email{qemu-devel@@nongnu.org} mailing list with information about
their usecases.
@subsection ide-drive (since 4.2)
The 'ide-drive' device is deprecated. Users should use 'ide-hd' or
'ide-cd' as appropriate to get an IDE hard disk or CD-ROM as needed.
@section System emulator machines
@subsection pc-0.12, pc-0.13, pc-0.14 and pc-0.15 (since 4.0)
+1 -1
View File
@@ -794,7 +794,7 @@ tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) qemu-img$(EXESUF)
tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o $(libqos-obj-y)
tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y)
tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
+551
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -158,7 +158,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive if=none,id=disk -device ide-drive,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
(qemu) QEMU_PROG: -device ide-drive,drive=disk: warning: 'ide-drive' is deprecated, please use 'ide-hd' or 'ide-cd' instead
QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
Testing: -drive if=none,id=disk -device ide-hd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
@@ -228,7 +229,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Block node is read-only
(qemu) QEMU_PROG: -device ide-drive,drive=disk: warning: 'ide-drive' is deprecated, please use 'ide-hd' or 'ide-cd' instead
QEMU_PROG: -device ide-drive,drive=disk: Block node is read-only
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information