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,
|
static int bdrv_rwv_co(BlockDriverState *bs, int64_t sector_num,
|
||||||
int nb_sectors, bool is_write)
|
QEMUIOVector *qiov, bool is_write)
|
||||||
{
|
{
|
||||||
QEMUIOVector qiov;
|
|
||||||
struct iovec iov = {
|
|
||||||
.iov_base = (void *)buf,
|
|
||||||
.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
|
|
||||||
};
|
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
RwCo rwco = {
|
RwCo rwco = {
|
||||||
.bs = bs,
|
.bs = bs,
|
||||||
.sector_num = sector_num,
|
.sector_num = sector_num,
|
||||||
.nb_sectors = nb_sectors,
|
.nb_sectors = qiov->size >> BDRV_SECTOR_BITS,
|
||||||
.qiov = &qiov,
|
.qiov = qiov,
|
||||||
.is_write = is_write,
|
.is_write = is_write,
|
||||||
.ret = NOT_DONE,
|
.ret = NOT_DONE,
|
||||||
};
|
};
|
||||||
|
assert((qiov->size & (BDRV_SECTOR_SIZE - 1)) == 0);
|
||||||
qemu_iovec_init_external(&qiov, &iov, 1);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In sync call context, when the vcpu is blocked, this throttling timer
|
* 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;
|
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 */
|
/* return < 0 if error. See bdrv_write() for the return codes */
|
||||||
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
|
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
|
||||||
uint8_t *buf, int nb_sectors)
|
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);
|
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,
|
int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
||||||
void *buf, int count1)
|
void *buf, int count1)
|
||||||
{
|
{
|
||||||
|
@ -2255,15 +2270,15 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
||||||
return count1;
|
return count1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov)
|
||||||
const void *buf, int count1)
|
|
||||||
{
|
{
|
||||||
uint8_t tmp_buf[BDRV_SECTOR_SIZE];
|
uint8_t tmp_buf[BDRV_SECTOR_SIZE];
|
||||||
int len, nb_sectors, count;
|
int len, nb_sectors, count;
|
||||||
int64_t sector_num;
|
int64_t sector_num;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
count = count1;
|
count = qiov->size;
|
||||||
|
|
||||||
/* first write to align to sector start */
|
/* first write to align to sector start */
|
||||||
len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
|
len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
|
||||||
if (len > count)
|
if (len > count)
|
||||||
|
@ -2272,24 +2287,32 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
|
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
|
||||||
return ret;
|
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)
|
if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
count -= len;
|
count -= len;
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return count1;
|
return qiov->size;
|
||||||
sector_num++;
|
sector_num++;
|
||||||
buf += len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write the sectors "in place" */
|
/* write the sectors "in place" */
|
||||||
nb_sectors = count >> BDRV_SECTOR_BITS;
|
nb_sectors = count >> BDRV_SECTOR_BITS;
|
||||||
if (nb_sectors > 0) {
|
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;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
sector_num += nb_sectors;
|
sector_num += nb_sectors;
|
||||||
len = nb_sectors << BDRV_SECTOR_BITS;
|
len = nb_sectors << BDRV_SECTOR_BITS;
|
||||||
buf += len;
|
|
||||||
count -= len;
|
count -= len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2297,11 +2320,24 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
|
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
|
||||||
return ret;
|
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)
|
if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
|
||||||
return ret;
|
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,
|
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||||
int64_t pos, int size)
|
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;
|
BlockDriver *drv = bs->drv;
|
||||||
if (!drv)
|
|
||||||
|
if (!drv) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
if (drv->bdrv_save_vmstate)
|
} else if (drv->bdrv_save_vmstate) {
|
||||||
return drv->bdrv_save_vmstate(bs, buf, pos, size);
|
return drv->bdrv_save_vmstate(bs, qiov, pos);
|
||||||
if (bs->file)
|
} else if (bs->file) {
|
||||||
return bdrv_save_vmstate(bs->file, buf, pos, size);
|
return bdrv_writev_vmstate(bs->file, qiov, pos);
|
||||||
|
}
|
||||||
|
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ block-obj-$(CONFIG_LIBISCSI) += iscsi.o
|
||||||
block-obj-$(CONFIG_CURL) += curl.o
|
block-obj-$(CONFIG_CURL) += curl.o
|
||||||
block-obj-$(CONFIG_RBD) += rbd.o
|
block-obj-$(CONFIG_RBD) += rbd.o
|
||||||
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
|
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
|
||||||
|
block-obj-$(CONFIG_LIBSSH2) += ssh.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
common-obj-y += stream.o
|
common-obj-y += stream.o
|
||||||
|
|
|
@ -1652,8 +1652,8 @@ static void dump_refcounts(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int qcow2_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||||
int64_t pos, int size)
|
int64_t pos)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int growable = bs->growable;
|
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);
|
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
|
||||||
bs->growable = 1;
|
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;
|
bs->growable = growable;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
37
block/rbd.c
37
block/rbd.c
|
@ -63,7 +63,8 @@
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RBD_AIO_READ,
|
RBD_AIO_READ,
|
||||||
RBD_AIO_WRITE,
|
RBD_AIO_WRITE,
|
||||||
RBD_AIO_DISCARD
|
RBD_AIO_DISCARD,
|
||||||
|
RBD_AIO_FLUSH
|
||||||
} RBDAIOCmd;
|
} RBDAIOCmd;
|
||||||
|
|
||||||
typedef struct RBDAIOCB {
|
typedef struct RBDAIOCB {
|
||||||
|
@ -379,8 +380,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
||||||
|
|
||||||
r = rcb->ret;
|
r = rcb->ret;
|
||||||
|
|
||||||
if (acb->cmd == RBD_AIO_WRITE ||
|
if (acb->cmd != RBD_AIO_READ) {
|
||||||
acb->cmd == RBD_AIO_DISCARD) {
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
acb->ret = r;
|
acb->ret = r;
|
||||||
acb->error = 1;
|
acb->error = 1;
|
||||||
|
@ -659,6 +659,16 @@ static int rbd_aio_discard_wrapper(rbd_image_t image,
|
||||||
#endif
|
#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,
|
static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
int64_t sector_num,
|
int64_t sector_num,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov,
|
||||||
|
@ -679,7 +689,7 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque);
|
acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque);
|
||||||
acb->cmd = cmd;
|
acb->cmd = cmd;
|
||||||
acb->qiov = qiov;
|
acb->qiov = qiov;
|
||||||
if (cmd == RBD_AIO_DISCARD) {
|
if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
|
||||||
acb->bounce = NULL;
|
acb->bounce = NULL;
|
||||||
} else {
|
} else {
|
||||||
acb->bounce = qemu_blockalign(bs, qiov->size);
|
acb->bounce = qemu_blockalign(bs, qiov->size);
|
||||||
|
@ -723,6 +733,9 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
case RBD_AIO_DISCARD:
|
case RBD_AIO_DISCARD:
|
||||||
r = rbd_aio_discard_wrapper(s->image, off, size, c);
|
r = rbd_aio_discard_wrapper(s->image, off, size, c);
|
||||||
break;
|
break;
|
||||||
|
case RBD_AIO_FLUSH:
|
||||||
|
r = rbd_aio_flush_wrapper(s->image, c);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -762,6 +775,16 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
|
||||||
RBD_AIO_WRITE);
|
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)
|
static int qemu_rbd_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
|
#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
|
||||||
|
@ -772,6 +795,7 @@ static int qemu_rbd_co_flush(BlockDriverState *bs)
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
|
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_readv = qemu_rbd_aio_readv,
|
||||||
.bdrv_aio_writev = qemu_rbd_aio_writev,
|
.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,
|
.bdrv_co_flush_to_disk = qemu_rbd_co_flush,
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBRBD_SUPPORTS_DISCARD
|
#ifdef LIBRBD_SUPPORTS_DISCARD
|
||||||
.bdrv_aio_discard = qemu_rbd_aio_discard,
|
.bdrv_aio_discard = qemu_rbd_aio_discard,
|
||||||
|
|
|
@ -2054,12 +2054,19 @@ cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sd_save_vmstate(BlockDriverState *bs, const uint8_t *data,
|
static int sd_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||||
int64_t pos, int size)
|
int64_t pos)
|
||||||
{
|
{
|
||||||
BDRVSheepdogState *s = bs->opaque;
|
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,
|
static int sd_load_vmstate(BlockDriverState *bs, uint8_t *data,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -239,6 +239,7 @@ virtio_blk_data_plane=""
|
||||||
gtk=""
|
gtk=""
|
||||||
gtkabi="2.0"
|
gtkabi="2.0"
|
||||||
tpm="no"
|
tpm="no"
|
||||||
|
libssh2=""
|
||||||
|
|
||||||
# parse CC options first
|
# parse CC options first
|
||||||
for opt do
|
for opt do
|
||||||
|
@ -922,6 +923,10 @@ for opt do
|
||||||
;;
|
;;
|
||||||
--enable-tpm) tpm="yes"
|
--enable-tpm) tpm="yes"
|
||||||
;;
|
;;
|
||||||
|
--disable-libssh2) libssh2="no"
|
||||||
|
;;
|
||||||
|
--enable-libssh2) libssh2="yes"
|
||||||
|
;;
|
||||||
*) echo "ERROR: unknown option $opt"; show_help="yes"
|
*) echo "ERROR: unknown option $opt"; show_help="yes"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -1182,6 +1187,8 @@ echo " --disable-glusterfs disable GlusterFS backend"
|
||||||
echo " --enable-gcov enable test coverage analysis with gcov"
|
echo " --enable-gcov enable test coverage analysis with gcov"
|
||||||
echo " --gcov=GCOV use specified gcov [$gcov_tool]"
|
echo " --gcov=GCOV use specified gcov [$gcov_tool]"
|
||||||
echo " --enable-tpm enable TPM support"
|
echo " --enable-tpm enable TPM support"
|
||||||
|
echo " --disable-libssh2 disable ssh block device support"
|
||||||
|
echo " --enable-libssh2 enable ssh block device support"
|
||||||
echo ""
|
echo ""
|
||||||
echo "NOTE: The object files are built at the place where configure is launched"
|
echo "NOTE: The object files are built at the place where configure is launched"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -2313,6 +2320,67 @@ EOF
|
||||||
fi
|
fi
|
||||||
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
|
# linux-aio probe
|
||||||
|
|
||||||
|
@ -3435,6 +3503,7 @@ echo "virtio-blk-data-plane $virtio_blk_data_plane"
|
||||||
echo "gcov $gcov_tool"
|
echo "gcov $gcov_tool"
|
||||||
echo "gcov enabled $gcov"
|
echo "gcov enabled $gcov"
|
||||||
echo "TPM support $tpm"
|
echo "TPM support $tpm"
|
||||||
|
echo "libssh2 support $libssh2"
|
||||||
|
|
||||||
if test "$sdl_too_old" = "yes"; then
|
if test "$sdl_too_old" = "yes"; then
|
||||||
echo "-> Your SDL version is too old - please upgrade to have SDL support"
|
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
|
echo "CONFIG_GLUSTERFS=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$libssh2" = "yes" ; then
|
||||||
|
echo "CONFIG_LIBSSH2=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$virtio_blk_data_plane" = "yes" ; then
|
if test "$virtio_blk_data_plane" = "yes" ; then
|
||||||
echo 'CONFIG_VIRTIO_BLK_DATA_PLANE=$(CONFIG_VIRTIO)' >> $config_host_mak
|
echo 'CONFIG_VIRTIO_BLK_DATA_PLANE=$(CONFIG_VIRTIO)' >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1262,6 +1262,10 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
|
||||||
lba48 = 1;
|
lba48 = 1;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case WIN_READ_NATIVE_MAX:
|
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_cmd_lba48_transform(s, lba48);
|
||||||
ide_set_sector(s, s->nb_sectors - 1);
|
ide_set_sector(s, s->nb_sectors - 1);
|
||||||
s->status = READY_STAT | SEEK_STAT;
|
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);
|
uint8_t *buf, int nb_sectors);
|
||||||
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
|
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
|
||||||
const uint8_t *buf, int nb_sectors);
|
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,
|
int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
||||||
void *buf, int count);
|
void *buf, int count);
|
||||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||||
const void *buf, int count);
|
const void *buf, int count);
|
||||||
|
int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov);
|
||||||
int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
|
int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
|
||||||
const void *buf, int count);
|
const void *buf, int count);
|
||||||
int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
|
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 *base_path,
|
||||||
const char *filename);
|
const char *filename);
|
||||||
|
|
||||||
|
int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
||||||
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||||
int64_t pos, int size);
|
int64_t pos, int size);
|
||||||
|
|
||||||
|
|
|
@ -164,8 +164,8 @@ struct BlockDriver {
|
||||||
const char *snapshot_name);
|
const char *snapshot_name);
|
||||||
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
||||||
|
|
||||||
int (*bdrv_save_vmstate)(BlockDriverState *bs, const uint8_t *buf,
|
int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||||
int64_t pos, int size);
|
int64_t pos);
|
||||||
int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
|
int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
|
||||||
int64_t pos, int size);
|
int64_t pos, int size);
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ typedef int (QEMUFileGetFD)(void *opaque);
|
||||||
* This function writes an iovec to file.
|
* This function writes an iovec to file.
|
||||||
*/
|
*/
|
||||||
typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
|
typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
|
||||||
int iovcnt);
|
int iovcnt, int64_t pos);
|
||||||
|
|
||||||
typedef struct QEMUFileOps {
|
typedef struct QEMUFileOps {
|
||||||
QEMUFilePutBufferFunc *put_buffer;
|
QEMUFilePutBufferFunc *put_buffer;
|
||||||
|
|
|
@ -423,6 +423,7 @@ snapshots.
|
||||||
* disk_images_sheepdog:: Sheepdog disk images
|
* disk_images_sheepdog:: Sheepdog disk images
|
||||||
* disk_images_iscsi:: iSCSI LUNs
|
* disk_images_iscsi:: iSCSI LUNs
|
||||||
* disk_images_gluster:: GlusterFS disk images
|
* disk_images_gluster:: GlusterFS disk images
|
||||||
|
* disk_images_ssh:: Secure Shell (ssh) disk images
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node disk_images_quickstart
|
@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
|
qemu-system-x86_64 -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
|
||||||
@end example
|
@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
|
@node pcsys_network
|
||||||
@section Network emulation
|
@section Network emulation
|
||||||
|
|
||||||
|
|
|
@ -2107,6 +2107,18 @@ Example for Unix Domain Sockets
|
||||||
qemu-system-i386 --drive file=nbd:unix:/tmp/nbd-socket
|
qemu-system-i386 --drive file=nbd:unix:/tmp/nbd-socket
|
||||||
@end example
|
@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
|
@item Sheepdog
|
||||||
Sheepdog is a distributed storage system for QEMU.
|
Sheepdog is a distributed storage system for QEMU.
|
||||||
QEMU supports using either local sheepdog devices or remote networked
|
QEMU supports using either local sheepdog devices or remote networked
|
||||||
|
|
21
savevm.c
21
savevm.c
|
@ -175,7 +175,8 @@ static void coroutine_fn yield_until_fd_readable(int fd)
|
||||||
qemu_coroutine_yield();
|
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;
|
QEMUFileSocket *s = opaque;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
@ -457,6 +458,21 @@ fail:
|
||||||
return NULL;
|
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,
|
static int block_put_buffer(void *opaque, const uint8_t *buf,
|
||||||
int64_t pos, int size)
|
int64_t pos, int size)
|
||||||
{
|
{
|
||||||
|
@ -481,6 +497,7 @@ static const QEMUFileOps bdrv_read_ops = {
|
||||||
|
|
||||||
static const QEMUFileOps bdrv_write_ops = {
|
static const QEMUFileOps bdrv_write_ops = {
|
||||||
.put_buffer = block_put_buffer,
|
.put_buffer = block_put_buffer,
|
||||||
|
.writev_buffer = block_writev_buffer,
|
||||||
.close = bdrv_fclose
|
.close = bdrv_fclose
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -535,7 +552,7 @@ static void qemu_fflush(QEMUFile *f)
|
||||||
|
|
||||||
if (f->ops->writev_buffer) {
|
if (f->ops->writev_buffer) {
|
||||||
if (f->iovcnt > 0) {
|
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 {
|
} else {
|
||||||
if (f->buf_index > 0) {
|
if (f->buf_index > 0) {
|
||||||
|
|
|
@ -61,10 +61,23 @@ $QEMU_IO -c "read -pP 0xa 0 $size" $TEST_IMG | _filter_qemu_io
|
||||||
echo
|
echo
|
||||||
echo "unaligned pwrite"
|
echo "unaligned pwrite"
|
||||||
$QEMU_IO -c 'write -pP 0xab 66 42' $TEST_IMG | _filter_qemu_io
|
$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
|
||||||
echo "verify pattern"
|
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 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
|
# success, all done
|
||||||
echo "*** done"
|
echo "*** done"
|
||||||
|
|
|
@ -16,8 +16,34 @@ read 134217728/134217728 bytes at offset 0
|
||||||
unaligned pwrite
|
unaligned pwrite
|
||||||
wrote 42/42 bytes at offset 66
|
wrote 42/42 bytes at offset 66
|
||||||
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
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
|
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
|
read 42/42 bytes at offset 66
|
||||||
42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
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
|
*** done
|
||||||
|
|
|
@ -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
|
|
@ -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
|
-rbd test rbd
|
||||||
-sheepdog test sheepdog
|
-sheepdog test sheepdog
|
||||||
-nbd test nbd
|
-nbd test nbd
|
||||||
|
-ssh test ssh
|
||||||
-xdiff graphical mode diff
|
-xdiff graphical mode diff
|
||||||
-nocache use O_DIRECT on backing file
|
-nocache use O_DIRECT on backing file
|
||||||
-misalign misalign memory allocations
|
-misalign misalign memory allocations
|
||||||
|
@ -206,6 +207,10 @@ testlist options
|
||||||
IMGPROTO=nbd
|
IMGPROTO=nbd
|
||||||
xpand=false
|
xpand=false
|
||||||
;;
|
;;
|
||||||
|
-ssh)
|
||||||
|
IMGPROTO=ssh
|
||||||
|
xpand=false
|
||||||
|
;;
|
||||||
-nocache)
|
-nocache)
|
||||||
QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --nocache"
|
QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --nocache"
|
||||||
xpand=false
|
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)/"
|
_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
|
# make sure this script returns success
|
||||||
/bin/true
|
/bin/true
|
||||||
|
|
|
@ -52,6 +52,9 @@ if [ "$IMGPROTO" = "file" ]; then
|
||||||
elif [ "$IMGPROTO" = "nbd" ]; then
|
elif [ "$IMGPROTO" = "nbd" ]; then
|
||||||
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
||||||
TEST_IMG="nbd:127.0.0.1:10810"
|
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
|
else
|
||||||
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
|
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -57,4 +57,5 @@
|
||||||
048 img auto quick
|
048 img auto quick
|
||||||
049 rw auto
|
049 rw auto
|
||||||
050 rw auto backing quick
|
050 rw auto backing quick
|
||||||
|
051 rw auto
|
||||||
052 rw auto backing
|
052 rw auto backing
|
||||||
|
|
Loading…
Reference in New Issue