summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--audio/fmodaudio.c6
-rw-r--r--block.c30
-rw-r--r--block.h10
-rw-r--r--block/cow.c22
-rw-r--r--block/qcow.c18
-rw-r--r--block/qcow2.c14
-rw-r--r--block/raw-win32.c15
-rw-r--r--block/raw.c8
-rw-r--r--block/rbd.c10
-rw-r--r--block/vdi.c2
-rw-r--r--block/vmdk.c4
-rw-r--r--block/vpc.c14
-rw-r--r--block/vvfat.c44
-rw-r--r--block_int.h14
-rw-r--r--blockdev.c10
-rwxr-xr-xconfigure6
-rw-r--r--hw/arm_sysctl.c27
-rw-r--r--hw/arm_timer.c4
-rw-r--r--hw/ide/atapi.c11
-rw-r--r--hw/ide/core.c13
-rw-r--r--hw/nand.c22
-rw-r--r--hw/omap_gpio.c2
-rw-r--r--hw/omap_intc.c6
-rw-r--r--hw/onenand.c5
-rw-r--r--hw/pc.c4
-rw-r--r--hw/pc_piix.c12
-rw-r--r--hw/pl061.c2
-rw-r--r--hw/pxa2xx.c5
-rw-r--r--hw/scsi-disk.c24
-rw-r--r--hw/tc58128.c6
-rw-r--r--linux-user/elfload.c5
-rw-r--r--linux-user/linuxload.c2
-rw-r--r--memory.c4
-rw-r--r--migration.c12
-rw-r--r--nbd.c7
-rw-r--r--os-posix.c3
-rw-r--r--posix-aio-compat.c1
-rw-r--r--qemu-char.c19
-rw-r--r--qemu-nbd.c298
-rw-r--r--qemu-sockets.c1
-rw-r--r--ui/keymaps.c12
-rw-r--r--vl.c10
43 files changed, 505 insertions, 241 deletions
diff --git a/VERSION b/VERSION
index 4a15714fa3..75a7da4bfe 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.15.91
+0.15.92
diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c
index c34cf53567..fabf84dd3b 100644
--- a/audio/fmodaudio.c
+++ b/audio/fmodaudio.c
@@ -343,7 +343,7 @@ static void fmod_fini_out (HWVoiceOut *hw)
 
 static int fmod_init_out (HWVoiceOut *hw, struct audsettings *as)
 {
-    int bits16, mode, channel;
+    int mode, channel;
     FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
     struct audsettings obt_as = *as;
 
@@ -374,7 +374,6 @@ static int fmod_init_out (HWVoiceOut *hw, struct audsettings *as)
     /* FMOD always operates on little endian frames? */
     obt_as.endianness = 0;
     audio_pcm_init_info (&hw->info, &obt_as);
-    bits16 = (mode & FSOUND_16BITS) != 0;
     hw->samples = conf.nb_samples;
     return 0;
 }
@@ -405,7 +404,7 @@ static int fmod_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
 static int fmod_init_in (HWVoiceIn *hw, struct audsettings *as)
 {
-    int bits16, mode;
+    int mode;
     FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
     struct audsettings obt_as = *as;
 
@@ -432,7 +431,6 @@ static int fmod_init_in (HWVoiceIn *hw, struct audsettings *as)
     /* FMOD always operates on little endian frames? */
     obt_as.endianness = 0;
     audio_pcm_init_info (&hw->info, &obt_as);
-    bits16 = (mode & FSOUND_16BITS) != 0;
     hw->samples = conf.nb_samples;
     return 0;
 }
diff --git a/block.c b/block.c
index 9bb236c989..86910b046c 100644
--- a/block.c
+++ b/block.c
@@ -816,6 +816,13 @@ bool bdrv_dev_has_removable_media(BlockDriverState *bs)
     return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
 }
 
