Merge remote-tracking branch 'stefanha/block' into staging
* stefanha/block: rbd: add an asynchronous flush iotests: Add 'check -ssh' option to test Secure Shell block device. block: ssh: Use libssh2_sftp_fsync (if supported by libssh2) to flush to disk. block: Add support for Secure Shell (ssh) block device. ide: refuse WIN_READ_NATIVE_MAX on empty device qemu-iotests: filter QEMU_PROG in 051.out qemu-iotests: Add test for -drive options qemu-iotests: A few more bdrv_pread/pwrite tests block: Introduce bdrv_pwritev() for qcow2_save_vmstate savevm: Implement block_writev_buffer() block: Introduce bdrv_writev_vmstate Conflicts: savevm.c aliguori: add f->pos parameter to writev_buffer(). Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
db08dc213b
105
block.c
105
block.c
@ -2131,27 +2131,21 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a synchronous request using coroutines
|
||||
* Process a vectored synchronous request using coroutines
|
||||
*/
|
||||
static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
|
||||
int nb_sectors, bool is_write)
|
||||
static int bdrv_rwv_co(BlockDriverState *bs, int64_t sector_num,
|
||||
QEMUIOVector *qiov, bool is_write)
|
||||
{
|
||||
QEMUIOVector qiov;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *)buf,
|
||||
.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
|
||||
};
|
||||
Coroutine *co;
|
||||
RwCo rwco = {
|
||||
.bs = bs,
|
||||
.sector_num = sector_num,
|
||||
.nb_sectors = nb_sectors,
|
||||
.qiov = &qiov,
|
||||
.nb_sectors = qiov->size >> BDRV_SECTOR_BITS,
|
||||
.qiov = qiov,
|
||||
.is_write = is_write,
|
||||
.ret = NOT_DONE,
|
||||
};
|
||||
|
||||
qemu_iovec_init_external(&qiov, &iov, 1);
|
||||
assert((qiov->size & (BDRV_SECTOR_SIZE - 1)) == 0);
|
||||
|
||||
/**
|
||||
* In sync call context, when the vcpu is blocked, this throttling timer
|
||||
@ -2177,6 +2171,22 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
|
||||
return rwco.ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a synchronous request using coroutines
|
||||
*/
|
||||
static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
|
||||
int nb_sectors, bool is_write)
|
||||
{
|
||||
QEMUIOVector qiov;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *)buf,
|
||||
.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
|
||||
};
|
||||
|
||||
qemu_iovec_init_external(&qiov, &iov, 1);
|
||||
return bdrv_rwv_co(bs, sector_num, &qiov, is_write);
|
||||
}
|
||||
|
||||
/* return < 0 if error. See bdrv_write() for the return codes */
|
||||
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
|
||||
uint8_t *buf, int nb_sectors)
|
||||
@ -2210,6 +2220,11 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
|
||||
return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
|
||||
}
|
||||
|
||||
int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov)
|
||||
{
|
||||
return bdrv_rwv_co(bs, sector_num, qiov, true);
|
||||
}
|
||||
|
||||
int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
||||
void *buf, int count1)
|
||||
{
|
||||
@ -2255,15 +2270,15 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
||||
return count1;
|
||||
}
|
||||
|
||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||
const void *buf, int count1)
|
||||
int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov)
|
||||
{
|
||||
uint8_t tmp_buf[BDRV_SECTOR_SIZE];
|
||||
int len, nb_sectors, count;
|
||||
int64_t sector_num;
|
||||
int ret;
|
||||
|
||||
count = count1;
|
||||
count = qiov->size;
|
||||
|
||||
/* first write to align to sector start */
|
||||
len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
|
||||
if (len > count)
|
||||
@ -2272,24 +2287,32 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||
if (len > 0) {
|
||||
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
|
||||
return ret;
|
||||
memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
|
||||
qemu_iovec_to_buf(qiov, 0, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)),
|
||||
len);
|
||||
if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
|
||||
return ret;
|
||||
count -= len;
|
||||
if (count == 0)
|
||||
return count1;
|
||||
return qiov->size;
|
||||
sector_num++;
|
||||
buf += len;
|
||||
}
|
||||
|
||||
/* write the sectors "in place" */
|
||||
nb_sectors = count >> BDRV_SECTOR_BITS;
|
||||
if (nb_sectors > 0) {
|
||||
if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
|
||||
QEMUIOVector qiov_inplace;
|
||||
|
||||
qemu_iovec_init(&qiov_inplace, qiov->niov);
|
||||
qemu_iovec_concat(&qiov_inplace, qiov, len,
|
||||
nb_sectors << BDRV_SECTOR_BITS);
|
||||
ret = bdrv_writev(bs, sector_num, &qiov_inplace);
|
||||
qemu_iovec_destroy(&qiov_inplace);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
sector_num += nb_sectors;
|
||||
len = nb_sectors << BDRV_SECTOR_BITS;
|
||||
buf += len;
|
||||
count -= len;
|
||||
}
|
||||
|
||||
@ -2297,11 +2320,24 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||
if (count > 0) {
|
||||
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
|
||||
return ret;
|
||||
memcpy(tmp_buf, buf, count);
|
||||
qemu_iovec_to_buf(qiov, qiov->size - count, tmp_buf, count);
|
||||
if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
|
||||
return ret;
|
||||
}
|
||||
return count1;
|
||||
return qiov->size;
|
||||
}
|
||||
|
||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||
const void *buf, int count1)
|
||||
{
|
||||
QEMUIOVector qiov;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *) buf,
|
||||
.iov_len = count1,
|
||||
};
|
||||
|
||||
qemu_iovec_init_external(&qiov, &iov, 1);
|
||||
return bdrv_pwritev(bs, offset, &qiov);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3183,14 +3219,29 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
|
||||
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||
int64_t pos, int size)
|
||||
{
|
||||
QEMUIOVector qiov;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *) buf,
|
||||
.iov_len = size,
|
||||
};
|
||||
|
||||
qemu_iovec_init_external(&qiov, &iov, 1);
|
||||
return bdrv_writev_vmstate(bs, &qiov, pos);
|
||||
}
|
||||
|
||||
int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
if (!drv)
|
||||
|
||||
if (!drv) {
|
||||
return -ENOMEDIUM;
|
||||
if (drv->bdrv_save_vmstate)
|
||||
return drv->bdrv_save_vmstate(bs, buf, pos, size);
|
||||
if (bs->file)
|
||||
return bdrv_save_vmstate(bs->file, buf, pos, size);
|
||||
} else if (drv->bdrv_save_vmstate) {
|
||||
return drv->bdrv_save_vmstate(bs, qiov, pos);
|
||||
} else if (bs->file) {
|
||||
return bdrv_writev_vmstate(bs->file, qiov, pos);
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ block-obj-$(CONFIG_LIBISCSI) += iscsi.o
|
||||
block-obj-$(CONFIG_CURL) += curl.o
|
||||
block-obj-$(CONFIG_RBD) += rbd.o
|
||||
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
|
||||
block-obj-$(CONFIG_LIBSSH2) += ssh.o
|
||||
endif
|
||||
|
||||
common-obj-y += stream.o
|
||||
|
@ -1652,8 +1652,8 @@ static void dump_refcounts(BlockDriverState *bs)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int qcow2_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||
int64_t pos, int size)
|
||||
static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||
int64_t pos)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int growable = bs->growable;
|
||||
@ -1661,7 +1661,7 @@ static int qcow2_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
|
||||
bs->growable = 1;
|
||||
ret = bdrv_pwrite(bs, qcow2_vm_state_offset(s) + pos, buf, size);
|
||||
ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov);
|
||||
bs->growable = growable;
|
||||
|
||||
return ret;
|
||||
|
37
block/rbd.c
37
block/rbd.c
@ -63,7 +63,8 @@
|
||||
typedef enum {
|
||||
RBD_AIO_READ,
|
||||
RBD_AIO_WRITE,
|
||||
RBD_AIO_DISCARD
|
||||
RBD_AIO_DISCARD,
|
||||
RBD_AIO_FLUSH
|
||||
} RBDAIOCmd;
|
||||
|
||||
typedef struct RBDAIOCB {
|
||||
@ -379,8 +380,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
||||
|
||||
r = rcb->ret;
|
||||
|
||||
if (acb->cmd == RBD_AIO_WRITE ||
|
||||
acb->cmd == RBD_AIO_DISCARD) {
|
||||
if (acb->cmd != RBD_AIO_READ) {
|
||||
if (r < 0) {
|
||||
acb->ret = r;
|
||||
acb->error = 1;
|
||||
@ -659,6 +659,16 @@ static int rbd_aio_discard_wrapper(rbd_image_t image,
|
||||
#endif
|
||||
}
|
||||
|
||||
static int rbd_aio_flush_wrapper(rbd_image_t image,
|
||||
rbd_completion_t comp)
|
||||
{
|
||||
#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
|
||||
return rbd_aio_flush(image, comp);
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||
int64_t sector_num,
|
||||
QEMUIOVector *qiov,
|
||||
@ -679,7 +689,7 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||
acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque);
|
||||
acb->cmd = cmd;
|
||||
acb->qiov = qiov;
|
||||
if (cmd == RBD_AIO_DISCARD) {
|
||||
if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
|
||||
acb->bounce = NULL;
|
||||
} else {
|
||||
acb->bounce = qemu_blockalign(bs, qiov->size);
|
||||
@ -723,6 +733,9 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||
case RBD_AIO_DISCARD:
|
||||
r = rbd_aio_discard_wrapper(s->image, off, size, c);
|
||||
break;
|
||||
case RBD_AIO_FLUSH:
|
||||
r = rbd_aio_flush_wrapper(s->image, c);
|
||||
break;
|
||||
default:
|
||||
r = -EINVAL;
|
||||
}
|
||||
@ -762,6 +775,16 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
|
||||
RBD_AIO_WRITE);
|
||||
}
|
||||
|
||||
#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
|
||||
static BlockDriverAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs,
|
||||
BlockDriverCompletionFunc *cb,
|
||||
void *opaque)
|
||||
{
|
||||
return rbd_start_aio(bs, 0, NULL, 0, cb, opaque, RBD_AIO_FLUSH);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int qemu_rbd_co_flush(BlockDriverState *bs)
|
||||
{
|
||||
#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
|
||||
@ -772,6 +795,7 @@ static int qemu_rbd_co_flush(BlockDriverState *bs)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
@ -949,7 +973,12 @@ static BlockDriver bdrv_rbd = {
|
||||
|
||||
.bdrv_aio_readv = qemu_rbd_aio_readv,
|
||||
.bdrv_aio_writev = qemu_rbd_aio_writev,
|
||||
|
||||
#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
|
||||
.bdrv_aio_flush = qemu_rbd_aio_flush,
|
||||
#else
|
||||
.bdrv_co_flush_to_disk = qemu_rbd_co_flush,
|
||||
#endif
|
||||
|
||||
#ifdef LIBRBD_SUPPORTS_DISCARD
|
||||
.bdrv_aio_discard = qemu_rbd_aio_discard,
|
||||
|
@ -2054,12 +2054,19 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sd_save_vmstate(BlockDriverState *bs, const uint8_t *data,
|
||||
int64_t pos, int size)
|
||||
static int sd_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||
int64_t pos)
|
||||
{
|
||||
BDRVSheepdogState *s = bs->opaque;
|
||||
void *buf;
|
||||
int ret;
|
||||
|
||||
return do_load_save_vmstate(s, (uint8_t *)data, pos, size, 0);
|
||||
buf = qemu_blockalign(bs, qiov->size);
|
||||
qemu_iovec_to_buf(qiov, 0, buf, qiov->size);
|
||||
ret = do_load_save_vmstate(s, (uint8_t *) buf, pos, qiov->size, 0);
|
||||
qemu_vfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sd_load_vmstate(BlockDriverState *bs, uint8_t *data,
|
||||
|
1063
block/ssh.c
Normal file
1063
block/ssh.c
Normal file
File diff suppressed because it is too large
Load Diff
73
configure
vendored
73
configure
vendored
@ -239,6 +239,7 @@ virtio_blk_data_plane=""
|
||||
gtk=""
|
||||
gtkabi="2.0"
|
||||
tpm="no"
|
||||
libssh2=""
|
||||
|
||||
# parse CC options first
|
||||
for opt do
|
||||
@ -922,6 +923,10 @@ for opt do
|
||||
;;
|
||||
--enable-tpm) tpm="yes"
|
||||
;;
|
||||
--disable-libssh2) libssh2="no"
|
||||
;;
|
||||
--enable-libssh2) libssh2="yes"
|
||||
;;
|
||||
*) echo "ERROR: unknown option $opt"; show_help="yes"
|
||||
;;
|
||||
esac
|
||||
@ -1182,6 +1187,8 @@ echo " --disable-glusterfs disable GlusterFS backend"
|
||||
echo " --enable-gcov enable test coverage analysis with gcov"
|
||||
echo " --gcov=GCOV use specified gcov [$gcov_tool]"
|
||||
echo " --enable-tpm enable TPM support"
|
||||
echo " --disable-libssh2 disable ssh block device support"
|
||||
echo " --enable-libssh2 enable ssh block device support"
|
||||
echo ""
|
||||
echo "NOTE: The object files are built at the place where configure is launched"
|
||||
exit 1
|
||||
@ -2313,6 +2320,67 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# libssh2 probe
|
||||
if test "$libssh2" != "no" ; then
|
||||
cat > $TMPC <<EOF
|
||||
#include <stdio.h>
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
int main(void) {
|
||||
LIBSSH2_SESSION *session;
|
||||
session = libssh2_session_init ();
|
||||
(void) libssh2_sftp_init (session);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
if $pkg_config libssh2 --modversion >/dev/null 2>&1; then
|
||||
libssh2_cflags=`$pkg_config libssh2 --cflags`
|
||||
libssh2_libs=`$pkg_config libssh2 --libs`
|
||||
else
|
||||
libssh2_cflags=
|
||||
libssh2_libs="-lssh2"
|
||||
fi
|
||||
|
||||
if compile_prog "$libssh2_cflags" "$libssh2_libs" ; then
|
||||
libssh2=yes
|
||||
libs_tools="$libssh2_libs $libs_tools"
|
||||
libs_softmmu="$libssh2_libs $libs_softmmu"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $libssh2_cflags"
|
||||
else
|
||||
if test "$libssh2" = "yes" ; then
|
||||
feature_not_found "libssh2"
|
||||
fi
|
||||
libssh2=no
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# libssh2_sftp_fsync probe
|
||||
|
||||
if test "$libssh2" = "yes"; then
|
||||
cat > $TMPC <<EOF
|
||||
#include <stdio.h>
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
int main(void) {
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_SFTP *sftp;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
session = libssh2_session_init ();
|
||||
sftp = libssh2_sftp_init (session);
|
||||
sftp_handle = libssh2_sftp_open (sftp, "/", 0, 0);
|
||||
libssh2_sftp_fsync (sftp_handle);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
# libssh2_cflags/libssh2_libs defined in previous test.
|
||||
if compile_prog "$libssh2_cflags" "$libssh2_libs" ; then
|
||||
QEMU_CFLAGS="-DHAS_LIBSSH2_SFTP_FSYNC $QEMU_CFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# linux-aio probe
|
||||
|
||||
@ -3435,6 +3503,7 @@ echo "virtio-blk-data-plane $virtio_blk_data_plane"
|
||||
echo "gcov $gcov_tool"
|
||||
echo "gcov enabled $gcov"
|
||||
echo "TPM support $tpm"
|
||||
echo "libssh2 support $libssh2"
|
||||
|
||||
if test "$sdl_too_old" = "yes"; then
|
||||
echo "-> Your SDL version is too old - please upgrade to have SDL support"
|
||||
@ -3793,6 +3862,10 @@ if test "$glusterfs" = "yes" ; then
|
||||
echo "CONFIG_GLUSTERFS=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$libssh2" = "yes" ; then
|
||||
echo "CONFIG_LIBSSH2=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$virtio_blk_data_plane" = "yes" ; then
|
||||
echo 'CONFIG_VIRTIO_BLK_DATA_PLANE=$(CONFIG_VIRTIO)' >> $config_host_mak
|
||||
fi
|
||||
|
@ -1262,6 +1262,10 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
|
||||
lba48 = 1;
|
||||
/* fall through */
|
||||
case WIN_READ_NATIVE_MAX:
|
||||
/* Refuse if no sectors are addressable (e.g. medium not inserted) */
|
||||
if (s->nb_sectors == 0) {
|
||||
goto abort_cmd;
|
||||
}
|
||||
ide_cmd_lba48_transform(s, lba48);
|
||||
ide_set_sector(s, s->nb_sectors - 1);
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
|
@ -166,10 +166,12 @@ int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
|
||||
uint8_t *buf, int nb_sectors);
|
||||
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
|
||||
const uint8_t *buf, int nb_sectors);
|
||||
int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov);
|
||||
int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
||||
void *buf, int count);
|
||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||
const void *buf, int count);
|
||||
int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov);
|
||||
int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
|
||||
const void *buf, int count);
|
||||
int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
|
||||
@ -348,6 +350,7 @@ void path_combine(char *dest, int dest_size,
|
||||
const char *base_path,
|
||||
const char *filename);
|
||||
|
||||
int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
||||
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||
int64_t pos, int size);
|
||||
|
||||
|
@ -164,8 +164,8 @@ struct BlockDriver {
|
||||
const char *snapshot_name);
|
||||
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
||||
|
||||
int (*bdrv_save_vmstate)(BlockDriverState *bs, const uint8_t *buf,
|
||||
int64_t pos, int size);
|
||||
int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||
int64_t pos);
|
||||
int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
|
||||
int64_t pos, int size);
|
||||
|
||||
|
@ -55,7 +55,7 @@ typedef int (QEMUFileGetFD)(void *opaque);
|
||||
* This function writes an iovec to file.
|
||||
*/
|
||||
typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
|
||||
int iovcnt);
|
||||
int iovcnt, int64_t pos);
|
||||
|
||||
typedef struct QEMUFileOps {
|
||||
QEMUFilePutBufferFunc *put_buffer;
|
||||
|
@ -423,6 +423,7 @@ snapshots.
|
||||
* disk_images_sheepdog:: Sheepdog disk images
|
||||
* disk_images_iscsi:: iSCSI LUNs
|
||||
* disk_images_gluster:: GlusterFS disk images
|
||||
* disk_images_ssh:: Secure Shell (ssh) disk images
|
||||
@end menu
|
||||
|
||||
@node disk_images_quickstart
|
||||
@ -1038,6 +1039,59 @@ qemu-system-x86_64 -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glu
|
||||
qemu-system-x86_64 -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
|
||||
@end example
|
||||
|
||||
@node disk_images_ssh
|
||||
@subsection Secure Shell (ssh) disk images
|
||||
|
||||
You can access disk images located on a remote ssh server
|
||||
by using the ssh protocol:
|
||||
|
||||
@example
|
||||
qemu-system-x86_64 -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
|
||||
@end example
|
||||
|
||||
Alternative syntax using properties:
|
||||
|
||||
@example
|
||||
qemu-system-x86_64 -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
|
||||
@end example
|
||||
|
||||
@var{ssh} is the protocol.
|
||||
|
||||
@var{user} is the remote user. If not specified, then the local
|
||||
username is tried.
|
||||
|
||||
@var{server} specifies the remote ssh server. Any ssh server can be
|
||||
used, but it must implement the sftp-server protocol. Most Unix/Linux
|
||||
systems should work without requiring any extra configuration.
|
||||
|
||||
@var{port} is the port number on which sshd is listening. By default
|
||||
the standard ssh port (22) is used.
|
||||
|
||||
@var{path} is the path to the disk image.
|
||||
|
||||
The optional @var{host_key_check} parameter controls how the remote
|
||||
host's key is checked. The default is @code{yes} which means to use
|
||||
the local @file{.ssh/known_hosts} file. Setting this to @code{no}
|
||||
turns off known-hosts checking. Or you can check that the host key
|
||||
matches a specific fingerprint:
|
||||
@code{host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8}
|
||||
(@code{sha1:} can also be used as a prefix, but note that OpenSSH
|
||||
tools only use MD5 to print fingerprints).
|
||||
|
||||
Currently authentication must be done using ssh-agent. Other
|
||||
authentication methods may be supported in future.
|
||||
|
||||
Note: Many ssh servers do not support an @code{fsync}-style operation.
|
||||
The ssh driver cannot guarantee that disk flush requests are
|
||||
obeyed, and this causes a risk of disk corruption if the remote
|
||||
server or network goes down during writes. The driver will
|
||||
print a warning when @code{fsync} is not supported:
|
||||
|
||||
warning: ssh server @code{ssh.example.com:22} does not support fsync
|
||||
|
||||
With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is
|
||||
supported.
|
||||
|
||||
@node pcsys_network
|
||||
@section Network emulation
|
||||
|
||||
|
@ -2107,6 +2107,18 @@ Example for Unix Domain Sockets
|
||||
qemu-system-i386 --drive file=nbd:unix:/tmp/nbd-socket
|
||||
@end example
|
||||
|
||||
@item SSH
|
||||
QEMU supports SSH (Secure Shell) access to remote disks.
|
||||
|
||||
Examples:
|
||||
@example
|
||||
qemu-system-i386 -drive file=ssh://user@@host/path/to/disk.img
|
||||
qemu-system-i386 -drive file.driver=ssh,file.user=user,file.host=host,file.port=22,file.path=/path/to/disk.img
|
||||
@end example
|
||||
|
||||
Currently authentication must be done using ssh-agent. Other
|
||||
authentication methods may be supported in future.
|
||||
|
||||
@item Sheepdog
|
||||
Sheepdog is a distributed storage system for QEMU.
|
||||
QEMU supports using either local sheepdog devices or remote networked
|
||||
|
25
savevm.c
25
savevm.c
@ -175,7 +175,8 @@ static void coroutine_fn yield_until_fd_readable(int fd)
|
||||
qemu_coroutine_yield();
|
||||
}
|
||||
|
||||
static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt)
|
||||
static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
|
||||
int64_t pos)
|
||||
{
|
||||
QEMUFileSocket *s = opaque;
|
||||
ssize_t len;
|
||||
@ -457,6 +458,21 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
|
||||
int64_t pos)
|
||||
{
|
||||
int ret;
|
||||
QEMUIOVector qiov;
|
||||
|
||||
qemu_iovec_init_external(&qiov, iov, iovcnt);
|
||||
ret = bdrv_writev_vmstate(opaque, &qiov, pos);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return qiov.size;
|
||||
}
|
||||
|
||||
static int block_put_buffer(void *opaque, const uint8_t *buf,
|
||||
int64_t pos, int size)
|
||||
{
|
||||
@ -480,8 +496,9 @@ static const QEMUFileOps bdrv_read_ops = {
|
||||
};
|
||||
|
||||
static const QEMUFileOps bdrv_write_ops = {
|
||||
.put_buffer = block_put_buffer,
|
||||
.close = bdrv_fclose
|
||||
.put_buffer = block_put_buffer,
|
||||
.writev_buffer = block_writev_buffer,
|
||||
.close = bdrv_fclose
|
||||
};
|
||||
|
||||
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
|
||||
@ -535,7 +552,7 @@ static void qemu_fflush(QEMUFile *f)
|
||||
|
||||
if (f->ops->writev_buffer) {
|
||||
if (f->iovcnt > 0) {
|
||||
ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt);
|
||||
ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
|
||||
}
|
||||
} else {
|
||||
if (f->buf_index > 0) {
|
||||
|
@ -61,10 +61,23 @@ $QEMU_IO -c "read -pP 0xa 0 $size" $TEST_IMG | _filter_qemu_io
|
||||
echo
|
||||
echo "unaligned pwrite"
|
||||
$QEMU_IO -c 'write -pP 0xab 66 42' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'write -pP 0xac 512 288' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'write -pP 0xad 800 224' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'write -pP 0xae 66000 128k' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'write -pP 0xaf 256k 42' $TEST_IMG | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "verify pattern"
|
||||
$QEMU_IO -c 'read -pP 0xa 0 66' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xab 66 42' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xa 108 404' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xac 512 288' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xad 800 224' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xa 1k 64976' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xae 66000 128k' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xa 197072 65072' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xaf 256k 42' $TEST_IMG | _filter_qemu_io
|
||||
$QEMU_IO -c 'read -pP 0xa 262186 470' $TEST_IMG | _filter_qemu_io
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
|
@ -16,8 +16,34 @@ read 134217728/134217728 bytes at offset 0
|
||||
unaligned pwrite
|
||||
wrote 42/42 bytes at offset 66
|
||||
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 288/288 bytes at offset 512
|
||||
288 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 224/224 bytes at offset 800
|
||||
224 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 131072/131072 bytes at offset 66000
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 42/42 bytes at offset 262144
|
||||
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
verify pattern
|
||||
read 66/66 bytes at offset 0
|
||||
66 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 42/42 bytes at offset 66
|
||||
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 404/404 bytes at offset 108
|
||||
404 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 288/288 bytes at offset 512
|
||||
288 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 224/224 bytes at offset 800
|
||||
224 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 64976/64976 bytes at offset 1024
|
||||
63.453 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 131072/131072 bytes at offset 66000
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 65072/65072 bytes at offset 197072
|
||||
63.547 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 42/42 bytes at offset 262144
|
||||
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 470/470 bytes at offset 262186
|
||||
470 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
*** done
|
||||
|
148
tests/qemu-iotests/051
Executable file
148
tests/qemu-iotests/051
Executable file
@ -0,0 +1,148 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Test command line configuration of block devices and driver-specific options
|
||||
#
|
||||
# Copyright (C) 2013 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# creator
|
||||
owner=kwolf@redhat.com
|
||||
|
||||
seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_test_img
|
||||
}
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
_supported_fmt qcow2
|
||||
_supported_proto file
|
||||
_supported_os Linux
|
||||
|
||||
function do_run_qemu()
|
||||
{
|
||||
echo Testing: "$@"
|
||||
echo quit | $QEMU -nographic -monitor stdio -serial none "$@"
|
||||
echo
|
||||
}
|
||||
|
||||
function run_qemu()
|
||||
{
|
||||
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu
|
||||
}
|
||||
|
||||
size=128M
|
||||
|
||||
_make_test_img $size
|
||||
|
||||
echo
|
||||
echo === Unknown option ===
|
||||
echo
|
||||
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,unknown_opt=
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,unknown_opt=on
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,unknown_opt=1234
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,unknown_opt=foo
|
||||
|
||||
|
||||
echo
|
||||
echo === Enable and disable lazy refcounting on the command line, plus some invalid values ===
|
||||
echo
|
||||
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,lazy_refcounts=on
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,lazy_refcounts=off
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,lazy_refcounts=
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,lazy_refcounts=42
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,lazy_refcounts=foo
|
||||
|
||||
|
||||
echo
|
||||
echo === With version 2 images enabling lazy refcounts must fail ===
|
||||
echo
|
||||
|
||||
_make_test_img -ocompat=0.10 $size
|
||||
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,lazy_refcounts=on
|
||||
run_qemu -drive file=$TEST_IMG,format=qcow2,lazy_refcounts=off
|
||||
|
||||
echo
|
||||
echo === No medium ===
|
||||
echo
|
||||
|
||||
run_qemu -drive if=floppy
|
||||
run_qemu -drive if=ide,media=cdrom
|
||||
run_qemu -drive if=scsi,media=cdrom
|
||||
|
||||
run_qemu -drive if=ide
|
||||
run_qemu -drive if=virtio
|
||||
run_qemu -drive if=scsi
|
||||
|
||||
run_qemu -drive if=none,id=disk -device ide-cd,drive=disk
|
||||
run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
|
||||
|
||||
run_qemu -drive if=none,id=disk -device ide-drive,drive=disk
|
||||
run_qemu -drive if=none,id=disk -device ide-hd,drive=disk
|
||||
run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
|
||||
run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
|
||||
|
||||
echo
|
||||
echo === Read-only ===
|
||||
echo
|
||||
|
||||
run_qemu -drive file=$TEST_IMG,if=floppy,readonly=on
|
||||
run_qemu -drive file=$TEST_IMG,if=ide,media=cdrom,readonly=on
|
||||
run_qemu -drive file=$TEST_IMG,if=scsi,media=cdrom,readonly=on
|
||||
|
||||
run_qemu -drive file=$TEST_IMG,if=ide,readonly=on
|
||||
run_qemu -drive file=$TEST_IMG,if=virtio,readonly=on
|
||||
run_qemu -drive file=$TEST_IMG,if=scsi,readonly=on
|
||||
|
||||
run_qemu -drive file=$TEST_IMG,if=none,id=disk,readonly=on -device ide-cd,drive=disk
|
||||
run_qemu -drive file=$TEST_IMG,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
|
||||
|
||||
run_qemu -drive file=$TEST_IMG,if=none,id=disk,readonly=on -device ide-drive,drive=disk
|
||||
run_qemu -drive file=$TEST_IMG,if=none,id=disk,readonly=on -device ide-hd,drive=disk
|
||||
run_qemu -drive file=$TEST_IMG,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
|
||||
run_qemu -drive file=$TEST_IMG,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
|
||||
|
||||
echo
|
||||
echo === Cache modes ===
|
||||
echo
|
||||
|
||||
# Cannot use the test image because cache=none might not work on the host FS
|
||||
# Use cdrom so that we won't get errors about missing media
|
||||
|
||||
run_qemu -drive media=cdrom,cache=none
|
||||
run_qemu -drive media=cdrom,cache=directsync
|
||||
run_qemu -drive media=cdrom,cache=writeback
|
||||
run_qemu -drive media=cdrom,cache=writethrough
|
||||
run_qemu -drive media=cdrom,cache=unsafe
|
||||
run_qemu -drive media=cdrom,cache=invalid_value
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
status=0
|
162
tests/qemu-iotests/051.out
Normal file
162
tests/qemu-iotests/051.out
Normal file
@ -0,0 +1,162 @@
|
||||
QA output created by 051
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||
|
||||
=== Unknown option ===
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=on
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=on: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=on: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=1234
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=1234: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=1234: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
|
||||
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=: Parameter 'lazy_refcounts' expects 'on' or 'off'
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=42
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=42: Parameter 'lazy_refcounts' expects 'on' or 'off'
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=42: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=foo
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=foo: Parameter 'lazy_refcounts' expects 'on' or 'off'
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=foo: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
|
||||
=== With version 2 images enabling lazy refcounts must fail ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on: Lazy refcounts require a qcow2 image with at least qemu 1.1 compatibility level
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
|
||||
=== No medium ===
|
||||
|
||||
Testing: -drive if=floppy
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=ide,media=cdrom
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=scsi,media=cdrom
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=ide
|
||||
QEMU_PROG: Device needs media, but drive is empty
|
||||
QEMU_PROG: Initialization of device ide-hd failed
|
||||
|
||||
Testing: -drive if=virtio
|
||||
QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
|
||||
QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
|
||||
|
||||
Testing: -drive if=scsi
|
||||
QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
|
||||
QEMU_PROG: Initialization of device lsi53c895a failed
|
||||
|
||||
Testing: -drive if=none,id=disk -device ide-cd,drive=disk
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=none,id=disk -device ide-drive,drive=disk
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
||||
|
||||
Testing: -drive if=none,id=disk -device ide-hd,drive=disk
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
||||
|
||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
|
||||
QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
|
||||
|
||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
|
||||
QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
|
||||
|
||||
|
||||
=== Read-only ===
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: readonly not supported by this bus type
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
|
||||
=== Cache modes ===
|
||||
|
||||
Testing: -drive media=cdrom,cache=none
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=directsync
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=writeback
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=writethrough
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=unsafe
|
||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=invalid_value
|
||||
QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
|
||||
|
||||
*** done
|
@ -137,6 +137,7 @@ check options
|
||||
-rbd test rbd
|
||||
-sheepdog test sheepdog
|
||||
-nbd test nbd
|
||||
-ssh test ssh
|
||||
-xdiff graphical mode diff
|
||||
-nocache use O_DIRECT on backing file
|
||||
-misalign misalign memory allocations
|
||||
@ -206,6 +207,10 @@ testlist options
|
||||
IMGPROTO=nbd
|
||||
xpand=false
|
||||
;;
|
||||
-ssh)
|
||||
IMGPROTO=ssh
|
||||
xpand=false
|
||||
;;
|
||||
-nocache)
|
||||
QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --nocache"
|
||||
xpand=false
|
||||
|
@ -152,5 +152,11 @@ _filter_qemu_io()
|
||||
_filter_win32 | sed -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/"
|
||||
}
|
||||
|
||||
# replace occurrences of QEMU_PROG with "qemu"
|
||||
_filter_qemu()
|
||||
{
|
||||
sed -e "s#$(basename $QEMU_PROG)#QEMU_PROG#g"
|
||||
}
|
||||
|
||||
# make sure this script returns success
|
||||
/bin/true
|
||||
|
@ -52,6 +52,9 @@ if [ "$IMGPROTO" = "file" ]; then
|
||||
elif [ "$IMGPROTO" = "nbd" ]; then
|
||||
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
||||
TEST_IMG="nbd:127.0.0.1:10810"
|
||||
elif [ "$IMGPROTO" = "ssh" ]; then
|
||||
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
||||
TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
|
||||
else
|
||||
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
|
||||
fi
|
||||
|
@ -57,4 +57,5 @@
|
||||
048 img auto quick
|
||||
049 rw auto
|
||||
050 rw auto backing quick
|
||||
051 rw auto
|
||||
052 rw auto backing
|
||||
|
Loading…
Reference in New Issue
Block a user