- kvm: ioeventfd fix for PPC64LE
- virtio-scsi: misc fixes - fix for --enable-profiler - nbd: fixes from Max - build: fix for scripts/make_device_config.sh - exec: fix for address_space_translate -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEbBAABAgAGBQJVCV1MAAoJEL/70l94x66DU48H+K2Dbic2jTL5tPQ5Tq9te74u 097ysrMmHwxa71/XJJVex78mzuO/QdayinsaAFRpafeOhB2LNyQAtTRKm6mrT6dz 7el3Wc0T3qQpNgZf+4wPWCHunmtJ9dbKevdQwML2YFMYiT9gCiGQqwKztVfW/lR9 98jiQi828cNhsAbLAsAuEvV6LX/MYiUoZH9SZsLYLuUocEZzYy1TpQFjytTWjFFH RqeFUYMvoXBShh4kt6wJ7/D+jCwwkBa4pmv2XpxXVlpxgcbN9S5J1HF4tw6fSYT2 RDzhebdlITPt0YQNygRmmoQAaI6wa014sZ1g4OW7W4TbwsNRBURayGpYUExZRw== =VW8Q -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging - kvm: ioeventfd fix for PPC64LE - virtio-scsi: misc fixes - fix for --enable-profiler - nbd: fixes from Max - build: fix for scripts/make_device_config.sh - exec: fix for address_space_translate # gpg: Signature made Wed Mar 18 11:11:08 2015 GMT using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: exec: Respect as_tranlsate_internal length clamp virtio-scsi-dataplane: fix memory leak in virtio_scsi_vring_init profiler: Reenable built-in profiler kvm: fix ioeventfd endianness on bi-endian architectures virtio-scsi: Fix assert in virtio_scsi_push_event build: pass .d file name to scripts/make_device_config.sh, fix makefile target coroutine-io: Return -errno in case of error nbd: Drop unexpected data for NBD_OPT_LIST nbd: Fix interpretation of the export flags nbd: Fix nbd_receive_options() nbd: Set block size to BDRV_SECTOR_SIZE nbd: Fix potential signed overflow issues qemu-nbd: fork() can fail nbd: Handle blk_getlength() failure nbd: Pass return value from nbd_handle_list() nbd: Fix nbd_establish_connection()'s return value qemu-nbd: Detect unused partitions by system == 0 util/uri: Add overflow check to rfc3986_parse_port nbd: Fix overflow return value Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1f3500976d
3
Makefile
3
Makefile
@ -112,7 +112,8 @@ endif
|
||||
-include $(SUBDIR_DEVICES_MAK_DEP)
|
||||
|
||||
%/config-devices.mak: default-configs/%.mak
|
||||
$(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/make_device_config.sh $@.tmp $<, " GEN $@.tmp")
|
||||
$(call quiet-command, \
|
||||
$(SHELL) $(SRC_PATH)/scripts/make_device_config.sh $< $*-config-devices.mak.d $@ > $@.tmp, " GEN $@.tmp")
|
||||
$(call quiet-command, if test -f $@; then \
|
||||
if cmp -s $@.old $@; then \
|
||||
mv $@.tmp $@; \
|
||||
|
@ -386,8 +386,7 @@ int nbd_client_init(BlockDriverState *bs, int sock, const char *export,
|
||||
logout("session init %s\n", export);
|
||||
qemu_set_block(sock);
|
||||
ret = nbd_receive_negotiate(sock, export,
|
||||
&client->nbdflags, &client->size,
|
||||
&client->blocksize, errp);
|
||||
&client->nbdflags, &client->size, errp);
|
||||
if (ret < 0) {
|
||||
logout("Failed to negotiate with the NBD server\n");
|
||||
closesocket(sock);
|
||||
|
@ -20,7 +20,6 @@ typedef struct NbdClientSession {
|
||||
int sock;
|
||||
uint32_t nbdflags;
|
||||
off_t size;
|
||||
size_t blocksize;
|
||||
|
||||
CoMutex send_mutex;
|
||||
CoMutex free_sema;
|
||||
|
@ -248,7 +248,7 @@ static int nbd_establish_connection(BlockDriverState *bs, Error **errp)
|
||||
/* Failed to establish connection */
|
||||
if (sock < 0) {
|
||||
logout("Failed to establish connection to NBD server\n");
|
||||
return -errno;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return sock;
|
||||
|
@ -105,7 +105,11 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
|
||||
writable = false;
|
||||
}
|
||||
|
||||
exp = nbd_export_new(blk, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL);
|
||||
exp = nbd_export_new(blk, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL,
|
||||
errp);
|
||||
if (!exp) {
|
||||
return;
|
||||
}
|
||||
|
||||
nbd_export_set_name(exp, device);
|
||||
|
||||
|
2
cpus.c
2
cpus.c
@ -1353,7 +1353,7 @@ static int tcg_cpu_exec(CPUArchState *env)
|
||||
}
|
||||
ret = cpu_exec(env);
|
||||
#ifdef CONFIG_PROFILER
|
||||
qemu_time += profile_getclock() - ti;
|
||||
tcg_time += profile_getclock() - ti;
|
||||
#endif
|
||||
if (use_icount) {
|
||||
/* Fold pending instructions back into the
|
||||
|
6
exec.c
6
exec.c
@ -380,7 +380,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
IOMMUTLBEntry iotlb;
|
||||
MemoryRegionSection *section;
|
||||
MemoryRegion *mr;
|
||||
hwaddr len = *plen;
|
||||
|
||||
rcu_read_lock();
|
||||
for (;;) {
|
||||
@ -395,7 +394,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
iotlb = mr->iommu_ops->translate(mr, addr, is_write);
|
||||
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
|
||||
| (addr & iotlb.addr_mask));
|
||||
len = MIN(len, (addr | iotlb.addr_mask) - addr + 1);
|
||||
*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
|
||||
if (!(iotlb.perm & (1 << is_write))) {
|
||||
mr = &io_mem_unassigned;
|
||||
break;
|
||||
@ -406,10 +405,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
|
||||
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
||||
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
|
||||
len = MIN(page, len);
|
||||
*plen = MIN(page, *plen);
|
||||
}
|
||||
|
||||
*plen = len;
|
||||
*xlat = addr;
|
||||
rcu_read_unlock();
|
||||
return mr;
|
||||
|
@ -45,7 +45,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s,
|
||||
{
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||
VirtIOSCSIVring *r = g_slice_new(VirtIOSCSIVring);
|
||||
VirtIOSCSIVring *r;
|
||||
int rc;
|
||||
|
||||
/* Set up virtqueue notify */
|
||||
@ -56,6 +56,8 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s,
|
||||
s->dataplane_fenced = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = g_slice_new(VirtIOSCSIVring);
|
||||
r->host_notifier = *virtio_queue_get_host_notifier(vq);
|
||||
r->guest_notifier = *virtio_queue_get_guest_notifier(vq);
|
||||
aio_set_event_notifier(s->ctx, &r->host_notifier, handler);
|
||||
|
@ -146,8 +146,12 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
|
||||
* TODO: always disable this workaround for virtio 1.0 devices.
|
||||
*/
|
||||
if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
|
||||
req_size = req->elem.out_sg[0].iov_len;
|
||||
resp_size = req->elem.in_sg[0].iov_len;
|
||||
if (req->elem.out_num) {
|
||||
req_size = req->elem.out_sg[0].iov_len;
|
||||
}
|
||||
if (req->elem.in_num) {
|
||||
resp_size = req->elem.in_sg[0].iov_len;
|
||||
}
|
||||
}
|
||||
|
||||
out_size = qemu_sgl_concat(req, req->elem.out_sg,
|
||||
|
@ -54,8 +54,8 @@ struct nbd_reply {
|
||||
/* Reply types. */
|
||||
#define NBD_REP_ACK (1) /* Data sending finished. */
|
||||
#define NBD_REP_SERVER (2) /* Export description. */
|
||||
#define NBD_REP_ERR_UNSUP ((1 << 31) | 1) /* Unknown option. */
|
||||
#define NBD_REP_ERR_INVALID ((1 << 31) | 3) /* Invalid length. */
|
||||
#define NBD_REP_ERR_UNSUP ((UINT32_C(1) << 31) | 1) /* Unknown option. */
|
||||
#define NBD_REP_ERR_INVALID ((UINT32_C(1) << 31) | 3) /* Invalid length. */
|
||||
|
||||
#define NBD_CMD_MASK_COMMAND 0x0000ffff
|
||||
#define NBD_CMD_FLAG_FUA (1 << 16)
|
||||
@ -75,8 +75,8 @@ enum {
|
||||
|
||||
ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
|
||||
int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
|
||||
off_t *size, size_t *blocksize, Error **errp);
|
||||
int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize);
|
||||
off_t *size, Error **errp);
|
||||
int nbd_init(int fd, int csock, uint32_t flags, off_t size);
|
||||
ssize_t nbd_send_request(int csock, struct nbd_request *request);
|
||||
ssize_t nbd_receive_reply(int csock, struct nbd_reply *reply);
|
||||
int nbd_client(int fd);
|
||||
@ -86,7 +86,8 @@ typedef struct NBDExport NBDExport;
|
||||
typedef struct NBDClient NBDClient;
|
||||
|
||||
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
uint32_t nbdflags, void (*close)(NBDExport *));
|
||||
uint32_t nbdflags, void (*close)(NBDExport *),
|
||||
Error **errp);
|
||||
void nbd_export_close(NBDExport *exp);
|
||||
void nbd_export_get(NBDExport *exp);
|
||||
void nbd_export_put(NBDExport *exp);
|
||||
|
@ -999,11 +999,10 @@ static inline int64_t cpu_get_real_ticks (void)
|
||||
#ifdef CONFIG_PROFILER
|
||||
static inline int64_t profile_getclock(void)
|
||||
{
|
||||
return cpu_get_real_ticks();
|
||||
return get_clock();
|
||||
}
|
||||
|
||||
extern int64_t qemu_time, qemu_time_start;
|
||||
extern int64_t tlb_flush_time;
|
||||
extern int64_t tcg_time;
|
||||
extern int64_t dev_time;
|
||||
#endif
|
||||
|
||||
|
24
kvm-all.c
24
kvm-all.c
@ -528,13 +528,33 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size)
|
||||
{
|
||||
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
|
||||
/* The kernel expects ioeventfd values in HOST_WORDS_BIGENDIAN
|
||||
* endianness, but the memory core hands them in target endianness.
|
||||
* For example, PPC is always treated as big-endian even if running
|
||||
* on KVM and on PPC64LE. Correct here.
|
||||
*/
|
||||
switch (size) {
|
||||
case 2:
|
||||
val = bswap16(val);
|
||||
break;
|
||||
case 4:
|
||||
val = bswap32(val);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
static int kvm_set_ioeventfd_mmio(int fd, hwaddr addr, uint32_t val,
|
||||
bool assign, uint32_t size, bool datamatch)
|
||||
{
|
||||
int ret;
|
||||
struct kvm_ioeventfd iofd;
|
||||
|
||||
iofd.datamatch = datamatch ? val : 0;
|
||||
iofd.datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0;
|
||||
iofd.addr = addr;
|
||||
iofd.len = size;
|
||||
iofd.flags = 0;
|
||||
@ -564,7 +584,7 @@ static int kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint16_t val,
|
||||
bool assign, uint32_t size, bool datamatch)
|
||||
{
|
||||
struct kvm_ioeventfd kick = {
|
||||
.datamatch = datamatch ? val : 0,
|
||||
.datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0,
|
||||
.addr = addr,
|
||||
.flags = KVM_IOEVENTFD_FLAG_PIO,
|
||||
.len = size,
|
||||
|
@ -1975,7 +1975,7 @@ static void hmp_info_numa(Monitor *mon, const QDict *qdict)
|
||||
|
||||
#ifdef CONFIG_PROFILER
|
||||
|
||||
int64_t qemu_time;
|
||||
int64_t tcg_time;
|
||||
int64_t dev_time;
|
||||
|
||||
static void hmp_info_profile(Monitor *mon, const QDict *qdict)
|
||||
@ -1983,8 +1983,8 @@ static void hmp_info_profile(Monitor *mon, const QDict *qdict)
|
||||
monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
|
||||
dev_time, dev_time / (double)get_ticks_per_sec());
|
||||
monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
|
||||
qemu_time, qemu_time / (double)get_ticks_per_sec());
|
||||
qemu_time = 0;
|
||||
tcg_time, tcg_time / (double)get_ticks_per_sec());
|
||||
tcg_time = 0;
|
||||
dev_time = 0;
|
||||
}
|
||||
#else
|
||||
|
112
nbd.c
112
nbd.c
@ -193,6 +193,26 @@ static ssize_t read_sync(int fd, void *buffer, size_t size)
|
||||
return nbd_wr_sync(fd, buffer, size, true);
|
||||
}
|
||||
|
||||
static ssize_t drop_sync(int fd, size_t size)
|
||||
{
|
||||
ssize_t ret, dropped = size;
|
||||
uint8_t *buffer = g_malloc(MIN(65536, size));
|
||||
|
||||
while (size > 0) {
|
||||
ret = read_sync(fd, buffer, MIN(65536, size));
|
||||
if (ret < 0) {
|
||||
g_free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert(ret <= size);
|
||||
size -= ret;
|
||||
}
|
||||
|
||||
g_free(buffer);
|
||||
return dropped;
|
||||
}
|
||||
|
||||
static ssize_t write_sync(int fd, void *buffer, size_t size)
|
||||
{
|
||||
int ret;
|
||||
@ -303,6 +323,9 @@ static int nbd_handle_list(NBDClient *client, uint32_t length)
|
||||
|
||||
csock = client->sock;
|
||||
if (length) {
|
||||
if (drop_sync(csock, length) != length) {
|
||||
return -EIO;
|
||||
}
|
||||
return nbd_send_rep(csock, NBD_REP_ERR_INVALID, NBD_OPT_LIST);
|
||||
}
|
||||
|
||||
@ -350,30 +373,39 @@ fail:
|
||||
|
||||
static int nbd_receive_options(NBDClient *client)
|
||||
{
|
||||
int csock = client->sock;
|
||||
uint32_t flags;
|
||||
|
||||
/* Client sends:
|
||||
[ 0 .. 3] client flags
|
||||
|
||||
[ 0 .. 7] NBD_OPTS_MAGIC
|
||||
[ 8 .. 11] NBD option
|
||||
[12 .. 15] Data length
|
||||
... Rest of request
|
||||
|
||||
[ 0 .. 7] NBD_OPTS_MAGIC
|
||||
[ 8 .. 11] Second NBD option
|
||||
[12 .. 15] Data length
|
||||
... Rest of request
|
||||
*/
|
||||
|
||||
if (read_sync(csock, &flags, sizeof(flags)) != sizeof(flags)) {
|
||||
LOG("read failed");
|
||||
return -EIO;
|
||||
}
|
||||
TRACE("Checking client flags");
|
||||
be32_to_cpus(&flags);
|
||||
if (flags != 0 && flags != NBD_FLAG_C_FIXED_NEWSTYLE) {
|
||||
LOG("Bad client flags received");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int csock = client->sock;
|
||||
int ret;
|
||||
uint32_t tmp, length;
|
||||
uint64_t magic;
|
||||
|
||||
/* Client sends:
|
||||
[ 0 .. 3] client flags
|
||||
[ 4 .. 11] NBD_OPTS_MAGIC
|
||||
[12 .. 15] NBD option
|
||||
[16 .. 19] length
|
||||
... Rest of request
|
||||
*/
|
||||
|
||||
if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
|
||||
LOG("read failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
TRACE("Checking client flags");
|
||||
tmp = be32_to_cpu(tmp);
|
||||
if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
|
||||
LOG("Bad client flags received");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
|
||||
LOG("read failed");
|
||||
return -EINVAL;
|
||||
@ -398,8 +430,9 @@ static int nbd_receive_options(NBDClient *client)
|
||||
TRACE("Checking option");
|
||||
switch (be32_to_cpu(tmp)) {
|
||||
case NBD_OPT_LIST:
|
||||
if (nbd_handle_list(client, length) < 0) {
|
||||
return 1;
|
||||
ret = nbd_handle_list(client, length);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -494,7 +527,7 @@ fail:
|
||||
}
|
||||
|
||||
int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
|
||||
off_t *size, size_t *blocksize, Error **errp)
|
||||
off_t *size, Error **errp)
|
||||
{
|
||||
char buf[256];
|
||||
uint64_t magic, s;
|
||||
@ -602,7 +635,6 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
|
||||
goto fail;
|
||||
}
|
||||
*size = be64_to_cpu(s);
|
||||
*blocksize = 1024;
|
||||
TRACE("Size is %" PRIu64, *size);
|
||||
|
||||
if (!name) {
|
||||
@ -616,7 +648,7 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
|
||||
error_setg(errp, "Failed to read export flags");
|
||||
goto fail;
|
||||
}
|
||||
*flags |= be32_to_cpu(tmp);
|
||||
*flags |= be16_to_cpu(tmp);
|
||||
}
|
||||
if (read_sync(csock, &buf, 124) != 124) {
|
||||
error_setg(errp, "Failed to read reserved block");
|
||||
@ -629,7 +661,7 @@ fail:
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
|
||||
int nbd_init(int fd, int csock, uint32_t flags, off_t size)
|
||||
{
|
||||
TRACE("Setting NBD socket");
|
||||
|
||||
@ -639,17 +671,17 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
|
||||
return -serrno;
|
||||
}
|
||||
|
||||
TRACE("Setting block size to %lu", (unsigned long)blocksize);
|
||||
TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE);
|
||||
|
||||
if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) < 0) {
|
||||
if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) {
|
||||
int serrno = errno;
|
||||
LOG("Failed setting NBD block size");
|
||||
return -serrno;
|
||||
}
|
||||
|
||||
TRACE("Setting size to %zd block(s)", (size_t)(size / blocksize));
|
||||
TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE));
|
||||
|
||||
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) < 0) {
|
||||
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / (size_t)BDRV_SECTOR_SIZE) < 0) {
|
||||
int serrno = errno;
|
||||
LOG("Failed setting size (in blocks)");
|
||||
return -serrno;
|
||||
@ -714,7 +746,7 @@ int nbd_client(int fd)
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
|
||||
int nbd_init(int fd, int csock, uint32_t flags, off_t size)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
@ -965,7 +997,8 @@ static void blk_aio_detach(void *opaque)
|
||||
}
|
||||
|
||||
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
uint32_t nbdflags, void (*close)(NBDExport *))
|
||||
uint32_t nbdflags, void (*close)(NBDExport *),
|
||||
Error **errp)
|
||||
{
|
||||
NBDExport *exp = g_malloc0(sizeof(NBDExport));
|
||||
exp->refcount = 1;
|
||||
@ -973,7 +1006,14 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
exp->blk = blk;
|
||||
exp->dev_offset = dev_offset;
|
||||
exp->nbdflags = nbdflags;
|
||||
exp->size = size == -1 ? blk_getlength(blk) : size;
|
||||
exp->size = size < 0 ? blk_getlength(blk) : size;
|
||||
if (exp->size < 0) {
|
||||
error_setg_errno(errp, -exp->size,
|
||||
"Failed to determine the NBD export's length");
|
||||
goto fail;
|
||||
}
|
||||
exp->size -= exp->size % BDRV_SECTOR_SIZE;
|
||||
|
||||
exp->close = close;
|
||||
exp->ctx = blk_get_aio_context(blk);
|
||||
blk_ref(blk);
|
||||
@ -985,6 +1025,10 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
*/
|
||||
blk_invalidate_cache(blk, NULL);
|
||||
return exp;
|
||||
|
||||
fail:
|
||||
g_free(exp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NBDExport *nbd_export_find(const char *name)
|
||||
@ -1295,7 +1339,7 @@ static void nbd_trip(void *opaque)
|
||||
default:
|
||||
LOG("invalid request type (%u) received", request.type);
|
||||
invalid_request:
|
||||
reply.error = -EINVAL;
|
||||
reply.error = EINVAL;
|
||||
error_reply:
|
||||
if (nbd_co_send_reply(req, &reply, 0) < 0) {
|
||||
goto out;
|
||||
|
@ -45,7 +45,7 @@ qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
|
||||
if (err == EAGAIN || err == EWOULDBLOCK) {
|
||||
qemu_coroutine_yield();
|
||||
} else if (done == 0) {
|
||||
return -1;
|
||||
return -err;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
30
qemu-nbd.c
30
qemu-nbd.c
@ -142,8 +142,9 @@ static void read_partition(uint8_t *p, struct partition_record *r)
|
||||
r->end_head = p[5];
|
||||
r->end_cylinder = p[7] | ((p[6] << 2) & 0x300);
|
||||
r->end_sector = p[6] & 0x3f;
|
||||
r->start_sector_abs = p[8] | p[9] << 8 | p[10] << 16 | p[11] << 24;
|
||||
r->nb_sectors_abs = p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24;
|
||||
|
||||
r->start_sector_abs = le32_to_cpup((uint32_t *)(p + 8));
|
||||
r->nb_sectors_abs = le32_to_cpup((uint32_t *)(p + 12));
|
||||
}
|
||||
|
||||
static int find_partition(BlockBackend *blk, int partition,
|
||||
@ -167,8 +168,9 @@ static int find_partition(BlockBackend *blk, int partition,
|
||||
for (i = 0; i < 4; i++) {
|
||||
read_partition(&data[446 + 16 * i], &mbr[i]);
|
||||
|
||||
if (!mbr[i].nb_sectors_abs)
|
||||
if (!mbr[i].system || !mbr[i].nb_sectors_abs) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mbr[i].system == 0xF || mbr[i].system == 0x5) {
|
||||
struct partition_record ext[4];
|
||||
@ -182,8 +184,9 @@ static int find_partition(BlockBackend *blk, int partition,
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
read_partition(&data1[446 + 16 * j], &ext[j]);
|
||||
if (!ext[j].nb_sectors_abs)
|
||||
if (!ext[j].system || !ext[j].nb_sectors_abs) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ext_partnum + j + 1) == partition) {
|
||||
*offset = (uint64_t)ext[j].start_sector_abs << 9;
|
||||
@ -276,7 +279,6 @@ static void *nbd_client_thread(void *arg)
|
||||
{
|
||||
char *device = arg;
|
||||
off_t size;
|
||||
size_t blocksize;
|
||||
uint32_t nbdflags;
|
||||
int fd, sock;
|
||||
int ret;
|
||||
@ -289,7 +291,7 @@ static void *nbd_client_thread(void *arg)
|
||||
}
|
||||
|
||||
ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
|
||||
&size, &blocksize, &local_error);
|
||||
&size, &local_error);
|
||||
if (ret < 0) {
|
||||
if (local_error) {
|
||||
fprintf(stderr, "%s\n", error_get_pretty(local_error));
|
||||
@ -305,7 +307,7 @@ static void *nbd_client_thread(void *arg)
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
ret = nbd_init(fd, sock, nbdflags, size, blocksize);
|
||||
ret = nbd_init(fd, sock, nbdflags, size);
|
||||
if (ret < 0) {
|
||||
goto out_fd;
|
||||
}
|
||||
@ -633,7 +635,9 @@ int main(int argc, char **argv)
|
||||
* print errors and exit with the proper status code.
|
||||
*/
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
if (pid < 0) {
|
||||
err(EXIT_FAILURE, "Failed to fork");
|
||||
} else if (pid == 0) {
|
||||
close(stderr_fd[0]);
|
||||
ret = qemu_daemon(1, 0);
|
||||
|
||||
@ -715,6 +719,10 @@ int main(int argc, char **argv)
|
||||
|
||||
bs->detect_zeroes = detect_zeroes;
|
||||
fd_size = blk_getlength(blk);
|
||||
if (fd_size < 0) {
|
||||
errx(EXIT_FAILURE, "Failed to determine the image length: %s",
|
||||
strerror(-fd_size));
|
||||
}
|
||||
|
||||
if (partition != -1) {
|
||||
ret = find_partition(blk, partition, &dev_offset, &fd_size);
|
||||
@ -724,7 +732,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, nbd_export_closed);
|
||||
exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, nbd_export_closed,
|
||||
&local_err);
|
||||
if (!exp) {
|
||||
errx(EXIT_FAILURE, "%s", error_get_pretty(local_err));
|
||||
}
|
||||
|
||||
if (sockpath) {
|
||||
fd = unix_socket_incoming(sockpath);
|
||||
|
@ -1,10 +1,12 @@
|
||||
#! /bin/sh
|
||||
# Construct a target device config file from a default, pulling in any
|
||||
# files from include directives.
|
||||
# Writes a target device config file to stdout, from a default and from
|
||||
# include directives therein. Also emits Makefile dependencies.
|
||||
#
|
||||
# Usage: make_device_config.sh SRC DEPFILE-NAME DEPFILE-TARGET > DEST
|
||||
|
||||
dest=$1
|
||||
dep=`dirname $1`-`basename $1`.d
|
||||
src=$2
|
||||
src=$1
|
||||
dep=$2
|
||||
target=$3
|
||||
src_dir=`dirname $src`
|
||||
all_includes=
|
||||
|
||||
@ -22,7 +24,7 @@ while [ -n "$f" ] ; do
|
||||
[ $? = 0 ] || exit 1
|
||||
all_includes="$all_includes $f"
|
||||
done
|
||||
process_includes $src > $dest
|
||||
process_includes $src
|
||||
|
||||
cat $src $all_includes | grep -v '^include' > $dest
|
||||
echo "$1: $all_includes" > $dep
|
||||
cat $src $all_includes | grep -v '^include'
|
||||
echo "$target: $all_includes" > $dep
|
||||
|
24
util/uri.c
24
util/uri.c
@ -320,19 +320,23 @@ static int
|
||||
rfc3986_parse_port(URI *uri, const char **str)
|
||||
{
|
||||
const char *cur = *str;
|
||||
int port = 0;
|
||||
|
||||
if (ISA_DIGIT(cur)) {
|
||||
if (uri != NULL)
|
||||
uri->port = 0;
|
||||
while (ISA_DIGIT(cur)) {
|
||||
if (uri != NULL)
|
||||
uri->port = uri->port * 10 + (*cur - '0');
|
||||
cur++;
|
||||
}
|
||||
*str = cur;
|
||||
return(0);
|
||||
while (ISA_DIGIT(cur)) {
|
||||
port = port * 10 + (*cur - '0');
|
||||
if (port > 65535) {
|
||||
return 1;
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
if (uri) {
|
||||
uri->port = port;
|
||||
}
|
||||
*str = cur;
|
||||
return 0;
|
||||
}
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user