+void bdrv_dev_eject_request(BlockDriverState *bs, bool force)
+{
+    if (bs->dev_ops && bs->dev_ops->eject_request_cb) {
+        bs->dev_ops->eject_request_cb(bs->dev_opaque, force);
+    }
+}
+
 bool bdrv_dev_is_tray_open(BlockDriverState *bs)
 {
     if (bs->dev_ops && bs->dev_ops->is_tray_open) {
@@ -2782,12 +2789,27 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque)
 
 int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
 {
-    if (bs->open_flags & BDRV_O_NO_FLUSH) {
+    int ret;
+
+    if (!bs->drv) {
         return 0;
-    } else if (!bs->drv) {
+    }
+
+    /* Write back cached data to the OS even with cache=unsafe */
+    if (bs->drv->bdrv_co_flush_to_os) {
+        ret = bs->drv->bdrv_co_flush_to_os(bs);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    /* But don't actually force it to the disk with cache=unsafe */
+    if (bs->open_flags & BDRV_O_NO_FLUSH) {
         return 0;
-    } else if (bs->drv->bdrv_co_flush) {
-        return bs->drv->bdrv_co_flush(bs);
+    }
+
+    if (bs->drv->bdrv_co_flush_to_disk) {
+        return bs->drv->bdrv_co_flush_to_disk(bs);
     } else if (bs->drv->bdrv_aio_flush) {
         BlockDriverAIOCB *acb;
         CoroutineIOCompletion co = {
diff --git a/block.h b/block.h
index 38cd748b60..051a25d8d6 100644
--- a/block.h
+++ b/block.h
@@ -39,6 +39,15 @@ typedef struct BlockDevOps {
      */
     void (*change_media_cb)(void *opaque, bool load);
     /*
+     * Runs when an eject request is issued from the monitor, the tray
+     * is closed, and the medium is locked.
+     * Device models that do not implement is_medium_locked will not need
+     * this callback.  Device models that can lock the medium or tray might
+     * want to implement the callback and unlock the tray when "force" is
+     * true, even if they do not support eject requests.
+     */
+    void (*eject_request_cb)(void *opaque, bool force);
+    /*
      * Is the virtual tray open?
      * Device models implement this only when the device has a tray.
      */
@@ -111,6 +120,7 @@ void bdrv_detach_dev(BlockDriverState *bs, void *dev);
 void *bdrv_get_attached_dev(BlockDriverState *bs);
 void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
                       void *opaque);
+void bdrv_dev_eject_request(BlockDriverState *bs, bool force);
 bool bdrv_dev_has_removable_media(BlockDriverState *bs);
 bool bdrv_dev_is_tray_open(BlockDriverState *bs);
 bool bdrv_dev_is_medium_locked(BlockDriverState *bs);
diff --git a/block/cow.c b/block/cow.c
index 707c0aad88..089d395c40 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -326,16 +326,18 @@ static QEMUOptionParameter cow_create_options[] = {
 };
 
 static BlockDriver bdrv_cow = {
-    .format_name	= "cow",
-    .instance_size	= sizeof(BDRVCowState),
-    .bdrv_probe		= cow_probe,
-    .bdrv_open		= cow_open,
-    .bdrv_read          = cow_co_read,
-    .bdrv_write         = cow_co_write,
-    .bdrv_close		= cow_close,
-    .bdrv_create	= cow_create,
-    .bdrv_co_flush      = cow_co_flush,
-    .bdrv_is_allocated	= cow_is_allocated,
+    .format_name    = "cow",
+    .instance_size  = sizeof(BDRVCowState),
+
+    .bdrv_probe     = cow_probe,
+    .bdrv_open      = cow_open,
+    .bdrv_close     = cow_close,
+    .bdrv_create    = cow_create,
+
+    .bdrv_read              = cow_co_read,
+    .bdrv_write             = cow_co_write,
+    .bdrv_co_flush_to_disk  = cow_co_flush,
+    .bdrv_is_allocated      = cow_is_allocated,
 
     .create_options = cow_create_options,
 };
diff --git a/block/qcow.c b/block/qcow.c
index 35e21eb6b3..adecee06c9 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -828,14 +828,16 @@ static BlockDriver bdrv_qcow = {
     .bdrv_open		= qcow_open,
     .bdrv_close		= qcow_close,
     .bdrv_create	= qcow_create,
-    .bdrv_is_allocated	= qcow_is_allocated,
-    .bdrv_set_key	= qcow_set_key,
-    .bdrv_make_empty	= qcow_make_empty,
-    .bdrv_co_readv      = qcow_co_readv,
-    .bdrv_co_writev     = qcow_co_writev,
-    .bdrv_co_flush      = qcow_co_flush,
-    .bdrv_write_compressed = qcow_write_compressed,
-    .bdrv_get_info	= qcow_get_info,
+
+    .bdrv_co_readv          = qcow_co_readv,
+    .bdrv_co_writev         = qcow_co_writev,
+    .bdrv_co_flush_to_disk  = qcow_co_flush,
+    .bdrv_is_allocated      = qcow_is_allocated,
+
+    .bdrv_set_key           = qcow_set_key,
+    .bdrv_make_empty        = qcow_make_empty,
+    .bdrv_write_compressed  = qcow_write_compressed,
+    .bdrv_get_info          = qcow_get_info,
 
     .create_options = qcow_create_options,
 };
diff --git a/block/qcow2.c b/block/qcow2.c
index ef057d31e0..5c784eee51 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1105,7 +1105,7 @@ fail:
     return ret;
 }
 
-static int qcow2_co_flush(BlockDriverState *bs)
+static int qcow2_co_flush_to_os(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
     int ret;
@@ -1124,6 +1124,11 @@ static int qcow2_co_flush(BlockDriverState *bs)
     }
     qemu_co_mutex_unlock(&s->lock);
 
+    return 0;
+}
+
+static int qcow2_co_flush_to_disk(BlockDriverState *bs)
+{
     return bdrv_co_flush(bs->file);
 }
 
@@ -1243,9 +1248,10 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_set_key       = qcow2_set_key,
     .bdrv_make_empty    = qcow2_make_empty,
 
-    .bdrv_co_readv      = qcow2_co_readv,
-    .bdrv_co_writev     = qcow2_co_writev,
-    .bdrv_co_flush      = qcow2_co_flush,
+    .bdrv_co_readv          = qcow2_co_readv,
+    .bdrv_co_writev         = qcow2_co_writev,
+    .bdrv_co_flush_to_os    = qcow2_co_flush_to_os,
+    .bdrv_co_flush_to_disk  = qcow2_co_flush_to_disk,
 
     .bdrv_co_discard        = qcow2_co_discard,
     .bdrv_truncate          = qcow2_truncate,
diff --git a/block/raw-win32.c b/block/raw-win32.c
index f5f73bcd64..e4b0b75b70 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -281,9 +281,11 @@ static BlockDriver bdrv_file = {
     .bdrv_file_open	= raw_open,
     .bdrv_close		= raw_close,
     .bdrv_create	= raw_create,
-    .bdrv_co_flush      = raw_flush,
-    .bdrv_read		= raw_read,
-    .bdrv_write		= raw_write,
+
+    .bdrv_read              = raw_read,
+    .bdrv_write             = raw_write,
+    .bdrv_co_flush_to_disk  = raw_flush,
+
     .bdrv_truncate	= raw_truncate,
     .bdrv_getlength	= raw_getlength,
     .bdrv_get_allocated_file_size
@@ -409,11 +411,12 @@ static BlockDriver bdrv_host_device = {
     .bdrv_probe_device	= hdev_probe_device,
     .bdrv_file_open	= hdev_open,
     .bdrv_close		= raw_close,
-    .bdrv_co_flush      = raw_flush,
     .bdrv_has_zero_init = hdev_has_zero_init,
 
-    .bdrv_read		= raw_read,
-    .bdrv_write	        = raw_write,
+    .bdrv_read              = raw_read,
+    .bdrv_write             = raw_write,
+    .bdrv_co_flush_to_disk  = raw_flush,
+
     .bdrv_getlength	= raw_getlength,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
diff --git a/block/raw.c b/block/raw.c
index 33cc4716d3..6098070d65 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -111,10 +111,10 @@ static BlockDriver bdrv_raw = {
     .bdrv_open          = raw_open,
     .bdrv_close         = raw_close,
 
-    .bdrv_co_readv      = raw_co_readv,
-    .bdrv_co_writev     = raw_co_writev,
-    .bdrv_co_flush      = raw_co_flush,
-    .bdrv_co_discard    = raw_co_discard,
+    .bdrv_co_readv          = raw_co_readv,
+    .bdrv_co_writev         = raw_co_writev,
+    .bdrv_co_flush_to_disk  = raw_co_flush,
+    .bdrv_co_discard        = raw_co_discard,
 
     .bdrv_probe         = raw_probe,
     .bdrv_getlength     = raw_getlength,
diff --git a/block/rbd.c b/block/rbd.c
index c684e0cb0b..9088c52d24 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -851,18 +851,18 @@ static BlockDriver bdrv_rbd = {
     .bdrv_file_open     = qemu_rbd_open,
     .bdrv_close         = qemu_rbd_close,
     .bdrv_create        = qemu_rbd_create,
-    .bdrv_co_flush      = qemu_rbd_co_flush,
     .bdrv_get_info      = qemu_rbd_getinfo,
     .create_options     = qemu_rbd_create_options,
     .bdrv_getlength     = qemu_rbd_getlength,
     .bdrv_truncate      = qemu_rbd_truncate,
     .protocol_name      = "rbd",
 
-    .bdrv_aio_readv     = qemu_rbd_aio_readv,
-    .bdrv_aio_writev    = qemu_rbd_aio_writev,
+    .bdrv_aio_readv         = qemu_rbd_aio_readv,
+    .bdrv_aio_writev        = qemu_rbd_aio_writev,
+    .bdrv_co_flush_to_disk  = qemu_rbd_co_flush,
 
-    .bdrv_snapshot_create = qemu_rbd_snap_create,
-    .bdrv_snapshot_list = qemu_rbd_snap_list,
+    .bdrv_snapshot_create   = qemu_rbd_snap_create,
+    .bdrv_snapshot_list     = qemu_rbd_snap_list,
 };
 
 static void bdrv_rbd_init(void)
diff --git a/block/vdi.c b/block/vdi.c
index 523a6409c5..684a4a87b6 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -980,7 +980,7 @@ static BlockDriver bdrv_vdi = {
     .bdrv_open = vdi_open,
     .bdrv_close = vdi_close,
     .bdrv_create = vdi_create,
-    .bdrv_co_flush = vdi_co_flush,
+    .bdrv_co_flush_to_disk = vdi_co_flush,
     .bdrv_is_allocated = vdi_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
 
diff --git a/block/vmdk.c b/block/vmdk.c
index 985006e203..e53a2f0920 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1581,8 +1581,8 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_write     = vmdk_co_write,
     .bdrv_close     = vmdk_close,
     .bdrv_create    = vmdk_create,
-    .bdrv_co_flush  = vmdk_co_flush,
-    .bdrv_is_allocated  = vmdk_is_allocated,
+    .bdrv_co_flush_to_disk  = vmdk_co_flush,
+    .bdrv_is_allocated      = vmdk_is_allocated,
     .bdrv_get_allocated_file_size  = vmdk_get_allocated_file_size,
 
     .create_options = vmdk_create_options,
diff --git a/block/vpc.c b/block/vpc.c
index 79be7d051b..39a324705d 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -617,7 +617,11 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options)
 
     memcpy(dyndisk_header->magic, "cxsparse", 8);
 
-    dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFF);
+    /*
+     * Note: The spec is actually wrong here for data_offset, it says
+     * 0xFFFFFFFF, but MS tools expect all 64 bits to be set.
+     */
+    dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);
     dyndisk_header->table_offset = be64_to_cpu(3 * 512);
     dyndisk_header->version = be32_to_cpu(0x00010000);
     dyndisk_header->block_size = be32_to_cpu(block_size);
@@ -661,14 +665,16 @@ static QEMUOptionParameter vpc_create_options[] = {
 static BlockDriver bdrv_vpc = {
     .format_name    = "vpc",
     .instance_size  = sizeof(BDRVVPCState),
+
     .bdrv_probe     = vpc_probe,
     .bdrv_open      = vpc_open,
-    .bdrv_read      = vpc_co_read,
-    .bdrv_write     = vpc_co_write,
-    .bdrv_co_flush  = vpc_co_flush,
     .bdrv_close     = vpc_close,
     .bdrv_create    = vpc_create,
 
+    .bdrv_read              = vpc_co_read,
+    .bdrv_write             = vpc_co_write,
+    .bdrv_co_flush_to_disk  = vpc_co_flush,
+
     .create_options = vpc_create_options,
 };
 
diff --git a/block/vvfat.c b/block/vvfat.c
index 8511fe523c..131680f6f4 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1254,15 +1254,15 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
 	   return -1;
 	if (s->qcow) {
 	    int n;
-	    if (s->qcow->drv->bdrv_is_allocated(s->qcow,
-			sector_num, nb_sectors-i, &n)) {
+            if (bdrv_is_allocated(s->qcow, sector_num, nb_sectors-i, &n)) {
 DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
-		if (s->qcow->drv->bdrv_read(s->qcow, sector_num, buf+i*0x200, n))
-		    return -1;
-		i += n - 1;
-		sector_num += n - 1;
-		continue;
-	    }
+                if (bdrv_read(s->qcow, sector_num, buf + i*0x200, n)) {
+                    return -1;
+                }
+                i += n - 1;
+                sector_num += n - 1;
+                continue;
+            }
 DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
 	}
 	if(sector_num<s->faked_sectors) {
@@ -1516,7 +1516,7 @@ static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
 	return 0;
 
     for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
-	was_modified = s->qcow->drv->bdrv_is_allocated(s->qcow,
+	was_modified = bdrv_is_allocated(s->qcow,
 		cluster2sector(s, cluster_num) + i, 1, &dummy);
 
     return was_modified;
@@ -1665,16 +1665,16 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
 		int64_t offset = cluster2sector(s, cluster_num);
 
 		vvfat_close_current_file(s);
-		for (i = 0; i < s->sectors_per_cluster; i++)
-		    if (!s->qcow->drv->bdrv_is_allocated(s->qcow,
-				offset + i, 1, &dummy)) {
-			if (vvfat_read(s->bs,
-				    offset, s->cluster_buffer, 1))
-			    return -1;
-			if (s->qcow->drv->bdrv_write(s->qcow,
-				    offset, s->cluster_buffer, 1))
-			    return -2;
-		    }
+                for (i = 0; i < s->sectors_per_cluster; i++) {
+                    if (!bdrv_is_allocated(s->qcow, offset + i, 1, &dummy)) {
+                        if (vvfat_read(s->bs, offset, s->cluster_buffer, 1)) {
+                            return -1;
+                        }
+                        if (bdrv_write(s->qcow, offset, s->cluster_buffer, 1)) {
+                            return -2;
+                        }
+                    }
+                }
 	    }
 	}
 
@@ -2619,7 +2619,9 @@ static int do_commit(BDRVVVFATState* s)
 	return ret;
     }
 
-    s->qcow->drv->bdrv_make_empty(s->qcow);
+    if (s->qcow->drv->bdrv_make_empty) {
+        s->qcow->drv->bdrv_make_empty(s->qcow);
+    }
 
     memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
 
@@ -2714,7 +2716,7 @@ DLOG(checkpoint());
      * Use qcow backend. Commit later.
      */
 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
-    ret = s->qcow->drv->bdrv_write(s->qcow, sector_num, buf, nb_sectors);
+    ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors);
     if (ret < 0) {
 	fprintf(stderr, "Error writing to qcow backend\n");
 	return ret;
diff --git a/block_int.h b/block_int.h
index f4547f6d93..1ec4921cc6 100644
--- a/block_int.h
+++ b/block_int.h
@@ -84,10 +84,22 @@ struct BlockDriver {
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
     int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
-    int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
     int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors);
 
+    /*
+     * Flushes all data that was already written to the OS all the way down to
+     * the disk (for example raw-posix calls fsync()).
+     */
+    int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs);
+
+    /*
+     * Flushes all internal caches to the OS. The data may still sit in a
+     * writeback cache of the host OS, but it will survive a crash of the qemu
+     * process.
+     */
+    int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
+
     int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs,
         int num_reqs);
     int (*bdrv_merge_requests)(BlockDriverState *bs, BlockRequest* a,
diff --git a/blockdev.c b/blockdev.c
index 0827bf7743..222818690d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -635,10 +635,12 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
         qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
         return -1;
     }
-    if (!force && !bdrv_dev_is_tray_open(bs)
-        && bdrv_dev_is_medium_locked(bs)) {
-        qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
-        return -1;
+    if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) {
+        bdrv_dev_eject_request(bs, force);
+        if (!force) {
+            qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
+            return -1;
+        }
     }
     bdrv_close(bs);
     return 0;
diff --git a/configure b/configure
index 8d85d232c1..6c77fbb1a5 100755
--- a/configure
+++ b/configure
@@ -1963,13 +1963,17 @@ if test "$attr" != "no" ; then
   cat > $TMPC <<EOF
 #include <stdio.h>
 #include <sys/types.h>
+#ifdef CONFIG_LIBATTR
+#include <attr/xattr.h>
+#else
 #include <sys/xattr.h>
+#endif
 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }
 EOF
   if compile_prog "" "" ; then
     attr=yes
   # Older distros have <attr/xattr.h>, and need -lattr:
-  elif sed -i s,sys/xattr,attr/xattr, $TMPC && compile_prog "" "-lattr" ; then
+  elif compile_prog "-DCONFIG_LIBATTR" "-lattr" ; then
     attr=yes
     LIBS="-lattr $LIBS"
     libattr=yes
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 17cf6f72ad..477fc6fd47 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -231,15 +231,30 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
         s->nvflags &= ~val;
         break;
     case 0x40: /* RESETCTL */
-        if (board_id(s) == BOARD_ID_VEXPRESS) {
+        switch (board_id(s)) {
+        case BOARD_ID_PB926:
+            if (s->lockval == LOCK_VALUE) {
+                s->resetlevel = val;
+                if (val & 0x100) {
+                    qemu_system_reset_request();
+                }
+            }
+            break;
+        case BOARD_ID_PBX:
+        case BOARD_ID_PBA8:
+            if (s->lockval == LOCK_VALUE) {
+                s->resetlevel = val;
+                if (val & 0x04) {
+                    qemu_system_reset_request();
+                }
+            }
+            break;
+        case BOARD_ID_VEXPRESS:
+        case BOARD_ID_EB:
+        default:
             /* reserved: RAZ/WI */
             break;
         }
-        if (s->lockval == LOCK_VALUE) {
-            s->resetlevel = val;
-            if (val & 0x100)
-                qemu_system_reset_request ();
-        }
         break;
     case 0x44: /* PCICTL */
         /* nothing to do.  */
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 09a4b247bd..66db81d5b7 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -269,7 +269,7 @@ static uint64_t icp_pit_read(void *opaque, target_phys_addr_t offset,
 
     /* ??? Don't know the PrimeCell ID for this device.  */
     n = offset >> 8;
-    if (n > 3) {
+    if (n > 2) {
         hw_error("sp804_read: Bad timer %d\n", n);
     }
 
@@ -283,7 +283,7 @@ static void icp_pit_write(void *opaque, target_phys_addr_t offset,
     int n;
 
     n = offset >> 8;
-    if (n > 3) {
+    if (n > 2) {
         hw_error("sp804_write: Bad timer %d\n", n);
     }
 
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 90b6729692..1fed359ab1 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -516,9 +516,14 @@ static unsigned int event_status_media(IDEState *s,
 
     /* Event notification descriptor */
     event_code = MEC_NO_CHANGE;
-    if (media_status != MS_TRAY_OPEN && s->events.new_media) {
-        event_code = MEC_NEW_MEDIA;
-        s->events.new_media = false;
+    if (media_status != MS_TRAY_OPEN) {
+        if (s->events.new_media) {
+            event_code = MEC_NEW_MEDIA;
+            s->events.new_media = false;
+        } else if (s->events.eject_request) {
+            event_code = MEC_EJECT_REQUESTED;
+            s->events.eject_request = false;
+        }
     }
 
     buf[4] = event_code;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 9a2fd30607..93a1a689c4 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -804,6 +804,18 @@ static void ide_cd_change_cb(void *opaque, bool load)
      */
     s->cdrom_changed = 1;
     s->events.new_media = true;
+    s->events.eject_request = false;
+    ide_set_irq(s->bus);
+}
+
+static void ide_cd_eject_request_cb(void *opaque, bool force)
+{
+    IDEState *s = opaque;
+
+    s->events.eject_request = true;
+    if (force) {
+        s->tray_locked = false;
+    }
     ide_set_irq(s->bus);
 }
 
@@ -1811,6 +1823,7 @@ static bool ide_cd_is_medium_locked(void *opaque)
 
 static const BlockDevOps ide_cd_block_ops = {
     .change_media_cb = ide_cd_change_cb,
+    .eject_request_cb = ide_cd_eject_request_cb,
     .is_tray_open = ide_cd_is_tray_open,
     .is_medium_locked = ide_cd_is_medium_locked,
 };
diff --git a/hw/nand.c b/hw/nand.c
index c27783e8ac..7f25814ddd 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -19,6 +19,7 @@
 # include "flash.h"
 # include "blockdev.h"
 # include "sysbus.h"
+#include "qemu-error.h"
 
 # define NAND_CMD_READ0		0x00
 # define NAND_CMD_READ1		0x01
@@ -384,18 +385,23 @@ static int nand_device_init(SysBusDevice *dev)
         nand_init_2048(s);
         break;
     default:
-        hw_error("%s: Unsupported NAND block size.\n", __func__);
+        error_report("Unsupported NAND block size");
+        return -1;
     }
 
     pagesize = 1 << s->oob_shift;
     s->mem_oob = 1;
-    if (s->bdrv && bdrv_getlength(s->bdrv) >=
-            (s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
-        pagesize = 0;
-        s->mem_oob = 0;
-    }
-
-    if (!s->bdrv) {
+    if (s->bdrv) {
+        if (bdrv_is_read_only(s->bdrv)) {
+            error_report("Can't use a read-only drive");
+            return -1;
+        }
+        if (bdrv_getlength(s->bdrv) >=
+                (s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
+            pagesize = 0;
+            s->mem_oob = 0;
+        }
+    } else {
         pagesize += 1 << s->page_shift;
     }
     if (pagesize) {
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index 42e59c3a53..30630a8aa9 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -510,7 +510,7 @@ static void omap2_gpio_module_write(void *opaque, target_phys_addr_t addr,
 
 static uint32_t omap2_gpio_module_readp(void *opaque, target_phys_addr_t addr)
 {
-    return omap2_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
+    return omap2_gpio_module_read(opaque, addr & ~3) >> ((addr & 3) << 3);
 }
 
 static void omap2_gpio_module_writep(void *opaque, target_phys_addr_t addr,
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index 0f7fd9dd4c..45efa25109 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -398,6 +398,9 @@ static uint64_t omap2_inth_read(void *opaque, target_phys_addr_t addr,
         if (bank_no < s->nbanks) {
             offset &= ~0x60;
             bank = &s->bank[bank_no];
+        } else {
+            OMAP_BAD_REG(addr);
+            return 0;
         }
     }
 
@@ -476,6 +479,9 @@ static void omap2_inth_write(void *opaque, target_phys_addr_t addr,
         if (bank_no < s->nbanks) {
             offset &= ~0x60;
             bank = &s->bank[bank_no];
+        } else {
+            OMAP_BAD_REG(addr);
+            return;
         }
     }
 
diff --git a/hw/onenand.c b/hw/onenand.c
index 6f68f70698..7898da9321 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -26,6 +26,7 @@
 #include "memory.h"
 #include "exec-memory.h"
 #include "sysbus.h"
+#include "qemu-error.h"
 
 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
 #define PAGE_SHIFT	11
@@ -772,6 +773,10 @@ static int onenand_initfn(SysBusDevice *dev)
         s->image = memset(g_malloc(size + (size >> 5)),
                           0xff, size + (size >> 5));
     } else {
+        if (bdrv_is_read_only(s->bdrv)) {
+            error_report("Can't use a read-only drive");
+            return -1;
+        }
         s->bdrv_cur = s->bdrv;
     }
     s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
diff --git a/hw/pc.c b/hw/pc.c
index 3015671858..33778fe422 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -335,7 +335,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
                   ISADevice *s)
 {
     int val, nb, nb_heads, max_track, last_sect, i;
-    FDriveType fd_type[2];
+    FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
     BlockDriverState *fd[MAX_FD];
     static pc_cmos_init_late_arg arg;
 
@@ -385,8 +385,6 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
                 bdrv_get_floppy_geometry_hint(fd[i], &nb_heads, &max_track,
                                               &last_sect, FDRIVE_DRV_NONE,
                                               &fd_type[i]);
-            } else {
-                fd_type[i] = FDRIVE_DRV_NONE;
             }
         }
     }
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 27ea5707e2..970f43c99c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -311,6 +311,18 @@ static QEMUMachine pc_machine_v0_14 = {
     .desc = "Standard PC",
     .init = pc_init_pci,
     .max_cpus = 255,
+    .compat_props = (GlobalProperty[]) {
+        {
+            .driver   = "qxl",
+            .property = "revision",
+            .value    = stringify(2),
+        },{
+            .driver   = "qxl-vga",
+            .property = "revision",
+            .value    = stringify(2),
+        },
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine pc_machine_v0_13 = {
diff --git a/hw/pl061.c b/hw/pl061.c
index d13746cfe5..cf5adbe1fb 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -103,7 +103,7 @@ static void pl061_update(pl061_state *s)
     s->old_data = out;
     for (i = 0; i < 8; i++) {
         mask = 1 << i;
-        if ((changed & mask) && s->out) {
+        if (changed & mask) {
             DPRINTF("Set output %d = %d\n", i, (out & mask) != 0);
             qemu_set_irq(s->out[i], (out & mask) != 0);
         }
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index bfc28a999b..e9a507ece5 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -114,7 +114,10 @@ static void pxa2xx_pm_write(void *opaque, target_phys_addr_t addr,
 
     switch (addr) {
     case PMCR:
-        s->pm_regs[addr >> 2] &= 0x15 & ~(value & 0x2a);
+        /* Clear the write-one-to-clear bits... */
+        s->pm_regs[addr >> 2] &= ~(value & 0x2a);
+        /* ...and set the plain r/w bits */
+        s->pm_regs[addr >> 2] &= ~0x15;
         s->pm_regs[addr >> 2] |= value & 0x15;
         break;
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 1c04872af7..62f538f4f8 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -65,6 +65,7 @@ struct SCSIDiskState
     uint32_t removable;
     bool media_changed;
     bool media_event;
+    bool eject_request;
     QEMUBH *bh;
     char *version;
     char *serial;
@@ -671,9 +672,14 @@ static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf)
 
     /* Event notification descriptor */
     event_code = MEC_NO_CHANGE;
-    if (media_status != MS_TRAY_OPEN && s->media_event) {
-        event_code = MEC_NEW_MEDIA;
-        s->media_event = false;
+    if (media_status != MS_TRAY_OPEN) {
+        if (s->media_event) {
+            event_code = MEC_NEW_MEDIA;
+            s->media_event = false;
+        } else if (s->eject_request) {
+            event_code = MEC_EJECT_REQUESTED;
+            s->eject_request = false;
+        }
     }
 
     outbuf[0] = event_code;
@@ -1470,6 +1476,17 @@ static void scsi_cd_change_media_cb(void *opaque, bool load)
     s->tray_open = !load;
     s->qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM);
     s->media_event = true;
+    s->eject_request = false;
+}
+
+static void scsi_cd_eject_request_cb(void *opaque, bool force)
+{
+    SCSIDiskState *s = opaque;
+
+    s->eject_request = true;
+    if (force) {
+        s->tray_locked = false;
+    }
 }
 
 static bool scsi_cd_is_tray_open(void *opaque)
@@ -1484,6 +1501,7 @@ static bool scsi_cd_is_medium_locked(void *opaque)
 
 static const BlockDevOps scsi_cd_block_ops = {
     .change_media_cb = scsi_cd_change_media_cb,
+    .eject_request_cb = scsi_cd_eject_request_cb,
     .is_tray_open = scsi_cd_is_tray_open,
     .is_medium_locked = scsi_cd_is_medium_locked,
 };
diff --git a/hw/tc58128.c b/hw/tc58128.c
index ee3ecad51a..4ce80b18f3 100644
--- a/hw/tc58128.c
+++ b/hw/tc58128.c
@@ -30,12 +30,8 @@ static void init_dev(tc58128_dev * dev, const char *filename)
     int ret, blocks;
 
     dev->state = WAIT;
-    dev->flash_contents = g_malloc0(FLASH_SIZE);
+    dev->flash_contents = g_malloc(FLASH_SIZE);
     memset(dev->flash_contents, 0xff, FLASH_SIZE);
-    if (!dev->flash_contents) {
-	fprintf(stderr, "could not alloc memory for flash\n");
-	exit(1);
-    }
     if (filename) {
 	/* Load flash image skipping the first block */
 	ret = load_image(filename, dev->flash_contents + 528 * 32);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a4139763f4..4635bb2e5d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1105,8 +1105,7 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
                 offset = p % TARGET_PAGE_SIZE;
                 pag = (char *)page[p/TARGET_PAGE_SIZE];
                 if (!pag) {
-                    pag = (char *)malloc(TARGET_PAGE_SIZE);
-                    memset(pag, 0, TARGET_PAGE_SIZE);
+                    pag = g_try_malloc0(TARGET_PAGE_SIZE);
                     page[p/TARGET_PAGE_SIZE] = pag;
                     if (!pag)
                         return 0;
@@ -1164,7 +1163,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
             info->rss++;
             /* FIXME - check return value of memcpy_to_target() for failure */
             memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
-            free(bprm->page[i]);
+            g_free(bprm->page[i]);
         }
         stack_base += TARGET_PAGE_SIZE;
     }
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index 62ebc7ed41..b47025f08a 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -178,7 +178,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp,
 
     /* Something went wrong, return the inode and free the argument pages*/
     for (i=0 ; i<MAX_ARG_PAGES ; i++) {
-        free(bprm->page[i]);
+        g_free(bprm->page[i]);
     }
     return(retval);
 }
diff --git a/memory.c b/memory.c
index c0c1d12d79..7c20a0703f 100644
--- a/memory.c
+++ b/memory.c
@@ -1401,7 +1401,7 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
                        alias_print_queue);
     }
 
-    QTAILQ_FOREACH_SAFE(next_ml, &submr_print_queue, queue, ml) {
+    QTAILQ_FOREACH_SAFE(ml, &submr_print_queue, queue, next_ml) {
         g_free(ml);
     }
 }
@@ -1425,7 +1425,7 @@ void mtree_info(fprintf_function mon_printf, void *f)
     }
 
     QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) {
-        g_free(ml2);
+        g_free(ml);
     }
 
     if (address_space_io.root &&
diff --git a/migration.c b/migration.c
index 4b17566857..41c3c24e09 100644
--- a/migration.c
+++ b/migration.c
@@ -155,7 +155,6 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 
 static void migrate_fd_monitor_suspend(MigrationState *s, Monitor *mon)
 {
-    s->mon = mon;
     if (monitor_suspend(mon) == 0) {
         DPRINTF("suspending monitor\n");
     } else {
@@ -383,7 +382,12 @@ static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc)
     s->bandwidth_limit = bandwidth_limit;
     s->blk = blk;
     s->shared = inc;
-    s->mon = NULL;
+
+    /* s->mon is used for two things:
+       - pass fd in fd migration
+       - suspend/resume monitor for not detached migration
+    */
+    s->mon = mon;
     s->bandwidth_limit = bandwidth_limit;
     s->state = MIG_STATE_SETUP;
 
@@ -435,6 +439,10 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
         return ret;
     }
 
+    if (detach) {
+        s->mon = NULL;
+    }
+
     notifier_list_notify(&migration_state_notifiers, s);
     return 0;
 }
diff --git a/nbd.c b/nbd.c
index fb5e424abe..e6c931c5ce 100644
--- a/nbd.c
+++ b/nbd.c
@@ -425,6 +425,13 @@ int nbd_client(int fd)
     TRACE("Doing NBD loop");
 
     ret = ioctl(fd, NBD_DO_IT);
+    if (ret == -1 && errno == EPIPE) {
+        /* NBD_DO_IT normally returns EPIPE when someone has disconnected
+         * the socket via NBD_DISCONNECT.  We do not want to return 1 in
+         * that case.
+         */
+        ret = 0;
+    }
     serrno = errno;
 
     TRACE("NBD loop returned %d: %s", ret, strerror(serrno));
diff --git a/os-posix.c b/os-posix.c
index dbf3b240f7..dc4a6bb3ff 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -372,13 +372,16 @@ int qemu_create_pidfile(const char *filename)
         return -1;
     }
     if (lockf(fd, F_TLOCK, 0) == -1) {
+        close(fd);
         return -1;
     }
     len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid());
     if (write(fd, buffer, len) != len) {
+        close(fd);
         return -1;
     }
 
+    close(fd);
     return 0;
 }
 
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index d3c1174ebf..0c0035cb18 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -667,6 +667,7 @@ int paio_init(void)
     s->first_aio = NULL;
     if (qemu_pipe(fds) == -1) {
         fprintf(stderr, "failed to create pipe\n");
+        g_free(s);
         return -1;
     }
 
diff --git a/qemu-char.c b/qemu-char.c
index 9fd94d1bb4..b562bf88a7 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -985,7 +985,7 @@ static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
     CharDriverState *chr;
     PtyCharDriver *s;
     struct termios tty;
-    int slave_fd, len;
+    int master_fd, slave_fd, len;
 #if defined(__OpenBSD__) || defined(__DragonFly__)
     char pty_name[PATH_MAX];
 #define q_ptsname(x) pty_name
@@ -994,10 +994,7 @@ static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
 #define q_ptsname(x) ptsname(x)
 #endif
 
-    chr = g_malloc0(sizeof(CharDriverState));
-    s = g_malloc0(sizeof(PtyCharDriver));
-
-    if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
+    if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) {
         return -errno;
     }
 
@@ -1007,17 +1004,21 @@ static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
     close(slave_fd);
 
-    len = strlen(q_ptsname(s->fd)) + 5;
+    chr = g_malloc0(sizeof(CharDriverState));
+
+    len = strlen(q_ptsname(master_fd)) + 5;
     chr->filename = g_malloc(len);
-    snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd));
-    qemu_opt_set(opts, "path", q_ptsname(s->fd));
-    fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
+    snprintf(chr->filename, len, "pty:%s", q_ptsname(master_fd));
+    qemu_opt_set(opts, "path", q_ptsname(master_fd));
+    fprintf(stderr, "char device redirected to %s\n", q_ptsname(master_fd));
 
+    s = g_malloc0(sizeof(PtyCharDriver));
     chr->opaque = s;
     chr->chr_write = pty_chr_write;
     chr->chr_update_read_handler = pty_chr_update_read_handler;
     chr->chr_close = pty_chr_close;
 
+    s->fd = master_fd;
     s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);
 
     *_chr = chr;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index d8d3e15a84..291cba2eaa 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -31,12 +31,17 @@
 #include <arpa/inet.h>
 #include <signal.h>
 #include <libgen.h>
+#include <pthread.h>
 
 #define SOCKET_PATH    "/var/lock/qemu-nbd-%s"
 
 #define NBD_BUFFER_SIZE (1024*1024)
 
+static int sigterm_wfd;
 static int verbose;
+static char *device;
+static char *srcpath;
+static char *sockpath;
 
 static void usage(const char *name)
 {
@@ -163,21 +168,80 @@ static int find_partition(BlockDriverState *bs, int partition,
     return -1;
 }
 
-static void show_parts(const char *device)
+static void termsig_handler(int signum)
 {
-    if (fork() == 0) {
-        int nbd;
+    static int sigterm_reported;
+    if (!sigterm_reported) {
+        sigterm_reported = (write(sigterm_wfd, "", 1) == 1);
+    }
+}
 
-        /* linux just needs an open() to trigger
-         * the partition table update
-         * but remember to load the module with max_part != 0 :
-         *     modprobe nbd max_part=63
-         */
-        nbd = open(device, O_RDWR);
-        if (nbd != -1)
-              close(nbd);
-        exit(0);
+static void *show_parts(void *arg)
+{
+    int nbd;
+
+    /* linux just needs an open() to trigger
+     * the partition table update
+     * but remember to load the module with max_part != 0 :
+     *     modprobe nbd max_part=63
+     */
+    nbd = open(device, O_RDWR);
+    if (nbd != -1) {
+        close(nbd);
     }
+    return NULL;
+}
+
+static void *nbd_client_thread(void *arg)
+{
+    int fd = *(int *)arg;
+    off_t size;
+    size_t blocksize;
+    uint32_t nbdflags;
+    int sock;
+    int ret;
+    pthread_t show_parts_thread;
+
+    do {
+        sock = unix_socket_outgoing(sockpath);
+        if (sock == -1) {
+            goto out;
+        }
+    } while (sock == -1);
+
+    ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
+                                &size, &blocksize);
+    if (ret == -1) {
+        goto out;
+    }
+
+    ret = nbd_init(fd, sock, nbdflags, size, blocksize);
+    if (ret == -1) {
+        goto out;
+    }
+
+    /* update partition table */
+    pthread_create(&show_parts_thread, NULL, show_parts, NULL);
+
+    if (verbose) {
+        fprintf(stderr, "NBD device %s is now connected to %s\n",
+                device, srcpath);
+    } else {
+        /* Close stderr so that the qemu-nbd process exits.  */
+        dup2(STDOUT_FILENO, STDERR_FILENO);
+    }
+
+    ret = nbd_client(fd);
+    if (ret) {
+        goto out;
+    }
+    close(fd);
+    kill(getpid(), SIGTERM);
+    return (void *) EXIT_SUCCESS;
+
+out:
+    kill(getpid(), SIGTERM);
+    return (void *) EXIT_FAILURE;
 }
 
 int main(int argc, char **argv)
@@ -192,9 +256,6 @@ int main(int argc, char **argv)
     struct sockaddr_in addr;
     socklen_t addr_len = sizeof(addr);
     off_t fd_size;
-    char *device = NULL;
-    char *socket = NULL;
-    char sockpath[128];
     const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
     struct option lopt[] = {
         { "help", 0, NULL, 'h' },
@@ -230,6 +291,21 @@ int main(int argc, char **argv)
     int nb_fds = 0;
     int max_fd;
     int persistent = 0;
+    pthread_t client_thread;
+
+    /* The client thread uses SIGTERM to interrupt the server.  A signal
+     * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
+     */
+    struct sigaction sa_sigterm;
+    int sigterm_fd[2];
+    if (qemu_pipe(sigterm_fd) == -1) {
+        err(EXIT_FAILURE, "Error setting up communication pipe");
+    }
+
+    sigterm_wfd = sigterm_fd[1];
+    memset(&sa_sigterm, 0, sizeof(sa_sigterm));
+    sa_sigterm.sa_handler = termsig_handler;
+    sigaction(SIGTERM, &sa_sigterm, NULL);
 
     while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
         switch (ch) {
@@ -273,8 +349,8 @@ int main(int argc, char **argv)
                 errx(EXIT_FAILURE, "Invalid partition %d", partition);
             break;
         case 'k':
-            socket = optarg;
-            if (socket[0] != '/')
+            sockpath = optarg;
+            if (sockpath[0] != '/')
                 errx(EXIT_FAILURE, "socket path must be absolute\n");
             break;
         case 'd':
@@ -332,130 +408,134 @@ int main(int argc, char **argv)
 	return 0;
     }
 
-    bdrv_init();
-
-    bs = bdrv_new("hda");
-
-    if ((ret = bdrv_open(bs, argv[optind], flags, NULL)) < 0) {
-        errno = -ret;
-        err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
-    }
-
-    fd_size = bs->total_sectors * 512;
-
-    if (partition != -1 &&
-        find_partition(bs, partition, &dev_offset, &fd_size))
-        err(EXIT_FAILURE, "Could not find partition %d", partition);
-
-    if (device) {
+    if (device && !verbose) {
+        int stderr_fd[2];
         pid_t pid;
-        int sock;
+        int ret;
 
-        /* want to fail before daemonizing */
-        if (access(device, R_OK|W_OK) == -1) {
-            err(EXIT_FAILURE, "Could not access '%s'", device);
+        if (qemu_pipe(stderr_fd) == -1) {
+            err(EXIT_FAILURE, "Error setting up communication pipe");
         }
 
-        if (!verbose) {
-            /* detach client and server */
-            if (qemu_daemon(0, 0) == -1) {
+        /* Now daemonize, but keep a communication channel open to
+         * print errors and exit with the proper status code.
+         */
+        pid = fork();
+        if (pid == 0) {
+            close(stderr_fd[0]);
+            ret = qemu_daemon(0, 0);
+
+            /* Temporarily redirect stderr to the parent's pipe...  */
+            dup2(stderr_fd[1], STDERR_FILENO);
+            if (ret == -1) {
                 err(EXIT_FAILURE, "Failed to daemonize");
             }
-        }
-
-        if (socket == NULL) {
-            snprintf(sockpath, sizeof(sockpath), SOCKET_PATH,
-                     basename(device));
-            socket = sockpath;
-        }
 
-        pid = fork();
-        if (pid < 0)
-            return 1;
-        if (pid != 0) {
-            off_t size;
-            size_t blocksize;
-
-            ret = 0;
-            bdrv_close(bs);
-
-            do {
-                sock = unix_socket_outgoing(socket);
-                if (sock == -1) {
-                    if (errno != ENOENT && errno != ECONNREFUSED) {
-                        ret = 1;
-                        goto out;
-                    }
-                    sleep(1);	/* wait children */
+            /* ... close the descriptor we inherited and go on.  */
+            close(stderr_fd[1]);
+        } else {
+            bool errors = false;
+            char *buf;
+
+            /* In the parent.  Print error messages from the child until
+             * it closes the pipe.
+             */
+            close(stderr_fd[1]);
+            buf = g_malloc(1024);
+            while ((ret = read(stderr_fd[0], buf, 1024)) > 0) {
+                errors = true;
+                ret = qemu_write_full(STDERR_FILENO, buf, ret);
+                if (ret == -1) {
+                    exit(EXIT_FAILURE);
                 }
-            } while (sock == -1);
-
-            fd = open(device, O_RDWR);
-            if (fd == -1) {
-                ret = 1;
-                goto out;
             }
-
-            ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
-                                        &size, &blocksize);
             if (ret == -1) {
-                ret = 1;
-                goto out;
+                err(EXIT_FAILURE, "Cannot read from daemon");
             }
 
-            ret = nbd_init(fd, sock, nbdflags, size, blocksize);
-            if (ret == -1) {
-                ret = 1;
-                goto out;
-            }
+            /* Usually the daemon should not print any message.
+             * Exit with zero status in that case.
+             */
+            exit(errors);
+        }
+    }
 
-            printf("NBD device %s is now connected to file %s\n",
-                    device, argv[optind]);
+    if (device) {
+        /* Open before spawning new threads.  In the future, we may
+         * drop privileges after opening.
+         */
+        fd = open(device, O_RDWR);
+        if (fd == -1) {
+            err(EXIT_FAILURE, "Failed to open %s", device);
+        }
 
-	    /* update partition table */
+        if (sockpath == NULL) {
+            sockpath = g_malloc(128);
+            snprintf(sockpath, 128, SOCKET_PATH, basename(device));
+        }
+    }
 
-            show_parts(device);
+    bdrv_init();
+    atexit(bdrv_close_all);
 
-            ret = nbd_client(fd);
-            if (ret) {
-                ret = 1;
-            }
-            close(fd);
- out:
-            kill(pid, SIGTERM);
-            unlink(socket);
+    bs = bdrv_new("hda");
+    srcpath = argv[optind];
+    if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) {
+        errno = -ret;
+        err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
+    }
 
-            return ret;
-        }
-        /* children */
+    fd_size = bs->total_sectors * 512;
+
+    if (partition != -1 &&
+        find_partition(bs, partition, &dev_offset, &fd_size)) {
+        err(EXIT_FAILURE, "Could not find partition %d", partition);
     }
 
     sharing_fds = g_malloc((shared + 1) * sizeof(int));
 
-    if (socket) {
-        sharing_fds[0] = unix_socket_incoming(socket);
+    if (sockpath) {
+        sharing_fds[0] = unix_socket_incoming(sockpath);
     } else {
         sharing_fds[0] = tcp_socket_incoming(bindto, port);
     }
 
     if (sharing_fds[0] == -1)
         return 1;
+
+    if (device) {
+        int ret;
+
+        ret = pthread_create(&client_thread, NULL, nbd_client_thread, &fd);
+        if (ret != 0) {
+            errx(EXIT_FAILURE, "Failed to create client thread: %s",
+                 strerror(ret));
+        }
+    } else {
+        /* Shut up GCC warnings.  */
+        memset(&client_thread, 0, sizeof(client_thread));
+    }
+
     max_fd = sharing_fds[0];
     nb_fds++;
 
     data = qemu_blockalign(bs, NBD_BUFFER_SIZE);
-    if (data == NULL)
+    if (data == NULL) {
         errx(EXIT_FAILURE, "Cannot allocate data buffer");
+    }
 
     do {
-
         FD_ZERO(&fds);
+        FD_SET(sigterm_fd[0], &fds);
         for (i = 0; i < nb_fds; i++)
             FD_SET(sharing_fds[i], &fds);
 
-        ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
-        if (ret == -1)
+        do {
+            ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
+        } while (ret == -1 && errno == EINTR);
+        if (ret == -1 || FD_ISSET(sigterm_fd[0], &fds)) {
             break;
+        }
 
         if (FD_ISSET(sharing_fds[0], &fds))
             ret--;
@@ -489,10 +569,16 @@ int main(int argc, char **argv)
     qemu_vfree(data);
 
     close(sharing_fds[0]);
-    bdrv_close(bs);
     g_free(sharing_fds);
-    if (socket)
-        unlink(socket);
+    if (sockpath) {
+        unlink(sockpath);
+    }
 
-    return 0;
+    if (device) {
+        void *ret;
+        pthread_join(client_thread, &ret);
+        exit(ret != NULL);
+    } else {
+        exit(EXIT_SUCCESS);
+    }
 }
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 183a9cbbd2..61b2247077 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -572,6 +572,7 @@ int unix_connect_opts(QemuOpts *opts)
     snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
     if (connect(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
         fprintf(stderr, "connect(unix:%s): %s\n", path, strerror(errno));
+        close(sock);
 	return -1;
     }
 
diff --git a/ui/keymaps.c b/ui/keymaps.c
index f54a11437b..f55a2aa464 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -92,15 +92,17 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
     int len;
 
     filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
-
-    if (!k)
-	k = g_malloc0(sizeof(kbd_layout_t));
-    if (!(filename && (f = fopen(filename, "r")))) {
+    f = filename ? fopen(filename, "r") : NULL;
+    g_free(filename);
+    if (!f) {
 	fprintf(stderr,
 		"Could not read keymap file: '%s'\n", language);
 	return NULL;
     }
-    g_free(filename);
+
+    if (!k)
+	k = g_malloc0(sizeof(kbd_layout_t));
+
     for(;;) {
 	if (fgets(line, 1024, f) == NULL)
             break;
diff --git a/vl.c b/vl.c
index f169aac1f9..f5afed4c49 100644
--- a/vl.c
+++ b/vl.c
@@ -3089,6 +3089,11 @@ int main(int argc, char **argv, char **envp)
         data_dir = CONFIG_QEMU_DATADIR;
     }
 
+    if (machine == NULL) {
+        fprintf(stderr, "No machine found.\n");
+        exit(1);
+    }
+
     /*
      * Default to max_cpus = smp_cpus, in case the user doesn't
      * specify a max_cpus value.
@@ -3226,6 +3231,11 @@ int main(int argc, char **argv, char **envp)
         fprintf(stderr, "could not initialize alarm timer\n");
         exit(1);
     }
+
+    if (icount_option && (kvm_enabled() || xen_enabled())) {
+        fprintf(stderr, "-icount is not allowed with kvm or xen\n");
+        exit(1);
+    }
     configure_icount(icount_option);
 
     if (net_init_clients() < 0) {