summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-08-11 15:11:50 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-08-11 15:11:50 +0100
commit9db6ffc76676731a25a5538ab71e8ca6ac234f80 (patch)
treecdfb74c60955bdc2490338a75fd8976777e94014
parent95766c2cd04395e5712b4d5967b3251f35d537df (diff)
parent8565c3ab537e78f3e69977ec2c609dc9417a806e (diff)
downloadqemu-9db6ffc76676731a25a5538ab71e8ca6ac234f80.tar.gz
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.10.0-rc3 # gpg: Signature made Fri 11 Aug 2017 15:02:58 BST # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: qemu-iotests: fix 185 file-posix: Do runtime check for ofd lock API osdep: Add runtime OFD lock detection qcow2: Check failure of bdrv_getlength() qcow2: Drop debugging dump_refcounts() vpc: Check failure of bdrv_getlength() tests/multiboot: Fix whitespace failure Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--block/file-posix.c19
-rw-r--r--block/qcow2.c26
-rw-r--r--block/vpc.c9
-rw-r--r--include/qemu/osdep.h1
-rwxr-xr-xtests/multiboot/run_test.sh2
-rwxr-xr-xtests/qemu-iotests/1854
-rw-r--r--util/osdep.c66
7 files changed, 82 insertions, 45 deletions
diff --git a/block/file-posix.c b/block/file-posix.c
index f4de022ae0..cb3bfce147 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -457,22 +457,19 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
switch (locking) {
case ON_OFF_AUTO_ON:
s->use_lock = true;
-#ifndef F_OFD_SETLK
- fprintf(stderr,
- "File lock requested but OFD locking syscall is unavailable, "
- "falling back to POSIX file locks.\n"
- "Due to the implementation, locks can be lost unexpectedly.\n");
-#endif
+ if (!qemu_has_ofd_lock()) {
+ fprintf(stderr,
+ "File lock requested but OFD locking syscall is "
+ "unavailable, falling back to POSIX file locks.\n"
+ "Due to the implementation, locks can be lost "
+ "unexpectedly.\n");
+ }
break;
case ON_OFF_AUTO_OFF:
s->use_lock = false;
break;
case ON_OFF_AUTO_AUTO:
-#ifdef F_OFD_SETLK
- s->use_lock = true;
-#else
- s->use_lock = false;
-#endif
+ s->use_lock = qemu_has_ofd_lock();
break;
default:
abort();
diff --git a/block/qcow2.c b/block/qcow2.c
index d7c600b5a2..40ba26c111 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3282,12 +3282,15 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
z_stream strm;
int ret, out_len;
uint8_t *buf, *out_buf;
- uint64_t cluster_offset;
+ int64_t cluster_offset;
if (bytes == 0) {
/* align end of file to a sector boundary to ease reading with
sector based I/Os */
cluster_offset = bdrv_getlength(bs->file->bs);
+ if (cluster_offset < 0) {
+ return cluster_offset;
+ }
return bdrv_truncate(bs->file, cluster_offset, PREALLOC_MODE_OFF, NULL);
}
@@ -3798,27 +3801,6 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
return spec_info;
}
-#if 0
-static void dump_refcounts(BlockDriverState *bs)
-{
- BDRVQcow2State *s = bs->opaque;
- int64_t nb_clusters, k, k1, size;
- int refcount;
-
- size = bdrv_getlength(bs->file->bs);
- nb_clusters = size_to_clusters(s, size);
- for(k = 0; k < nb_clusters;) {
- k1 = k;
- refcount = get_refcount(bs, k);
- k++;
- while (k < nb_clusters && get_refcount(bs, k) == refcount)
- k++;
- printf("%" PRId64 ": refcount=%d nb=%" PRId64 "\n", k, refcount,
- k - k1);
- }
-}
-#endif
-
static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
int64_t pos)
{
diff --git a/block/vpc.c b/block/vpc.c
index 574879ba7c..82911ebead 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -219,6 +219,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
uint64_t pagetable_size;
int disk_type = VHD_DYNAMIC;
int ret;
+ int64_t bs_size;
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
false, errp);
@@ -411,7 +412,13 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
}
}
- if (s->free_data_block_offset > bdrv_getlength(bs->file->bs)) {
+ bs_size = bdrv_getlength(bs->file->bs);
+ if (bs_size < 0) {
+ error_setg_errno(errp, -bs_size, "Unable to learn image size");
+ ret = bs_size;
+ goto fail;
+ }
+ if (s->free_data_block_offset > bs_size) {
error_setg(errp, "block-vpc: free_data_block_offset points after "
"the end of file. The image has been truncated.");
ret = -EINVAL;
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 3b74f6fcb2..6855b94bbf 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -357,6 +357,7 @@ int qemu_dup(int fd);
int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive);
int qemu_unlock_fd(int fd, int64_t start, int64_t len);
int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive);
+bool qemu_has_ofd_lock(void);
#if defined(__HAIKU__) && defined(__i386__)
#define FMT_pid "%ld"
diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh
index c8f3da8f37..0278148b43 100755
--- a/tests/multiboot/run_test.sh
+++ b/tests/multiboot/run_test.sh
@@ -26,7 +26,7 @@ run_qemu() {
local kernel=$1
shift
- printf %b "\n\n=== Running test case: $kernel $@ ===\n\n" >> test.log
+ printf %b "\n\n=== Running test case: $kernel $* ===\n\n" >> test.log
$QEMU \
-kernel $kernel \
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
index 0eda371f27..f5b47e4c1a 100755
--- a/tests/qemu-iotests/185
+++ b/tests/qemu-iotests/185
@@ -156,6 +156,10 @@ _send_qemu_cmd $h \
'speed': 65536 } }" \
"return"
+# If we don't sleep here 'quit' command may be handled before
+# the first mirror iteration is done
+sleep 0.5
+
_send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
wait=1 _cleanup_qemu
diff --git a/util/osdep.c b/util/osdep.c
index a2863c8e53..a479fedc4a 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -38,14 +38,6 @@ extern int madvise(caddr_t, size_t, int);
#include "qemu/error-report.h"
#include "monitor/monitor.h"
-#ifdef F_OFD_SETLK
-#define QEMU_SETLK F_OFD_SETLK
-#define QEMU_GETLK F_OFD_GETLK
-#else
-#define QEMU_SETLK F_SETLK
-#define QEMU_GETLK F_GETLK
-#endif
-
static bool fips_enabled = false;
static const char *hw_version = QEMU_HW_VERSION;
@@ -82,6 +74,10 @@ int qemu_madvise(void *addr, size_t len, int advice)
}
#ifndef _WIN32
+
+static int fcntl_op_setlk = -1;
+static int fcntl_op_getlk = -1;
+
/*
* Dups an fd and sets the flags
*/
@@ -149,6 +145,54 @@ static int qemu_parse_fdset(const char *param)
return qemu_parse_fd(param);
}
+static void qemu_probe_lock_ops(void)
+{
+ if (fcntl_op_setlk == -1) {
+#ifdef F_OFD_SETLK
+ int fd;
+ int ret;
+ struct flock fl = {
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = 0,
+ .l_type = F_WRLCK,
+ };
+
+ fd = open("/dev/null", O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr,
+ "Failed to open /dev/null for OFD lock probing: %s\n",
+ strerror(errno));
+ fcntl_op_setlk = F_SETLK;
+ fcntl_op_getlk = F_GETLK;
+ return;
+ }
+ ret = fcntl(fd, F_OFD_GETLK, &fl);
+ close(fd);
+ if (!ret) {
+ fcntl_op_setlk = F_OFD_SETLK;
+ fcntl_op_getlk = F_OFD_GETLK;
+ } else {
+ fcntl_op_setlk = F_SETLK;
+ fcntl_op_getlk = F_GETLK;
+ }
+#else
+ fcntl_op_setlk = F_SETLK;
+ fcntl_op_getlk = F_GETLK;
+#endif
+ }
+}
+
+bool qemu_has_ofd_lock(void)
+{
+ qemu_probe_lock_ops();
+#ifdef F_OFD_SETLK
+ return fcntl_op_setlk == F_OFD_SETLK;
+#else
+ return false;
+#endif
+}
+
static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
{
int ret;
@@ -158,7 +202,8 @@ static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
.l_len = len,
.l_type = fl_type,
};
- ret = fcntl(fd, QEMU_SETLK, &fl);
+ qemu_probe_lock_ops();
+ ret = fcntl(fd, fcntl_op_setlk, &fl);
return ret == -1 ? -errno : 0;
}
@@ -181,7 +226,8 @@ int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive)
.l_len = len,
.l_type = exclusive ? F_WRLCK : F_RDLCK,
};
- ret = fcntl(fd, QEMU_GETLK, &fl);
+ qemu_probe_lock_ops();
+ ret = fcntl(fd, fcntl_op_getlk, &fl);
if (ret == -1) {
return -errno;
} else {