Re: [Qemu-devel] build with trace enabled is broken by the commit c572f23a3e7180dbeab5e86583e43ea2afed6271 hw/9pfs: Introduce tracing for 9p pdu handlers
On Sun, 23 Oct 2011 15:54:59 +0200, Jan Kiszka jan.kis...@web.de wrote: On 2011-10-21 17:10, Aneesh Kumar K.V wrote: On Thu, 20 Oct 2011 23:20:54 +0400, Max Filippov jcmvb...@gmail.com wrote: Hi. Current git head build with trace enabled is broken by the commit c572f23a3e7180dbeab5e86583e43ea2afed6271 hw/9pfs: Introduce tracing for 9p pdu handlers. Error messages: In file included from trace.c:2:0: trace.h: In function ‘trace_v9fs_attach’: trace.h:2850:9: error: too many arguments for format [-Werror=format-extra-args] trace.h: In function ‘trace_v9fs_wstat’: trace.h:3039:9: error: too many arguments for format [-Werror=format-extra-args] trace.h: In function ‘trace_v9fs_mkdir’: trace.h:3088:9: error: too many arguments for format [-Werror=format-extra-args] trace.h: In function ‘trace_v9fs_mkdir_return’: trace.h:3095:9: error: too many arguments for format [-Werror=format-extra-args] cc1: all warnings being treated as errors Prototypes in the trace-events do not match format strings, e.g. v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) tag %d id %d fid %d afid %d aname %s The following patch fixes it, but I'm not sure the format lines are appropriate. Can you send the patch with signed-off-by: I will add it in the next pull request. There are more breakages with tracing enabled: CClibhw64/9pfs/virtio-9p.o cc1: warnings being treated as errors /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_create’: /data/qemu/hw/9pfs/virtio-9p.c:2225:9: error: ‘iounit’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_readdir’: /data/qemu/hw/9pfs/virtio-9p.c:2063:13: error: ‘count’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_xattrwalk’: /data/qemu/hw/9pfs/virtio-9p.c:3103:13: error: ‘size’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_lcreate’: /data/qemu/hw/9pfs/virtio-9p.c:1730:13: error: ‘iounit’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_open’: /data/qemu/hw/9pfs/virtio-9p.c:1651:9: error: ‘iounit’ may be used uninitialized in this function Not sure what the undefined variables are supposed to contain for the trace output, so I refrain from writing any patch. Ok i am testing VirtFS tracing and will send a patch that should fix these issues. Sorry for all inconvenience. Even though i do test on three different distros, all of them were done without tracing enabled. -aneesh
Re: [Qemu-devel] [Qemu-discuss] [Qemu-discussion] QEMU via GDB
It dosen't work. GDB returns the same error. - Original Message - From: davide.ferrare...@studenti.univr.it Date: Monday, October 24, 2011 8:37 Subject: Re: [Qemu-discuss] [Qemu-discussion] QEMU via GDB To: davide.ferrare...@studenti.univr.it It dosen't work. GDB return the same error. - Original Message - From: davide.ferrare...@studenti.univr.it Date: Friday, October 21, 2011 16:18 Subject: [Qemu-discuss] [Qemu-discussion] QEMU via GDB To: qemu-disc...@nongnu.org Dear all, I am trying to debug QEMU via GDB. I configured and compiled QEMU with debugging flags, i.e., # CFLAGS=-g3 -O0 ./configure --disable-gfx-check and run gdb: # gdb ./i386-linux-user/qemu-i386 (gdb) break main (gdb) run Starting program: /home/test/femu/i386-linux-user/qemu-i386 Failed to read a valid object file image from memory. Warning: Cannot insert breakpoint 1. Error accessing memory address 0x2f7df: Input/output error. Is there any extra flag to be specified with the GDB for QEMU debugging? I am wondering if the QEMU virtual machine creates any problem to the GDB virtual machine. Thanks.
[Qemu-devel] Question about intermediate code generation in qemu (tcg)
Hi, I was wondering if someone could help me understand some aspects of the current qemu code generation routines. How are floating point and SSE ops currently handled? I do not see specific tcg routines for these cases(the README seems to indicate that FP and vector ops are not handled using the current IL). Thanks in advanced, Carter.
Re: [Qemu-devel] [PATCH] qxl: reset update_surface
On 10/23/11 17:03, Alon Levy wrote: update init_qxl_ram to reset update_surface to 0. This fixes one case of breakage when installing an old driver in a vm that had a new driver installed. The newer driver would know about surface creation and would change update_surface to !=0, then a reset would happen, all surfaces are destroyed, then the old driver is initialized and issues an UPDATE_AREA, and spice server aborts on invalid surface. Patch added to spice patch queue. thanks, Gerd
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
Am 21.10.2011 20:44, schrieb Paolo Bonzini: On 10/21/2011 07:08 PM, Kevin Wolf wrote: Avi complained that not even writing out qcow2's cache on bdrv_flush() made cache=unsafe too unsafe to be useful. He's got a point. Why? cache=unsafe is explicitly allowing to s/data/manure/ on crash. It's surely expected on a host crash, but is it for a qemu crash? cache=unsafe was introduced to avoid fsync() costs, which it still does after this patch. If you do this for raw-posix, you need to do it for all protocols. rbd could use it, too, right. Any other protocol I missed? Kevin
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
On 10/24/2011 09:37 AM, Kevin Wolf wrote: Why? cache=unsafe is explicitly allowing to s/data/manure/ on crash. It's surely expected on a host crash, but is it for a qemu crash? cache=unsafe was introduced to avoid fsync() costs, which it still does after this patch. I think it's not about why is it there, but rather about what is it useful for. My interpretation of it is I do not need the image anymore unless the command exits cleanly: VM installations, qemu-img conversions, BDRV_O_SNAPSHOT (doesn't do it yet, but it could). Even SIGINT and SIGTERM would be excluded from this definition, but they cost nothing so it's nice to include them. If you do this for raw-posix, you need to do it for all protocols. rbd could use it, too, right. Any other protocol I missed? NBD could, but it doesn't support flush yet. In general, even if it were useful to implement this, I'm not sure this is the best way to implement it. For example you could simply clear BDRV_O_NO_FLUSH in qcow2_open. Paolo
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
Am 23.10.2011 16:33, schrieb Paolo Bonzini: On 10/22/2011 05:07 PM, Alexander Graf wrote: On 21.10.2011, at 11:44, Paolo Bonzini wrote: On 10/21/2011 07:08 PM, Kevin Wolf wrote: Avi complained that not even writing out qcow2's cache on bdrv_flush() made cache=unsafe too unsafe to be useful. He's got a point. Why? cache=unsafe is explicitly allowing to s/data/manure/ on crash. Exactly, but not on kill. By not flushing internal caches you're almost guaranteed to get an inconsistent qcow2 image. This should be covered already by termsig_handler. bdrv_close_all closes all block devices, and qcow2_close does flush the caches. SIGKILL doesn't give any guarantee of course but it does not in general, even without cache=unsafe; you might get a SIGKILL a moment before a bdrv_flush even without cache=unsafe, and get unclean qcow2 metadata. Unclean yes, in the sense that you may get cluster leaks. If getting SIGKILL a moment before the flush led to real corruption however, cache=none would be broken as well. By not flushing internal caches you're almost guaranteed to get an inconsistent qcow2 image. Of course the inconsistencies with cache=unsafe will be massive if you don't have a clean exit, but that's expected. If in some cases you want a clean exit, but right now you don't, the place to fix those cases doesn't seem to be the block layer, but the main loop. I don't think there's much the main loop can do against SIGKILL, segfaults or abort(). Also, 1) why should cache=unsafe differentiate an OS that sends a flush from one that doesn't (e.g. MS-DOS), from the point of view of image metadata? 2) why should the guest actually send a flush if cache=unsafe? Currently if (flags BDRV_O_CACHE_WB) bs-enable_write_cache = 1; covers cache=unsafe. However, in the end write cache enable means do I need to flush data, and the answer is no when cache=unsafe, because the flushes are useless and guests are free to reorder requests. shot-in-the-darkPerhaps what you want is to make qcow2 caches writethrough in cache=unsafe mode, so that at least a try is made to write the metadata/shot-in-the-dark (even though the underlying raw protocol won't flush it)? I'm not sure that is particularly useful, but maybe it can help me understanding the benefit of this change. Yes, this is the intention. It's about flushing metadata, not guest data. The semantics that I think cache=unsafe should have is that after a bdrv_flush() we have flushed all caches in qemu (so that the image survives a qemu crash), but we don't care about flushing the host page cache. Kevin
Re: [Qemu-devel] build with trace enabled is broken by the commit c572f23a3e7180dbeab5e86583e43ea2afed6271 hw/9pfs: Introduce tracing for 9p pdu handlers
On Mon, 24 Oct 2011 11:46:21 +0530, Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com wrote: On Sun, 23 Oct 2011 15:54:59 +0200, Jan Kiszka jan.kis...@web.de wrote: On 2011-10-21 17:10, Aneesh Kumar K.V wrote: On Thu, 20 Oct 2011 23:20:54 +0400, Max Filippov jcmvb...@gmail.com wrote: Hi. Current git head build with trace enabled is broken by the commit c572f23a3e7180dbeab5e86583e43ea2afed6271 hw/9pfs: Introduce tracing for 9p pdu handlers. Error messages: In file included from trace.c:2:0: trace.h: In function ‘trace_v9fs_attach’: trace.h:2850:9: error: too many arguments for format [-Werror=format-extra-args] trace.h: In function ‘trace_v9fs_wstat’: trace.h:3039:9: error: too many arguments for format [-Werror=format-extra-args] trace.h: In function ‘trace_v9fs_mkdir’: trace.h:3088:9: error: too many arguments for format [-Werror=format-extra-args] trace.h: In function ‘trace_v9fs_mkdir_return’: trace.h:3095:9: error: too many arguments for format [-Werror=format-extra-args] cc1: all warnings being treated as errors Prototypes in the trace-events do not match format strings, e.g. v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) tag %d id %d fid %d afid %d aname %s The following patch fixes it, but I'm not sure the format lines are appropriate. Can you send the patch with signed-off-by: I will add it in the next pull request. There are more breakages with tracing enabled: CClibhw64/9pfs/virtio-9p.o cc1: warnings being treated as errors /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_create’: /data/qemu/hw/9pfs/virtio-9p.c:2225:9: error: ‘iounit’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_readdir’: /data/qemu/hw/9pfs/virtio-9p.c:2063:13: error: ‘count’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_xattrwalk’: /data/qemu/hw/9pfs/virtio-9p.c:3103:13: error: ‘size’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_lcreate’: /data/qemu/hw/9pfs/virtio-9p.c:1730:13: error: ‘iounit’ may be used uninitialized in this function /data/qemu/hw/9pfs/virtio-9p.c: In function ‘v9fs_open’: /data/qemu/hw/9pfs/virtio-9p.c:1651:9: error: ‘iounit’ may be used uninitialized in this function Not sure what the undefined variables are supposed to contain for the trace output, so I refrain from writing any patch. Ok i am testing VirtFS tracing and will send a patch that should fix these issues. Sorry for all inconvenience. Even though i do test on three different distros, all of them were done without tracing enabled. Can you try this patch. I will still like to get more testing tracing all 9p operations and making sure python script is correct. commit fe80ec13e59b581cba530e923e20df3fe9957177 Author: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com Date: Mon Oct 24 11:49:17 2011 +0530 hw/9pfs: Make VirtTFS work correctly this patch fix multiple issues with VitFS tracing. a) Add tracepoint to the correct code path. We handle error in complete_pdu b) Fix indentation in python script c) Fix variable naming issue in python script Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index aab3beb..8b6813f 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -969,7 +969,7 @@ static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len) if (s-proto_version == V9FS_PROTO_2000L) { id = P9_RLERROR; } -trace_complete_pdu(pdu-tag, pdu-id, err); /* Trace ERROR */ +trace_v9fs_rerror(pdu-tag, pdu-id, err); /* Trace ERROR */ } /* fill out the header */ @@ -1332,11 +1332,11 @@ static void v9fs_attach(void *opaque) } offset += pdu_marshal(pdu, offset, Q, qid); err = offset; +trace_v9fs_attach_return(pdu-tag, pdu-id, + qid.type, qid.version, qid.path); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_attach_return(pdu-tag, pdu-id, -
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
Am 24.10.2011 09:53, schrieb Paolo Bonzini: On 10/24/2011 09:37 AM, Kevin Wolf wrote: Why? cache=unsafe is explicitly allowing to s/data/manure/ on crash. It's surely expected on a host crash, but is it for a qemu crash? cache=unsafe was introduced to avoid fsync() costs, which it still does after this patch. I think it's not about why is it there, but rather about what is it useful for. My interpretation of it is I do not need the image anymore unless the command exits cleanly: VM installations, qemu-img conversions, BDRV_O_SNAPSHOT (doesn't do it yet, but it could). Even SIGINT and SIGTERM would be excluded from this definition, but they cost nothing so it's nice to include them. I think another common interpretation is: I don't run this VM in production but for development. I want the VM to go faster and I can recreate the image in the unlikely event that power fails during my work. But it certainly would be nasty. If you do this for raw-posix, you need to do it for all protocols. rbd could use it, too, right. Any other protocol I missed? NBD could, but it doesn't support flush yet. In general, even if it were useful to implement this, I'm not sure this is the best way to implement it. For example you could simply clear BDRV_O_NO_FLUSH in qcow2_open. That could work, too. On the other hand I don't like block drivers to modify their flags. For example, would query-block still provide the correct cache mode then? But I think that starting to make exceptions for single block drivers isn't a good idea anyway. If we want bdrv_flush() to write out all metadata internal to qemu, I think the approach with checking the flag in drivers calling things like fsync() is better. The common thing is to do the flush. Kevin
Re: [Qemu-devel] Question about intermediate code generation in qemu (tcg)
On 24 October 2011 07:46, Carter Cheng carterch...@gmail.com wrote: I was wondering if someone could help me understand some aspects of the current qemu code generation routines. How are floating point and SSE ops currently handled? I do not see specific tcg routines for these cases(the README seems to indicate that FP and vector ops are not handled using the current IL). FP instructions are generally turned into code which calls out to a helper function written in C which emulates the floating point arithmetic -- see target-i386/op_helper.c for the x87 ops and target-i386/ops_sse.h for the SSE ops. (Some simple arithmetic vector ops might be done by generating inline code; ARM does this but I haven't checked target-i386.) IEEE arithmetic emulation is done in fpu/ but you probably don't need to look at the actual implementation... In the TCG intermediate representation there's no special support for float/double types -- they're just passed around as i32/i64. -- PMM
[Qemu-devel] [PATCH] hw/9pfs: Make VirtTFS work correctly
From: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com this patch fix multiple issues with VitFS tracing. a) Add tracepoint to the correct code path. We handle error in complete_pdu b) Fix indentation in python script c) Fix variable naming issue in python script Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/9pfs/virtio-9p.c | 60 +++--- scripts/analyse-9p-simpletrace.py | 164 ++-- trace-events |2 +- 3 files changed, 112 insertions(+), 114 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index aab3beb..8b6813f 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -969,7 +969,7 @@ static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len) if (s-proto_version == V9FS_PROTO_2000L) { id = P9_RLERROR; } -trace_complete_pdu(pdu-tag, pdu-id, err); /* Trace ERROR */ +trace_v9fs_rerror(pdu-tag, pdu-id, err); /* Trace ERROR */ } /* fill out the header */ @@ -1332,11 +1332,11 @@ static void v9fs_attach(void *opaque) } offset += pdu_marshal(pdu, offset, Q, qid); err = offset; +trace_v9fs_attach_return(pdu-tag, pdu-id, + qid.type, qid.version, qid.path); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_attach_return(pdu-tag, pdu-id, - qid.type, qid.version, qid.path); complete_pdu(s, pdu, err); v9fs_string_free(uname); v9fs_string_free(aname); @@ -1371,13 +1371,12 @@ static void v9fs_stat(void *opaque) } offset += pdu_marshal(pdu, offset, wS, 0, v9stat); err = offset; +trace_v9fs_stat_return(pdu-tag, pdu-id, v9stat.mode, + v9stat.atime, v9stat.mtime, v9stat.length); v9fs_stat_free(v9stat); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_stat_return(pdu-tag, pdu-id, v9stat.mode, - v9stat.atime, v9stat.mtime, v9stat.length); - complete_pdu(s, pdu, err); } @@ -1421,13 +1420,12 @@ static void v9fs_getattr(void *opaque) } retval = offset; retval += pdu_marshal(pdu, offset, A, v9stat_dotl); -out: -put_fid(pdu, fidp); -out_nofid: trace_v9fs_getattr_return(pdu-tag, pdu-id, v9stat_dotl.st_result_mask, v9stat_dotl.st_mode, v9stat_dotl.st_uid, v9stat_dotl.st_gid); - +out: +put_fid(pdu, fidp); +out_nofid: complete_pdu(s, pdu, retval); } @@ -1605,6 +1603,7 @@ static void v9fs_walk(void *opaque) v9fs_path_copy(newfidp-path, path); } err = v9fs_walk_marshal(pdu, nwnames, qids); +trace_v9fs_walk_return(pdu-tag, pdu-id, nwnames, qids); out: put_fid(pdu, fidp); if (newfidp) { @@ -1613,7 +1612,6 @@ out: v9fs_path_free(dpath); v9fs_path_free(path); out_nofid: -trace_v9fs_walk_return(pdu-tag, pdu-id, nwnames, qids); complete_pdu(s, pdu, err); if (nwnames nwnames = P9_MAXWELEM) { for (name_idx = 0; name_idx nwnames; name_idx++) { @@ -1648,10 +1646,10 @@ static int32_t get_iounit(V9fsPDU *pdu, V9fsPath *path) static void v9fs_open(void *opaque) { int flags; -int iounit; int32_t fid; int32_t mode; V9fsQID qid; +int iounit = 0; ssize_t err = 0; size_t offset = 7; struct stat stbuf; @@ -1709,11 +1707,11 @@ static void v9fs_open(void *opaque) offset += pdu_marshal(pdu, offset, Qd, qid, iounit); err = offset; } +trace_v9fs_open_return(pdu-tag, pdu-id, + qid.type, qid.version, qid.path, iounit); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_open_return(pdu-tag, pdu-id, - qid.type, qid.version, qid.path, iounit); complete_pdu(s, pdu, err); } @@ -1759,11 +1757,11 @@ static void v9fs_lcreate(void *opaque) stat_to_qid(stbuf, qid); offset += pdu_marshal(pdu, offset, Qd, qid, iounit); err = offset; +trace_v9fs_lcreate_return(pdu-tag, pdu-id, + qid.type, qid.version, qid.path, iounit); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_lcreate_return(pdu-tag, pdu-id, - qid.type, qid.version, qid.path, iounit); complete_pdu(pdu-s, pdu, err); v9fs_string_free(name); } @@ -1978,10 +1976,10 @@ static void v9fs_read(void *opaque) } else { err = -EINVAL; } +trace_v9fs_read_return(pdu-tag, pdu-id, count, err); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_read_return(pdu-tag, pdu-id, count, err); complete_pdu(s, pdu, err); } @@ -2090,10 +2088,10 @@ static void v9fs_readdir(void *opaque) retval = offset; retval += pdu_marshal(pdu, offset, d, count); retval += count; +trace_v9fs_readdir_return(pdu-tag, pdu-id, count, retval); out: put_fid(pdu, fidp); out_nofid: -
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
On 10/24/2011 10:17 AM, Kevin Wolf wrote: I think it's not about why is it there, but rather about what is it useful for. My interpretation of it is I do not need the image anymore unless the command exits cleanly: VM installations, qemu-img conversions, BDRV_O_SNAPSHOT (doesn't do it yet, but it could). Even SIGINT and SIGTERM would be excluded from this definition, but they cost nothing so it's nice to include them. I think another common interpretation is: I don't run this VM in production but for development. I want the VM to go faster and I can recreate the image in the unlikely event that power fails during my work. But it certainly would be nasty. Fair enough. But I think that starting to make exceptions for single block drivers isn't a good idea anyway. If we want bdrv_flush() to write out all metadata internal to qemu, I think the approach with checking the flag in drivers calling things like fsync() is better. The common thing is to do the flush. I don't know... checking BDRV_O_NO_FLUSH in the drivers rather than in the generic code sounds like a layering violation. Perhaps what you're after is a separation of bdrv_co_flush from bdrv_{,co_,aio_}fsync? Then BDRV_O_NO_FLUSH (better renamed to BDRV_O_NO_FSYNC...) would only inhibit the latter. Paolo
Re: [Qemu-devel] [PATCH] monitor: refactor whitespace and optional argument parsing
Alon Levy al...@redhat.com writes: Takes out the optional ('?') message parsing from the main switch loop in monitor_parse_command. Adds optional argument option for boolean parameters. Signed-off-by: Alon Levy al...@redhat.com --- Previous patch used qemu_free (that's how old it is), fixed. monitor.c | 79 +++- 1 files changed, 30 insertions(+), 49 deletions(-) diff --git a/monitor.c b/monitor.c index ffda0fe..a482705 100644 --- a/monitor.c +++ b/monitor.c @@ -3976,6 +3976,29 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, break; c = *typestr; typestr++; +while (qemu_isspace(*p)) { +p++; +} +/* take care of optional arguments */ +switch (c) { +case 's': +case 'i': +case 'l': +case 'M': +case 'o': +case 'T': +case 'b': +if (*typestr == '?') { +typestr++; +if (*p == '\0') { +/* missing optional argument: NULL argument */ +g_free(key); +key = NULL; +continue; +} +} +break; +} switch(c) { case 'F': case 'B': @@ -3983,15 +4006,6 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, { int ret; -while (qemu_isspace(*p)) -p++; -if (*typestr == '?') { -typestr++; -if (*p == '\0') { -/* no optional string: NULL argument */ -break; -} -} ret = get_str(buf, sizeof(buf), p); if (ret 0) { switch(c) { This is cases 'F', 'B' and 's'. I'm afraid your new code covers only 's'. @@ -4021,9 +4035,6 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, if (!opts_list || opts_list-desc-name) { goto bad_type; } -while (qemu_isspace(*p)) { -p++; -} if (!*p) break; if (get_str(buf, sizeof(buf), p) 0) { @@ -4041,8 +4052,6 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, { int count, format, size; -while (qemu_isspace(*p)) -p++; if (*p == '/') { /* format found */ p++; @@ -4122,23 +4131,15 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, { int64_t val; -while (qemu_isspace(*p)) -p++; -if (*typestr == '?' || *typestr == '.') { -if (*typestr == '?') { -if (*p == '\0') { -typestr++; -break; -} -} else { -if (*p == '.') { +if (*typestr == '.') { +if (*p == '.') { +p++; +while (qemu_isspace(*p)) { p++; -while (qemu_isspace(*p)) -p++; -} else { -typestr++; -break; } +} else { +typestr++; +break; } typestr++; } @@ -4160,15 +4161,6 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, int64_t val; char *end; -while (qemu_isspace(*p)) { -p++; -} -if (*typestr == '?') { -typestr++; -if (*p == '\0') { -break; -} -} val = strtosz(p, end); if (val 0) { monitor_printf(mon, invalid size\n); @@ -4182,14 +4174,6 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, { double val; -while (qemu_isspace(*p)) -p++; -if (*typestr == '?') { -typestr++; -if (*p == '\0') { -break; -} -} if (get_double(mon, val, p) 0) { goto fail; } @@ -4215,9 +4199,6 @@ static
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
Am 24.10.2011 10:47, schrieb Paolo Bonzini: On 10/24/2011 10:17 AM, Kevin Wolf wrote: I think it's not about why is it there, but rather about what is it useful for. My interpretation of it is I do not need the image anymore unless the command exits cleanly: VM installations, qemu-img conversions, BDRV_O_SNAPSHOT (doesn't do it yet, but it could). Even SIGINT and SIGTERM would be excluded from this definition, but they cost nothing so it's nice to include them. I think another common interpretation is: I don't run this VM in production but for development. I want the VM to go faster and I can recreate the image in the unlikely event that power fails during my work. But it certainly would be nasty. Fair enough. But I think that starting to make exceptions for single block drivers isn't a good idea anyway. If we want bdrv_flush() to write out all metadata internal to qemu, I think the approach with checking the flag in drivers calling things like fsync() is better. The common thing is to do the flush. I don't know... checking BDRV_O_NO_FLUSH in the drivers rather than in the generic code sounds like a layering violation. Perhaps what you're after is a separation of bdrv_co_flush from bdrv_{,co_,aio_}fsync? Then BDRV_O_NO_FLUSH (better renamed to BDRV_O_NO_FSYNC...) would only inhibit the latter. Why? All other cache related BDRV_O_* flags are interpreted by the block drivers, so why should BDRV_O_NO_FLUSH be special? Kevin
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
On 24 October 2011 09:17, Kevin Wolf kw...@redhat.com wrote: Am 24.10.2011 09:53, schrieb Paolo Bonzini: I think it's not about why is it there, but rather about what is it useful for. My interpretation of it is I do not need the image anymore unless the command exits cleanly: VM installations, qemu-img conversions, BDRV_O_SNAPSHOT (doesn't do it yet, but it could). Even SIGINT and SIGTERM would be excluded from this definition, but they cost nothing so it's nice to include them. I think another common interpretation is: I don't run this VM in production but for development. I want the VM to go faster and I can recreate the image in the unlikely event that power fails during my work. But it certainly would be nasty. So at the moment the documentation (qemu-doc.html) says: Writeback caching will report data writes as completed as soon as the data is present in the host page cache. This is safe as long as you trust your host. If your host crashes or loses power, then the guest may experience data corruption. and also: In case you don't care about data integrity over host failures, use cache=unsafe. This option tells qemu that it never needs to write any data to the disk but can instead keeps things in cache. If anything goes wrong, like your host losing power, the disk storage getting disconnected accidently, etc. you're image will most probably be rendered unusable. which to me reads in both cases as will not corrupt data if the guest crashes but may do so if the host crashes and leaves me with no idea what the difference is. It might be nice if we could clarify that a bit... -- PMM
Re: [Qemu-devel] [RFC v2 PATCH 5/4 PATCH] virtio-net: send gratuitous packet when needed
On Mon, 2011-10-24 at 07:25 +0200, Michael S. Tsirkin wrote: On Mon, Oct 24, 2011 at 02:54:59PM +1030, Rusty Russell wrote: On Sat, 22 Oct 2011 13:43:11 +0800, Jason Wang jasow...@redhat.com wrote: This make let virtio-net driver can send gratituous packet by a new config bit - VIRTIO_NET_S_ANNOUNCE in each config update interrupt. When this bit is set by backend, the driver would schedule a workqueue to send gratituous packet through NETDEV_NOTIFY_PEERS. This feature is negotiated through bit VIRTIO_NET_F_GUEST_ANNOUNCE. Signed-off-by: Jason Wang jasow...@redhat.com This seems like a huge layering violation. Imagine this in real hardware, for example. commits 06c4648d46d1b757d6b9591a86810be79818b60c and 99606477a5888b0ead0284fecb13417b1da8e3af document the need for this: NETDEV_NOTIFY_PEERS notifier indicates that a device moved to a different physical link. and In real hardware such notifications are only generated when the device comes up or the address changes. So hypervisor could get the same behaviour by sending link up/down events, this is just an optimization so guest won't do unecessary stuff like try to reconfigure an IP address. Maybe LOCATION_CHANGE would be a better name? [...] We also use this in bonding failover, where the system location doesn't change but a different link is used. However, I do recognise that the name ought to indicate what kind of change happened and not what the expected action is. Ben. -- Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked.
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
On 10/24/2011 10:54 AM, Kevin Wolf wrote: I don't know... checking BDRV_O_NO_FLUSH in the drivers rather than in the generic code sounds like a layering violation. Perhaps what you're after is a separation of bdrv_co_flush from bdrv_{,co_,aio_}fsync? Then BDRV_O_NO_FLUSH (better renamed to BDRV_O_NO_FSYNC...) would only inhibit the latter. Why? All other cache related BDRV_O_* flags are interpreted by the block drivers, so why should BDRV_O_NO_FLUSH be special? You're changing the API and asking for possibly non-trivial changes in all protocol drivers, in order to accomodate semantics that all format drivers potentially could desire. So I wonder if the problem is simply that the current API is not expressive enough. Paolo
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
Am 24.10.2011 11:26, schrieb Paolo Bonzini: On 10/24/2011 10:54 AM, Kevin Wolf wrote: I don't know... checking BDRV_O_NO_FLUSH in the drivers rather than in the generic code sounds like a layering violation. Perhaps what you're after is a separation of bdrv_co_flush from bdrv_{,co_,aio_}fsync? Then BDRV_O_NO_FLUSH (better renamed to BDRV_O_NO_FSYNC...) would only inhibit the latter. Why? All other cache related BDRV_O_* flags are interpreted by the block drivers, so why should BDRV_O_NO_FLUSH be special? You're changing the API and asking for possibly non-trivial changes in all protocol drivers, in order to accomodate semantics that all format drivers potentially could desire. So I wonder if the problem is simply that the current API is not expressive enough. Can you think of any cases where a caller would want to invoke bdrv_flush, but not bdrv_fsync? (The other way round it makes even less sense) Kevin
[Qemu-devel] [PATCH] hw/9pfs: Make VirtFS tracing work correctly
From: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com this patch fix multiple issues with VirtFS tracing. a) Add tracepoint to the correct code path. We handle error in complete_pdu b) Fix indentation in python script c) Fix variable naming issue in python script Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/9pfs/virtio-9p.c | 60 +++--- scripts/analyse-9p-simpletrace.py | 164 ++-- trace-events |2 +- 3 files changed, 112 insertions(+), 114 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index aab3beb..8b6813f 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -969,7 +969,7 @@ static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len) if (s-proto_version == V9FS_PROTO_2000L) { id = P9_RLERROR; } -trace_complete_pdu(pdu-tag, pdu-id, err); /* Trace ERROR */ +trace_v9fs_rerror(pdu-tag, pdu-id, err); /* Trace ERROR */ } /* fill out the header */ @@ -1332,11 +1332,11 @@ static void v9fs_attach(void *opaque) } offset += pdu_marshal(pdu, offset, Q, qid); err = offset; +trace_v9fs_attach_return(pdu-tag, pdu-id, + qid.type, qid.version, qid.path); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_attach_return(pdu-tag, pdu-id, - qid.type, qid.version, qid.path); complete_pdu(s, pdu, err); v9fs_string_free(uname); v9fs_string_free(aname); @@ -1371,13 +1371,12 @@ static void v9fs_stat(void *opaque) } offset += pdu_marshal(pdu, offset, wS, 0, v9stat); err = offset; +trace_v9fs_stat_return(pdu-tag, pdu-id, v9stat.mode, + v9stat.atime, v9stat.mtime, v9stat.length); v9fs_stat_free(v9stat); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_stat_return(pdu-tag, pdu-id, v9stat.mode, - v9stat.atime, v9stat.mtime, v9stat.length); - complete_pdu(s, pdu, err); } @@ -1421,13 +1420,12 @@ static void v9fs_getattr(void *opaque) } retval = offset; retval += pdu_marshal(pdu, offset, A, v9stat_dotl); -out: -put_fid(pdu, fidp); -out_nofid: trace_v9fs_getattr_return(pdu-tag, pdu-id, v9stat_dotl.st_result_mask, v9stat_dotl.st_mode, v9stat_dotl.st_uid, v9stat_dotl.st_gid); - +out: +put_fid(pdu, fidp); +out_nofid: complete_pdu(s, pdu, retval); } @@ -1605,6 +1603,7 @@ static void v9fs_walk(void *opaque) v9fs_path_copy(newfidp-path, path); } err = v9fs_walk_marshal(pdu, nwnames, qids); +trace_v9fs_walk_return(pdu-tag, pdu-id, nwnames, qids); out: put_fid(pdu, fidp); if (newfidp) { @@ -1613,7 +1612,6 @@ out: v9fs_path_free(dpath); v9fs_path_free(path); out_nofid: -trace_v9fs_walk_return(pdu-tag, pdu-id, nwnames, qids); complete_pdu(s, pdu, err); if (nwnames nwnames = P9_MAXWELEM) { for (name_idx = 0; name_idx nwnames; name_idx++) { @@ -1648,10 +1646,10 @@ static int32_t get_iounit(V9fsPDU *pdu, V9fsPath *path) static void v9fs_open(void *opaque) { int flags; -int iounit; int32_t fid; int32_t mode; V9fsQID qid; +int iounit = 0; ssize_t err = 0; size_t offset = 7; struct stat stbuf; @@ -1709,11 +1707,11 @@ static void v9fs_open(void *opaque) offset += pdu_marshal(pdu, offset, Qd, qid, iounit); err = offset; } +trace_v9fs_open_return(pdu-tag, pdu-id, + qid.type, qid.version, qid.path, iounit); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_open_return(pdu-tag, pdu-id, - qid.type, qid.version, qid.path, iounit); complete_pdu(s, pdu, err); } @@ -1759,11 +1757,11 @@ static void v9fs_lcreate(void *opaque) stat_to_qid(stbuf, qid); offset += pdu_marshal(pdu, offset, Qd, qid, iounit); err = offset; +trace_v9fs_lcreate_return(pdu-tag, pdu-id, + qid.type, qid.version, qid.path, iounit); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_lcreate_return(pdu-tag, pdu-id, - qid.type, qid.version, qid.path, iounit); complete_pdu(pdu-s, pdu, err); v9fs_string_free(name); } @@ -1978,10 +1976,10 @@ static void v9fs_read(void *opaque) } else { err = -EINVAL; } +trace_v9fs_read_return(pdu-tag, pdu-id, count, err); out: put_fid(pdu, fidp); out_nofid: -trace_v9fs_read_return(pdu-tag, pdu-id, count, err); complete_pdu(s, pdu, err); } @@ -2090,10 +2088,10 @@ static void v9fs_readdir(void *opaque) retval = offset; retval += pdu_marshal(pdu, offset, d, count); retval += count; +trace_v9fs_readdir_return(pdu-tag, pdu-id, count, retval); out: put_fid(pdu, fidp); out_nofid: -
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
On 10/24/2011 11:36 AM, Kevin Wolf wrote: You're changing the API and asking for possibly non-trivial changes in all protocol drivers, in order to accomodate semantics that all format drivers potentially could desire. So I wonder if the problem is simply that the current API is not expressive enough. Can you think of any cases where a caller would want to invoke bdrv_flush, but not bdrv_fsync? (The other way round it makes even less sense) I'm talking about the internal driver API only. The external API is fine as is. Paolo
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
Am 24.10.2011 11:40, schrieb Paolo Bonzini: On 10/24/2011 11:36 AM, Kevin Wolf wrote: You're changing the API and asking for possibly non-trivial changes in all protocol drivers, in order to accomodate semantics that all format drivers potentially could desire. So I wonder if the problem is simply that the current API is not expressive enough. Can you think of any cases where a caller would want to invoke bdrv_flush, but not bdrv_fsync? (The other way round it makes even less sense) I'm talking about the internal driver API only. The external API is fine as is. Ok, so external callers don't force us to do it. Yes, we could split bdrv_flush internally into two functions for flush one level to the OS and flush all the way down to the disk, but I'm not sure if this really buys us anything or just adds complexity. Kevin
Re: [Qemu-devel] Question about intermediate code generation in qemu (tcg)
Thanks Peter. On Mon, Oct 24, 2011 at 7:39 PM, Peter Maydell peter.mayd...@linaro.orgwrote: On 24 October 2011 07:46, Carter Cheng carterch...@gmail.com wrote: I was wondering if someone could help me understand some aspects of the current qemu code generation routines. How are floating point and SSE ops currently handled? I do not see specific tcg routines for these cases(the README seems to indicate that FP and vector ops are not handled using the current IL). FP instructions are generally turned into code which calls out to a helper function written in C which emulates the floating point arithmetic -- see target-i386/op_helper.c for the x87 ops and target-i386/ops_sse.h for the SSE ops. (Some simple arithmetic vector ops might be done by generating inline code; ARM does this but I haven't checked target-i386.) IEEE arithmetic emulation is done in fpu/ but you probably don't need to look at the actual implementation... In the TCG intermediate representation there's no special support for float/double types -- they're just passed around as i32/i64. -- PMM
[Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
I have a qemu-kvm guest (apparently a Ubuntu 11.04 x86-64 install) which has stopped and refuses to continue: (qemu) info status VM status: paused (qemu) cont (qemu) info status VM status: paused The host is running linux 2.6.39.2 with qemu-kvm 0.14.1 on 24-core Opteron 6176 box, and has nine other 2GB production guests on it running absolutely fine. It's been a while since I've seen one of these. When I last saw a cluster of them, they were emulation failures (big real mode instructions, maybe?). I also remember a message about abnormal exit in the dmesg previously, but I don't have that here. This time, there is no host kernel output at all, just the paused guest. I have qemu monitor access and can even strace the relevant qemu process if necessary: is it possible to use this to diagnose what's caused this guest to stop, e.g. the unsupported instruction if it's an emulation failure? Cheers, Chris.
Re: [Qemu-devel] [PATCH 0/2] block: Write out internal caches even with cache=unsafe
On 10/24/2011 11:53 AM, Kevin Wolf wrote: I'm talking about the internal driver API only. The external API is fine as is. Ok, so external callers don't force us to do it. Yes, we could split bdrv_flush internally into two functions for flush one level to the OS and flush all the way down to the disk, but I'm not sure if this really buys us anything or just adds complexity. I would say that: 1) the safe NBD and iSCSI drivers are not in-tree, but you would have to convert those too. iSCSI uses aio, so it would be non-trivial. 2) long-term you wanted to convert raw-posix to coroutines, but in the meanwhile your patch introduces yet another partial transition; 3) your two patches are more complex compared to something like this: diff --git a/block.c b/block.c index 11c7f91..1e06a8a 100644 --- a/block.c +++ b/block.c @@ -2908,9 +2908,19 @@ 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) { +if (!bs-drv) { return 0; -} else if (!bs-drv) { +} + +/* First send everything to the OS. */ +if (bs-drv-bdrv_co_flush_metadata) { +int ret = bs-drv-bdrv_co_flush_metadata(bs); +if (ret 0) { +return ret; +} +} + +/* Now flush the host cache to disk if we need to. */ +if (bs-open_flags BDRV_O_NO_FLUSH) { return 0; } else if (bs-drv-bdrv_co_flush) { return bs-drv-bdrv_co_flush(bs); diff --git a/block/qcow2.c b/block/qcow2.c index a181932..cd13452 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_metadata(BlockDriverState *bs) { BDRVQcowState *s = bs-opaque; int ret; @@ -1121,7 +1121,11 @@ static int qcow2_co_flush(BlockDriverState *bs) return ret; } qemu_co_mutex_unlock(s-lock); +return 0; +} +static int qcow2_co_flush(BlockDriverState *bs) +{ return bdrv_co_flush(bs-file); } @@ -1244,6 +1248,7 @@ static BlockDriver bdrv_qcow2 = { .bdrv_co_readv = qcow2_co_readv, .bdrv_co_writev = qcow2_co_writev, .bdrv_co_flush = qcow2_co_flush, +.bdrv_co_flush_metadata = qcow2_co_flush_metadata, .bdrv_co_discard= qcow2_co_discard, .bdrv_truncate = qcow2_truncate, diff --git a/block_int.h b/block_int.h index dac00f5..ab4ceea 100644 --- a/block_int.h +++ b/block_int.h @@ -84,6 +84,7 @@ struct BlockDriver { 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_flush_metadata)(BlockDriverState *bs); int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs, int64_t sector_num, int nb_sectors); Paolo
[Qemu-devel] (no subject)
ff
Re: [Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
Am 24.10.2011 12:00, schrieb Chris Webb: I have a qemu-kvm guest (apparently a Ubuntu 11.04 x86-64 install) which has stopped and refuses to continue: (qemu) info status VM status: paused (qemu) cont (qemu) info status VM status: paused The host is running linux 2.6.39.2 with qemu-kvm 0.14.1 on 24-core Opteron 6176 box, and has nine other 2GB production guests on it running absolutely fine. It's been a while since I've seen one of these. When I last saw a cluster of them, they were emulation failures (big real mode instructions, maybe?). I also remember a message about abnormal exit in the dmesg previously, but I don't have that here. This time, there is no host kernel output at all, just the paused guest. I have qemu monitor access and can even strace the relevant qemu process if necessary: is it possible to use this to diagnose what's caused this guest to stop, e.g. the unsupported instruction if it's an emulation failure? Another common cause for stopped VMs are I/O errors, for example writes to a sparse image when the disk is full. Kevin
Re: [Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
Kevin Wolf kw...@redhat.com writes: Am 24.10.2011 12:00, schrieb Chris Webb: I have qemu monitor access and can even strace the relevant qemu process if necessary: is it possible to use this to diagnose what's caused this guest to stop, e.g. the unsupported instruction if it's an emulation failure? Another common cause for stopped VMs are I/O errors, for example writes to a sparse image when the disk is full. This guest are backed by LVM LVs so I don't think they can return EFULL, but I could imagine read errors, so I've just done a trivial test to make sure I can read them end-to-end: 0015# dd if=/dev/mapper/guest\:e549f8e1-4c0e-4dea-826a-e4b877282c07\:ide\:0\:0 of=/dev/null bs=1M 3136+0 records in 3136+0 records out 3288334336 bytes (3.3 GB) copied, 20.898 s, 157 MB/s 0015# dd if=/dev/mapper/guest\:e549f8e1-4c0e-4dea-826a-e4b877282c07\:ide\:0\:1 of=/dev/null bs=1M 276+0 records in 276+0 records out 289406976 bytes (289 MB) copied, 1.85218 s, 156 MB/s Is there any way to ask qemu why a guest has stopped, so I can distinguish IO problems from emulation problems from anything else? Cheers, Chris.
[Qemu-devel] KVM call agenda for October 25
Hi Please send in any agenda items you are interested in covering. Thanks, Juan.
Re: [Qemu-devel] [PATCH] fw_cfg: Use g_file_get_contents instead of multiple fread() calls
On 21 October 2011 12:35, Pavel Borzenkov pavel.borzen...@gmail.com wrote: Signed-off-by: Pavel Borzenkov pavel.borzen...@gmail.com Thanks; I think this looks a lot nicer than the raw file ops code did. I think we could probably make the error messages slightly more user friendly while we're here. + res = g_file_get_contents(filename, content, (gsize *)file_sizep, err); + if (res == FALSE) { + error_report(falied to read file '%s', filename); You've made a typo here (failed); also I think all the error messages in this function should say splash file rather than just file, and include the filename. + if (*file_sizep 30) { + error_report(file size is less than 30 bytes '%s', filename); + g_free(content); + return NULL; Rather than saying exactly what check failed (the user won't care) we should just say splash file '%s' format not recognized; must be JPEG or 24 bit BMP. + error_report('%s' not jpg/bmp file, head:0x%x., filename, filehead); and here also. if (bmp_bpp != 24) { error_report(only 24bpp bmp file is supported.); and here I think. -- PMM
Re: [Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
Am 24.10.2011 12:58, schrieb Chris Webb: Kevin Wolf kw...@redhat.com writes: Am 24.10.2011 12:00, schrieb Chris Webb: I have qemu monitor access and can even strace the relevant qemu process if necessary: is it possible to use this to diagnose what's caused this guest to stop, e.g. the unsupported instruction if it's an emulation failure? Another common cause for stopped VMs are I/O errors, for example writes to a sparse image when the disk is full. This guest are backed by LVM LVs so I don't think they can return EFULL, but I could imagine read errors, so I've just done a trivial test to make sure I can read them end-to-end: 0015# dd if=/dev/mapper/guest\:e549f8e1-4c0e-4dea-826a-e4b877282c07\:ide\:0\:0 of=/dev/null bs=1M 3136+0 records in 3136+0 records out 3288334336 bytes (3.3 GB) copied, 20.898 s, 157 MB/s 0015# dd if=/dev/mapper/guest\:e549f8e1-4c0e-4dea-826a-e4b877282c07\:ide\:0\:1 of=/dev/null bs=1M 276+0 records in 276+0 records out 289406976 bytes (289 MB) copied, 1.85218 s, 156 MB/s Is there any way to ask qemu why a guest has stopped, so I can distinguish IO problems from emulation problems from anything else? In qemu 1.0 we'll have an extended 'info status' that includes the stop reason, but 0.14 doesn't have this yet (was committed to git master only recently). If you attach a QMP monitor (see QMP/README, don't forget to send the capabilities command, it's part of creating the connection) you will receive messages for I/O errors, though. Kevin
Re: [Qemu-devel] [PATCH] target-arm: Tidy up ARM1136 CPUID naming
On 22 October 2011 11:33, Andreas Färber andreas.faer...@web.de wrote: Am 22.10.2011 12:20, schrieb Peter Maydell: On 3 October 2011 11:32, Andreas Färber andreas.faer...@web.de wrote: -#define ARM_CPUID_ARM1136 0x4117b363 -#define ARM_CPUID_ARM1136_R2 0x4107b362 +#define ARM_CPUID_ARM1136_R1P3 0x4117b363 +#define ARM_CPUID_ARM1136_R0P2 0x4107b362 I don't think the patchlevels are important enough to memorialise in the constant names. The important distinction in behaviour is between the r0 and r1, so I think that ARM1136_R0 vs _R1 would be better. Would you be okay if we do the following? #define ARM_CPUID_ARM1136_R0 ARM_CPUID_ARM1136_R0P2 #define ARM_CPUID_ARM1136_R1 ARM_CPUID_ARM1136_R1P3 Not sure that makes it any better. My point is that the number is actually hardcoded in there, whatever we name the constant. I think that's really the problem... -- PMM
Re: [Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
Kevin Wolf kw...@redhat.com writes: In qemu 1.0 we'll have an extended 'info status' that includes the stop reason, but 0.14 doesn't have this yet (was committed to git master only recently). Right, okay. I might take a look at cherry-picking and back-porting that to our version of qemu-kvm if it's not too entangled with other changes. It would be very useful in these situations. If you attach a QMP monitor (see QMP/README, don't forget to send the capabilities command, it's part of creating the connection) you will receive messages for I/O errors, though. Thanks. I don't think I can do this with an already-running qemu-kvm that's in a stopped state can I, only with a new qemu-kvm invocation and wait to try to catch the problem again? Cheers, Chris.
[Qemu-devel] [PATCH v2] fw_cfg: Use g_file_get_contents instead of multiple fread() calls
Signed-off-by: Pavel Borzenkov pavel.borzen...@gmail.com --- hw/fw_cfg.c | 102 ++- 1 files changed, 38 insertions(+), 64 deletions(-) diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c index 8df265c..dbcb888 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -60,71 +60,55 @@ struct FWCfgState { #define JPG_FILE 0 #define BMP_FILE 1 -static FILE *probe_splashfile(char *filename, int *file_sizep, int *file_typep) +static char *read_splashfile(char *filename, int *file_sizep, int *file_typep) { -FILE *fp = NULL; -int fop_ret; -int file_size; +GError *err = NULL; +gboolean res; +gchar *content; int file_type = -1; -unsigned char buf[2] = {0, 0}; -unsigned int filehead_value = 0; +unsigned int filehead = 0; int bmp_bpp; -fp = fopen(filename, rb); -if (fp == NULL) { -error_report(failed to open file '%s'., filename); -return fp; +res = g_file_get_contents(filename, content, (gsize *)file_sizep, err); +if (res == FALSE) { +error_report(failed to read splash file '%s', filename); +g_error_free(err); +return NULL; } + /* check file size */ -fseek(fp, 0L, SEEK_END); -file_size = ftell(fp); -if (file_size 2) { -error_report(file size is less than 2 bytes '%s'., filename); -fclose(fp); -fp = NULL; -return fp; +if (*file_sizep 30) { +goto error; } + /* check magic ID */ -fseek(fp, 0L, SEEK_SET); -fop_ret = fread(buf, 1, 2, fp); -if (fop_ret != 2) { -error_report(Could not read header from '%s': %s, - filename, strerror(errno)); -fclose(fp); -fp = NULL; -return fp; -} -filehead_value = (buf[0] + (buf[1] 8)) 0x; -if (filehead_value == 0xd8ff) { +filehead = ((content[0] 0xff) + (content[1] 8)) 0x; +if (filehead == 0xd8ff) { file_type = JPG_FILE; +} else if (filehead == 0x4d42) { +file_type = BMP_FILE; } else { -if (filehead_value == 0x4d42) { -file_type = BMP_FILE; -} -} -if (file_type 0) { -error_report('%s' not jpg/bmp file,head:0x%x., - filename, filehead_value); -fclose(fp); -fp = NULL; -return fp; +goto error; } + /* check BMP bpp */ if (file_type == BMP_FILE) { -fseek(fp, 28, SEEK_SET); -fop_ret = fread(buf, 1, 2, fp); -bmp_bpp = (buf[0] + (buf[1] 8)) 0x; +bmp_bpp = (content[28] + (content[29] 8)) 0x; if (bmp_bpp != 24) { -error_report(only 24bpp bmp file is supported.); -fclose(fp); -fp = NULL; -return fp; +goto error; } } + /* return values */ -*file_sizep = file_size; *file_typep = file_type; -return fp; + +return content; + +error: +error_report(splash file '%s' format not recognized; must be JPEG + or 24 bit BMP, filename); +g_free(content); +return NULL; } static void fw_cfg_bootsplash(FWCfgState *s) @@ -132,9 +116,7 @@ static void fw_cfg_bootsplash(FWCfgState *s) int boot_splash_time = -1; const char *boot_splash_filename = NULL; char *p; -char *filename; -FILE *fp; -int fop_ret; +char *filename, *file_data; int file_size; int file_type = -1; const char *temp; @@ -174,27 +156,19 @@ static void fw_cfg_bootsplash(FWCfgState *s) error_report(failed to find file '%s'., boot_splash_filename); return; } -/* probing the file */ -fp = probe_splashfile(filename, file_size, file_type); -if (fp == NULL) { + +/* loading file data */ +file_data = read_splashfile(filename, file_size, file_type); +if (file_data == NULL) { g_free(filename); return; } -/* loading file data */ if (boot_splash_filedata != NULL) { g_free(boot_splash_filedata); } -boot_splash_filedata = g_malloc(file_size); +boot_splash_filedata = (uint8_t *)file_data; boot_splash_filedata_size = file_size; -fseek(fp, 0L, SEEK_SET); -fop_ret = fread(boot_splash_filedata, 1, file_size, fp); -if (fop_ret != file_size) { -error_report(failed to read data from '%s'., - boot_splash_filename); -fclose(fp); -return; -} -fclose(fp); + /* insert data */ if (file_type == JPG_FILE) { fw_cfg_add_file(s, bootsplash.jpg, -- 1.7.0.4
[Qemu-devel] [PATCH] tools: reorganize Makefile variables
- Add all dependencies of the block layer to block-obj-y, and all dependencies of QObject to qobject-obj-y - Remove the block layer from tools-obj-y, add it to qemu-img, qemu-nbd, qemu-io - Add qobject-obj-y and tools-obj-y wherever useful, remove duplicates Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile | 32 +++- Makefile.objs |8 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index f63fc02..ba8d738 100644 --- a/Makefile +++ b/Makefile @@ -146,27 +146,25 @@ endif qemu-img.o: qemu-img-cmds.h qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: $(GENERATED_HEADERS) -tools-obj-y = qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) \ -$(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +tools-obj-y = qemu-tool.o $(oslib-obj-y) $(trace-obj-y) \ + qemu-timer-common.o cutils.o -qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) -qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) -qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) +qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) +qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y) +qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h $ $@, GEN $@) check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o test-coroutine.o: $(GENERATED_HEADERS) -CHECK_PROG_DEPS = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o - -check-qint: check-qint.o qint.o $(CHECK_PROG_DEPS) -check-qstring: check-qstring.o qstring.o $(CHECK_PROG_DEPS) -check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(CHECK_PROG_DEPS) -check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS) -check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS) -check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o qemu-error.o $(CHECK_PROG_DEPS) -test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y) $(CHECK_PROG_DEPS) +check-qint: check-qint.o qint.o $(tools-obj-y) +check-qstring: check-qstring.o qstring.o $(tools-obj-y) +check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(tools-obj-y) +check-qlist: check-qlist.o qlist.o qint.o $(tools-obj-y) +check-qfloat: check-qfloat.o qfloat.o $(tools-obj-y) +check-qjson: check-qjson.o $(qobject-obj-y) $(tools-obj-y) +test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y) $(tools-obj-y) $(qapi-obj-y): $(GENERATED_HEADERS) qapi-dir := qapi-generated @@ -204,16 +202,16 @@ qmp-marshal.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -m -o . $, GEN $@) test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y) -test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o +test-visitor: test-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y) -test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o +test-qmp-commands: test-qmp-commands.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.c qga-qapi-types.h qga-qapi-visit.c qga-qmp-marshal.c) $(QGALIB_GEN): $(GENERATED_HEADERS) $(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) -qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(qapi-obj-y) $(trace-obj-y) $(qobject-obj-y) $(version-obj-y) $(addprefix $(qapi-dir)/, qga-qapi-visit.o qga-qapi-types.o qga-qmp-marshal.o) +qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qobject-obj-y) $(version-obj-y) $(addprefix $(qapi-dir)/, qga-qapi-visit.o qga-qapi-types.o qga-qmp-marshal.o) QEMULIBS=libhw32 libhw64 libuser libdis libdis-user diff --git a/Makefile.objs b/Makefile.objs index 01587c8..a19e7c5 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -2,7 +2,7 @@ # QObject qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o
Re: [Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
Am 24.10.2011 13:29, schrieb Chris Webb: Kevin Wolf kw...@redhat.com writes: In qemu 1.0 we'll have an extended 'info status' that includes the stop reason, but 0.14 doesn't have this yet (was committed to git master only recently). Right, okay. I might take a look at cherry-picking and back-porting that to our version of qemu-kvm if it's not too entangled with other changes. It would be very useful in these situations. I'm afraid that it depends on many other changes, but you can try. If you attach a QMP monitor (see QMP/README, don't forget to send the capabilities command, it's part of creating the connection) you will receive messages for I/O errors, though. Thanks. I don't think I can do this with an already-running qemu-kvm that's in a stopped state can I, only with a new qemu-kvm invocation and wait to try to catch the problem again? Good point... The only other thing that I can think of would be attaching gdb and setting a breakpoint in vm_stop() or something. Kevin
Re: [Qemu-devel] KVM call agenda for October 25
On 10/24/2011 01:04 PM, Juan Quintela wrote: Hi Please send in any agenda items you are interested in covering. - What's left to merge for 1.0. - What kind of patch after the end of the freeze Paolo
Re: [Qemu-devel] KVM call agenda for October 25
On 24 October 2011 12:35, Paolo Bonzini pbonz...@redhat.com wrote: On 10/24/2011 01:04 PM, Juan Quintela wrote: Please send in any agenda items you are interested in covering. - What's left to merge for 1.0. Things on my list, FWIW: * current target-arm pullreq * PL041 support (needs another patch round to fix a minor bug Andrzej spotted) * cpu_single_env must be thread-local I also think that it's somewhat unfortunate that we now will compile on ARM hosts so that we always abort on startup (due to the reliance on a working makecontext()) but I'm not really sure how to deal with that one. -- PMM
[Qemu-devel] [PATCH 0/5] monitor+qxl: async monitor support
This patchset converts the screen_dump command to async across qemu, and then implements it asynchronously for the qxl device in Native mode. This fixes a hang that is caused when the spice client is also a qemu monitor client and the client is single threaded: io thread worker threadclient screendump do_screen_dump- read--- flush, read client socket- Monitor maintainers: The first patch changes the monitor command to be async. The rest are qxl changes only. Alon Levy (5): monitor: screen_dump async qxl: s/__FUNCTION__/__func__/, change logging levels qxl: support concurrent async commands qxl: split qxl_render_display_resized qxl: support async monitor screen dump console.c |5 +- console.h |7 +- hmp-commands.hx|3 +- hw/g364fb.c| 12 ++- hw/qxl-render.c| 136 -- hw/qxl.c | 236 +-- hw/qxl.h | 63 +- hw/vga.c |7 +- hw/vmware_vga.c|5 +- monitor.c |5 +- qmp-commands.hx|3 +- ui/spice-display.c | 19 ++-- ui/spice-display.h |7 +- 13 files changed, 363 insertions(+), 145 deletions(-) -- 1.7.7
Re: [Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
Kevin Wolf kw...@redhat.com writes: Good point... The only other thing that I can think of would be attaching gdb and setting a breakpoint in vm_stop() or something. Perfect, that seems to identified what's going on very nicely: (gdb) break vm_stop Breakpoint 1 at 0x407d10: file /home/root/packages/qemu-kvm/src-UMBurO/cpus.c, line 318. (gdb) fg Continuing. Breakpoint 1, vm_stop (reason=0) at /home/root/packages/qemu-kvm/src-UMBurO/cpus.c:318 318 /home/root/packages/qemu-kvm/src-UMBurO/cpus.c: No such file or directory. in /home/root/packages/qemu-kvm/src-UMBurO/cpus.c (gdb) bt #0 vm_stop (reason=0) at /home/root/packages/qemu-kvm/src-UMBurO/cpus.c:318 #1 0x0058585f in ide_handle_rw_error (s=0x20330d8, error=28, op=8) at /home/root/packages/qemu-kvm/src-UMBurO/hw/ide/core.c:468 #2 0x00588376 in ide_dma_cb (opaque=0x20330d8, ret=value optimized out) at /home/root/packages/qemu-kvm/src-UMBurO/hw/ide/core.c:494 #3 0x00590092 in dma_bdrv_cb (opaque=0x2043a10, ret=-28) at /home/root/packages/qemu-kvm/src-UMBurO/dma-helpers.c:94 #4 0x0044d64a in qcow2_aio_write_cb (opaque=0x2034900, ret=-28) at block/qcow2.c:714 #5 0x0043df6d in posix_aio_process_queue ( opaque=value optimized out) at posix-aio-compat.c:462 #6 0x0043e07d in posix_aio_read (opaque=0x17c8110) at posix-aio-compat.c:503 #7 0x00415fca in main_loop_wait (nonblocking=value optimized out) at /home/root/packages/qemu-kvm/src-UMBurO/vl.c:1383 #8 0x0042ca37 in kvm_main_loop () at /home/root/packages/qemu-kvm/src-UMBurO/qemu-kvm.c:1589 #9 0x004170a3 in main (argc=32, argv=value optimized out, envp=value optimized out) at /home/root/packages/qemu-kvm/src-UMBurO/vl.c:1429 I see what's happened here: we're not explicitly setting format=raw when we start that guest and someone's uploaded a qcow2 image directly to a block device. Ouch. Sorry for the noise! Best wishes, Chris.
[Qemu-devel] [PATCH 2/5] qxl: s/__FUNCTION__/__func__/, change logging levels
--- hw/qxl.c |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index 4003e53..af02cda 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -515,7 +515,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) switch (qxl-mode) { case QXL_MODE_VGA: -dprint(qxl, 2, %s: vga\n, __FUNCTION__); +dprint(qxl, 4, %s: vga\n, __func__); ret = false; qemu_mutex_lock(qxl-ssd.lock); if (qxl-ssd.update != NULL) { @@ -526,19 +526,19 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) } qemu_mutex_unlock(qxl-ssd.lock); if (ret) { -dprint(qxl, 2, %s %s\n, __FUNCTION__, qxl_mode_to_string(qxl-mode)); +dprint(qxl, 4, %s %s\n, __func__, qxl_mode_to_string(qxl-mode)); qxl_log_command(qxl, vga, ext); } return ret; case QXL_MODE_COMPAT: case QXL_MODE_NATIVE: case QXL_MODE_UNDEFINED: -dprint(qxl, 4, %s: %s\n, __FUNCTION__, qxl_mode_to_string(qxl-mode)); +dprint(qxl, 5, %s: %s\n, __func__, qxl_mode_to_string(qxl-mode)); ring = qxl-ram-cmd_ring; if (SPICE_RING_IS_EMPTY(ring)) { return false; } -dprint(qxl, 2, %s: %s\n, __FUNCTION__, qxl_mode_to_string(qxl-mode)); +dprint(qxl, 4, %s: %s\n, __func__, qxl_mode_to_string(qxl-mode)); SPICE_RING_CONS_ITEM(ring, cmd); ext-cmd = *cmd; ext-group_id = MEMSLOT_GROUP_GUEST; -- 1.7.7
[Qemu-devel] [PATCH 1/5] monitor: screen_dump async
Make screen_dump monitor command an async command to allow next for qxl to implement it as a initiating call to red_worker and completion on callback, to fix a deadlock when issueing a screendump command via libvirt while connected with a libvirt controlled spice-gtk client. This patch introduces no functional changes. --- console.c |5 +++-- console.h |7 +-- hmp-commands.hx |3 ++- hw/g364fb.c | 12 hw/qxl.c|6 -- hw/vga.c|7 +-- hw/vmware_vga.c |5 +++-- monitor.c |5 +++-- qmp-commands.hx |3 ++- 9 files changed, 35 insertions(+), 18 deletions(-) diff --git a/console.c b/console.c index e43de92..30c667a 100644 --- a/console.c +++ b/console.c @@ -173,7 +173,8 @@ void vga_hw_invalidate(void) active_console-hw_invalidate(active_console-hw); } -void vga_hw_screen_dump(const char *filename) +void vga_hw_screen_dump(const char *filename, MonitorCompletion cb, +void *opaque) { TextConsole *previous_active_console; @@ -183,7 +184,7 @@ void vga_hw_screen_dump(const char *filename) so always dump the first one. */ console_select(0); if (consoles[0] consoles[0]-hw_screen_dump) { -consoles[0]-hw_screen_dump(consoles[0]-hw, filename); +consoles[0]-hw_screen_dump(consoles[0]-hw, filename, cb, opaque); } console_select(previous_active_console-index); diff --git a/console.h b/console.h index 9c1487e..dde4088 100644 --- a/console.h +++ b/console.h @@ -343,7 +343,9 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch) typedef void (*vga_hw_update_ptr)(void *); typedef void (*vga_hw_invalidate_ptr)(void *); -typedef void (*vga_hw_screen_dump_ptr)(void *, const char *); +typedef void (*vga_hw_screen_dump_ptr)(void *, const char *, + MonitorCompletion *, + void *); typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *); DisplayState *graphic_console_init(vga_hw_update_ptr update, @@ -354,7 +356,8 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update, void vga_hw_update(void); void vga_hw_invalidate(void); -void vga_hw_screen_dump(const char *filename); +void vga_hw_screen_dump(const char *filename, MonitorCompletion cb, +void *opaque); void vga_hw_text_update(console_ch_t *chardata); int is_graphic_console(void); diff --git a/hmp-commands.hx b/hmp-commands.hx index ab08d58..a7b3494 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -157,7 +157,8 @@ ETEXI .params = filename, .help = save screen into PPM image 'filename', .user_print = monitor_user_noop, -.mhandler.cmd_new = do_screen_dump, +.mhandler.cmd_async = do_screen_dump, +.flags = MONITOR_CMD_ASYNC, }, STEXI diff --git a/hw/g364fb.c b/hw/g364fb.c index f00ee27..5884e20 100644 --- a/hw/g364fb.c +++ b/hw/g364fb.c @@ -291,7 +291,8 @@ static void g364fb_reset(G364State *s) g364fb_invalidate_display(s); } -static void g364fb_screen_dump(void *opaque, const char *filename) +static void g364fb_screen_dump(void *opaque, const char *filename, + MonitorCompletion *cb, void *cb_opaque) { G364State *s = opaque; int y, x; @@ -303,12 +304,13 @@ static void g364fb_screen_dump(void *opaque, const char *filename) if (s-depth != 8) { error_report(g364: unknown guest depth %d, s-depth); -return; +goto end; } f = fopen(filename, wb); -if (!f) -return; +if (!f) { +goto end; +} if (s-ctla CTLA_FORCE_BLANK) { /* blank screen */ @@ -331,6 +333,8 @@ static void g364fb_screen_dump(void *opaque, const char *filename) } fclose(f); +end: +cb(cb_opaque, NULL); } /* called for accesses to io ports */ diff --git a/hw/qxl.c b/hw/qxl.c index 03848ed..4003e53 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1423,7 +1423,8 @@ static void qxl_hw_invalidate(void *opaque) vga-invalidate(vga); } -static void qxl_hw_screen_dump(void *opaque, const char *filename) +static void qxl_hw_screen_dump(void *opaque, const char *filename, + MonitorCompletion *cb, void *cb_opaque) { PCIQXLDevice *qxl = opaque; VGACommonState *vga = qxl-vga; @@ -1433,9 +1434,10 @@ static void qxl_hw_screen_dump(void *opaque, const char *filename) case QXL_MODE_NATIVE: qxl_render_update(qxl); ppm_save(filename, qxl-ssd.ds-surface); +cb(cb_opaque, NULL); break; case QXL_MODE_VGA: -vga-screen_dump(vga, filename); +vga-screen_dump(vga, filename, cb, cb_opaque); break; default: break; diff --git a/hw/vga.c b/hw/vga.c index ca79aa1..b257f74 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -148,7 +148,8 @@ static uint32_t expand4[256]; static uint16_t
[Qemu-devel] [PATCH 3/5] qxl: support concurrent async commands
change the single pending current_async to a linked list of pending SpiceAsyncCommand. Signed-off-by: Alon Levy al...@redhat.com --- hw/qxl-render.c|2 +- hw/qxl.c | 145 +++- hw/qxl.h | 29 +-- ui/spice-display.c | 19 --- ui/spice-display.h |7 ++- 5 files changed, 137 insertions(+), 65 deletions(-) diff --git a/hw/qxl-render.c b/hw/qxl-render.c index c290739..23a4289 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -125,7 +125,7 @@ void qxl_render_update(PCIQXLDevice *qxl) memset(dirty, 0, sizeof(dirty)); qxl_spice_update_area(qxl, 0, update, - dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC); + dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC, 0); for (i = 0; i ARRAY_SIZE(dirty); i++) { if (qemu_spice_rect_is_empty(dirty+i)) { diff --git a/hw/qxl.c b/hw/qxl.c index af02cda..008f5f7 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -120,7 +120,8 @@ static QXLMode qxl_modes[] = { static PCIQXLDevice *qxl0; static void qxl_send_events(PCIQXLDevice *d, uint32_t events); -static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async); +static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async, + uint64_t cookie); static void qxl_reset_memslots(PCIQXLDevice *d); static void qxl_reset_surfaces(PCIQXLDevice *d); static void qxl_ring_set_dirty(PCIQXLDevice *qxl); @@ -140,12 +141,11 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) } } - void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, struct QXLRect *area, struct QXLRect *dirty_rects, uint32_t num_dirty_rects, uint32_t clear_dirty_region, - qxl_async_io async) + qxl_async_io async, uint64_t cookie) { if (async == QXL_SYNC) { qxl-ssd.worker-update_area(qxl-ssd.worker, surface_id, area, @@ -153,7 +153,7 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, } else { #if SPICE_INTERFACE_QXL_MINOR = 1 spice_qxl_update_area_async(qxl-ssd.qxl, surface_id, area, -clear_dirty_region, 0); +clear_dirty_region, cookie); #else abort(); #endif @@ -170,14 +170,13 @@ static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl, } static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id, - qxl_async_io async) + qxl_async_io async, uint64_t cookie) { if (async) { #if SPICE_INTERFACE_QXL_MINOR 1 abort(); #else -spice_qxl_destroy_surface_async(qxl-ssd.qxl, id, -(uint64_t)id); +spice_qxl_destroy_surface_async(qxl-ssd.qxl, id, cookie); #endif } else { qxl-ssd.worker-destroy_surface_wait(qxl-ssd.worker, id); @@ -186,9 +185,9 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id, } #if SPICE_INTERFACE_QXL_MINOR = 1 -static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl) +static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl, uint64_t cookie) { -spice_qxl_flush_surfaces_async(qxl-ssd.qxl, 0); +spice_qxl_flush_surfaces_async(qxl-ssd.qxl, cookie); } #endif @@ -216,13 +215,14 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl) qemu_mutex_unlock(qxl-track_lock); } -static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async) +static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async, + uint64_t cookie) { if (async) { #if SPICE_INTERFACE_QXL_MINOR 1 abort(); #else -spice_qxl_destroy_surfaces_async(qxl-ssd.qxl, 0); +spice_qxl_destroy_surfaces_async(qxl-ssd.qxl, cookie); #endif } else { qxl-ssd.worker-destroy_surfaces(qxl-ssd.worker); @@ -736,17 +736,61 @@ static void qxl_create_guest_primary_complete(PCIQXLDevice *d); #if SPICE_INTERFACE_QXL_MINOR = 1 +SpiceAsyncCommand *push_spice_async_command(PCIQXLDevice *qxl, +uint32_t async_io, int size) +{ +assert(size = sizeof(SpiceAsyncCommand)); +SpiceAsyncCommand *spice_async_command = g_malloc0(size); + +spice_async_command-cookie = qxl-async_next_cookie++; +spice_async_command-async_io = async_io; +QLIST_INSERT_HEAD(qxl-async_commands, spice_async_command, next); +dprint(qxl, 2, allocated async cookie %PRId64\n, + qxl-async_next_cookie - 1); +return spice_async_command; +} + +/* caller must call g_free */ +static SpiceAsyncCommand *pop_spice_async_command(PCIQXLDevice *qxl, + uint64_t cookie) +{ +SpiceAsyncCommand *spice_async_command = NULL;
[Qemu-devel] [PATCH 5/5] qxl: support async monitor screen dump
Split qxl_spice_update_area_complete from qxl_render_update, use SPICE_INTERFACE_QXL_MINOR 2 introduced spice_qxl_update_area_dirty_async to retrive the dirty rectangles asyncronously (the previous spice_qxl_update_area_async did not accept a dirty rectangles array). Introduce SpiceAsyncMonitorScreenDump for a screen_dump. vga mode screen dumps are still synchronous. Signed-off-by: Alon Levy al...@redhat.com --- patchcheck gives one false positive, identifying a point function argument as a multiplication: ERROR: need consistent spacing around '*' (ctx:WxV) #135: FILE: hw/qxl.c:148: + SpiceAsyncCommand *async_command) ^ --- hw/qxl-render.c | 67 +- hw/qxl.c| 95 +++--- hw/qxl.h| 38 -- 3 files changed, 161 insertions(+), 39 deletions(-) diff --git a/hw/qxl-render.c b/hw/qxl-render.c index fd3c016..7dfd67f 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -27,6 +27,10 @@ static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect) uint8_t *dst = qxl-guest_primary.flipped; int len, i; +assert(rect-bottom = 0); +assert(rect-bottom = qxl-guest_primary.surface.height); +assert(rect-top = 0); +assert(rect-top = qxl-guest_primary.surface.height); src += (qxl-guest_primary.surface.height - rect-top - 1) * qxl-guest_primary.stride; dst += rect-top * qxl-guest_primary.stride; @@ -110,17 +114,39 @@ static void qxl_render_display_resized(PCIQXLDevice *qxl) dpy_resize(vga-ds); } -void qxl_render_update(PCIQXLDevice *qxl) +void qxl_spice_update_area_complete(PCIQXLDevice *qxl, QXLRect *dirty, +int n_dirty) { VGACommonState *vga = qxl-vga; -QXLRect dirty[32], update; int i; +for (i = 0; i n_dirty; i++) { +if (qemu_spice_rect_is_empty(dirty + i)) { +break; +} +if (qxl-guest_primary.flipped) { +qxl_flip(qxl, dirty + i); +} +dpy_update(vga-ds, + dirty[i].left, dirty[i].top, + dirty[i].right - dirty[i].left, + dirty[i].bottom - dirty[i].top); +} +} + +void qxl_render_update(PCIQXLDevice *qxl, + SpiceAsyncMonitorScreenDump *async_screen_dump) +{ +QXLRect dirty[32], update; + if (qxl-guest_primary.resized) { qxl_render_display_resized(qxl); } - if (!qxl-guest_primary.commands) { +if (async_screen_dump) { +dprint(qxl, 2, %s: no update required\n, __func__); +complete_spice_async_command(qxl, async_screen_dump-base); +} return; } qxl-guest_primary.commands = 0; @@ -131,20 +157,29 @@ void qxl_render_update(PCIQXLDevice *qxl) update.bottom = qxl-guest_primary.surface.height; memset(dirty, 0, sizeof(dirty)); +if (async_screen_dump) { +#if SPICE_INTERFACE_QXL_MINOR = 2 +dprint(qxl, 2, A-SYNC update_area 0 (%d,%d,%d,%d)\n, + update.top, update.left, update.bottom, update.right); +async_screen_dump-n_dirty = 32; +async_screen_dump-dirty = g_malloc0(sizeof(QXLRect) * +async_screen_dump-n_dirty); +qxl_spice_update_area(qxl, 0, update, + async_screen_dump-dirty, + async_screen_dump-n_dirty, 1, + async_screen_dump-base); +return; +#else +fprintf(stderr, %s: warning: fallback to sync, spice-server 0.8.4\n, +__func__); +#endif +} +dprint(qxl, 2, SYNC update_area\n); qxl_spice_update_area(qxl, 0, update, - dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC, 0); - -for (i = 0; i ARRAY_SIZE(dirty); i++) { -if (qemu_spice_rect_is_empty(dirty+i)) { -break; -} -if (qxl-guest_primary.flipped) { -qxl_flip(qxl, dirty+i); -} -dpy_update(vga-ds, - dirty[i].left, dirty[i].top, - dirty[i].right - dirty[i].left, - dirty[i].bottom - dirty[i].top); + dirty, ARRAY_SIZE(dirty), 1, NULL); +qxl_spice_update_area_complete(qxl, dirty, ARRAY_SIZE(dirty)); +if (async_screen_dump) { +complete_spice_async_command(qxl, async_screen_dump-base); } } diff --git a/hw/qxl.c b/hw/qxl.c index 008f5f7..a3e89cd 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -145,18 +145,32 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, struct QXLRect *area, struct QXLRect *dirty_rects, uint32_t num_dirty_rects, uint32_t clear_dirty_region, - qxl_async_io async, uint64_t cookie) + SpiceAsyncCommand *async_command) { -if (async == QXL_SYNC) { +
[Qemu-devel] [PATCH 4/5] qxl: split qxl_render_display_resized
Signed-off-by: Alon Levy al...@redhat.com --- hw/qxl-render.c | 75 ++- 1 files changed, 41 insertions(+), 34 deletions(-) diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 23a4289..fd3c016 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -70,47 +70,54 @@ void qxl_render_resize(PCIQXLDevice *qxl) } } +static void qxl_render_display_resized(PCIQXLDevice *qxl) +{ +VGACommonState *vga = qxl-vga; +void *ptr; + +qxl-guest_primary.resized = 0; + +if (qxl-guest_primary.flipped) { +g_free(qxl-guest_primary.flipped); +qxl-guest_primary.flipped = NULL; +} +qemu_free_displaysurface(vga-ds); + +qxl-guest_primary.data = memory_region_get_ram_ptr(qxl-vga.vram); +if (qxl-guest_primary.stride 0) { +/* spice surface is upside down - need extra buffer to flip */ +qxl-guest_primary.stride = -qxl-guest_primary.stride; +qxl-guest_primary.flipped = g_malloc(qxl-guest_primary.surface.width * + qxl-guest_primary.stride); +ptr = qxl-guest_primary.flipped; +} else { +ptr = qxl-guest_primary.data; +} +dprint(qxl, 1, %s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n, + __func__, + qxl-guest_primary.surface.width, + qxl-guest_primary.surface.height, + qxl-guest_primary.stride, + qxl-guest_primary.bytes_pp, + qxl-guest_primary.bits_pp, + qxl-guest_primary.flipped ? yes : no); +vga-ds-surface = +qemu_create_displaysurface_from(qxl-guest_primary.surface.width, +qxl-guest_primary.surface.height, +qxl-guest_primary.bits_pp, +qxl-guest_primary.stride, +ptr); +dpy_resize(vga-ds); +} + void qxl_render_update(PCIQXLDevice *qxl) { VGACommonState *vga = qxl-vga; QXLRect dirty[32], update; -void *ptr; int i; if (qxl-guest_primary.resized) { -qxl-guest_primary.resized = 0; - -if (qxl-guest_primary.flipped) { -g_free(qxl-guest_primary.flipped); -qxl-guest_primary.flipped = NULL; -} -qemu_free_displaysurface(vga-ds); - -qxl-guest_primary.data = memory_region_get_ram_ptr(qxl-vga.vram); -if (qxl-guest_primary.stride 0) { -/* spice surface is upside down - need extra buffer to flip */ -qxl-guest_primary.stride = -qxl-guest_primary.stride; -qxl-guest_primary.flipped = g_malloc(qxl-guest_primary.surface.width * - qxl-guest_primary.stride); -ptr = qxl-guest_primary.flipped; -} else { -ptr = qxl-guest_primary.data; -} -dprint(qxl, 1, %s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n, - __FUNCTION__, - qxl-guest_primary.surface.width, - qxl-guest_primary.surface.height, - qxl-guest_primary.stride, - qxl-guest_primary.bytes_pp, - qxl-guest_primary.bits_pp, - qxl-guest_primary.flipped ? yes : no); -vga-ds-surface = -qemu_create_displaysurface_from(qxl-guest_primary.surface.width, -qxl-guest_primary.surface.height, -qxl-guest_primary.bits_pp, -qxl-guest_primary.stride, -ptr); -dpy_resize(vga-ds); +qxl_render_display_resized(qxl); } if (!qxl-guest_primary.commands) { -- 1.7.7
Re: [Qemu-devel] KVM call agenda for October 25
Am 24.10.2011 14:02, schrieb Peter Maydell: On 24 October 2011 12:35, Paolo Bonzini pbonz...@redhat.com wrote: On 10/24/2011 01:04 PM, Juan Quintela wrote: Please send in any agenda items you are interested in covering. - What's left to merge for 1.0. I also think that it's somewhat unfortunate that we now will compile on ARM hosts so that we always abort on startup (due to the reliance on a working makecontext()) but I'm not really sure how to deal with that one. FWIW we're also not working / not building on Darwin ppc+Intel, which is related to a) softfloat integer types, b) GThread initialization, c) unknown issues. Bisecting did not work well and I am lacking time and ideas to investigate and fix this. For softfloat there are several solutions around, in need of a decision. Nice to merge would be the Cocoa sheet issue, once verified. Andreas
Re: [Qemu-devel] [PATCH v2 1/4] Add basic version of bridge helper
On 10/23/2011 08:56 AM, Blue Swirl wrote: On Fri, Oct 21, 2011 at 15:07, Corey Bryantcor...@linux.vnet.ibm.com wrote: This patch adds a helper that can be used to create a tap device attached to a bridge device. Since this helper is minimal in what it does, it can be given CAP_NET_ADMIN which allows qemu to avoid running as root while still satisfying the majority of what users tend to want to do with tap devices. The way this all works is that qemu launches this helper passing a bridge name and the name of an inherited file descriptor. The descriptor is one end of a socketpair() of domain sockets. This domain socket is used to transmit a file descriptor of the opened tap device from the helper to qemu. The helper can then exit and let qemu use the tap device. Signed-off-by: Anthony Liguorialigu...@us.ibm.com Signed-off-by: Richa Marwaharmar...@linux.vnet.ibm.com Signed-off-by: Corey Bryantcor...@linux.vnet.ibm.com --- Makefile | 12 +++- configure|1 + qemu-bridge-helper.c | 205 ++ 3 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 qemu-bridge-helper.c diff --git a/Makefile b/Makefile index f63fc02..d9b447e 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,8 @@ $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw) LIBS+=-lz $(LIBS_TOOLS) +HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF) + ifdef BUILD_DOCS DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 QMP/qmp-commands.txt else @@ -75,7 +77,7 @@ defconfig: -include config-all-devices.mak -build-all: $(DOCS) $(TOOLS) recurse-all +build-all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all config-host.h: config-host.h-timestamp config-host.h-timestamp: config-host.mak @@ -153,6 +155,8 @@ qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) +qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o + qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h $$@, GEN $@) @@ -221,7 +225,7 @@ clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f qemu-options.def - rm -f *.o *.d *.a *.lo $(TOOLS) qemu-ga TAGS cscope.* *.pod *~ */*~ + rm -f *.o *.d *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ rm -Rf .libs rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d rm -f qemu-img-cmds.h @@ -289,6 +293,10 @@ install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig ifneq ($(TOOLS),) $(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) $(DESTDIR)$(bindir) endif +ifneq ($(HELPERS-y),) + $(INSTALL_DIR) $(DESTDIR)$(libexecdir) + $(INSTALL_PROG) $(STRIP_OPT) $(HELPERS-y) $(DESTDIR)$(libexecdir) +endif ifneq ($(BLOBS),) $(INSTALL_DIR) $(DESTDIR)$(datadir) set -e; for x in $(BLOBS); do \ diff --git a/configure b/configure index 4f87e0a..6c8b659 100755 --- a/configure +++ b/configure @@ -2768,6 +2768,7 @@ echo datadir=$datadir $config_host_mak echo sysconfdir=$sysconfdir $config_host_mak echo docdir=$docdir $config_host_mak echo confdir=$confdir $config_host_mak +echo libexecdir=\${prefix}/libexec $config_host_mak case $cpu in i386|x86_64|alpha|cris|hppa|ia64|lm32|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64|unicore32) diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c new file mode 100644 index 000..2ce82fb --- /dev/null +++ b/qemu-bridge-helper.c @@ -0,0 +1,205 @@ +/* + * QEMU Bridge Helper + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguorialigu...@us.ibm.com + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include config-host.h + +#includestdio.h +#includeerrno.h +#includefcntl.h +#includeunistd.h +#includestring.h +#includestdlib.h +#includectype.h + +#includesys/types.h +#includesys/ioctl.h +#includesys/socket.h +#includesys/un.h +#includesys/prctl.h + +#includenet/if.h + +#includelinux/sockios.h + +#include net/tap-linux.h + +static int has_vnet_hdr(int fd) +{ +unsigned int features = 0; +struct ifreq ifreq; + +if (ioctl(fd, TUNGETFEATURES,features) == -1) { +return -errno; +} + +if (!(features IFF_VNET_HDR)) { +return -ENOTSUP; +} + +if (ioctl(fd, TUNGETIFF,ifreq) != -1 || errno != EBADFD) { +return -ENOTSUP; +} + +return 1; +} + +static void prep_ifreq(struct ifreq *ifr, const char *ifname) +{ +memset(ifr, 0, sizeof(*ifr)); +snprintf(ifr-ifr_name, IFNAMSIZ, %s, ifname); +} + +static int send_fd(int c, int fd) +{ +char
[Qemu-devel] [PATCH 06/19] qapi: Convert the cpu command
Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- hmp-commands.hx |3 +-- hmp.c| 12 hmp.h|1 + monitor.c| 11 --- qapi-schema.json | 11 +++ qmp-commands.hx |5 + qmp.c|5 + 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index ab08d58..969ccf5 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -587,8 +587,7 @@ ETEXI .args_type = index:i, .params = index, .help = set the default CPU, -.user_print = monitor_user_noop, -.mhandler.cmd_new = do_cpu_set, +.mhandler.cmd = hmp_cpu, }, STEXI diff --git a/hmp.c b/hmp.c index 619b8ba..35b0ca0 100644 --- a/hmp.c +++ b/hmp.c @@ -165,3 +165,15 @@ void hmp_system_powerdown(Monitor *mon, const QDict *qdict) { qmp_system_powerdown(NULL); } + +void hmp_cpu(Monitor *mon, const QDict *qdict) +{ +int64_t cpu_index; + +/* XXX: drop the monitor_set_cpu() usage when all HMP commands that +use it are converted to the QAPI */ +cpu_index = qdict_get_int(qdict, index); +if (monitor_set_cpu(cpu_index) 0) { +monitor_printf(mon, invalid CPU index\n); +} +} diff --git a/hmp.h b/hmp.h index 49d9662..9322b7f 100644 --- a/hmp.h +++ b/hmp.h @@ -29,5 +29,6 @@ void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); void hmp_system_powerdown(Monitor *mon, const QDict *qdict); +void hmp_cpu(Monitor *mon, const QDict *qdict); #endif diff --git a/monitor.c b/monitor.c index 3e1cd33..1edb646 100644 --- a/monitor.c +++ b/monitor.c @@ -902,17 +902,6 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data) *ret_data = QOBJECT(cpu_list); } -static int do_cpu_set(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ -int index = qdict_get_int(qdict, index); -if (monitor_set_cpu(index) 0) { -qerror_report(QERR_INVALID_PARAMETER_VALUE, index, - a CPU number); -return -1; -} -return 0; -} - static void do_info_jit(Monitor *mon) { dump_exec_info((FILE *)mon, monitor_fprintf); diff --git a/qapi-schema.json b/qapi-schema.json index eb155b4..e4cf6da 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -351,3 +351,14 @@ #prompting the user in some way. ## { 'command': 'system_powerdown' } + +## +# @cpu: +# +# This command is a nop that is only provided for the purposes of compatibility. +# +# Since: 0.14.0 +# +# Notes: Do not use this command. +## +{ 'command': 'cpu', 'data': {'index': 'int'} } diff --git a/qmp-commands.hx b/qmp-commands.hx index 8efdb25..dcca53c 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -331,10 +331,7 @@ EQMP { .name = cpu, .args_type = index:i, -.params = index, -.help = set the default CPU, -.user_print = monitor_user_noop, -.mhandler.cmd_new = do_cpu_set, +.mhandler.cmd_new = qmp_marshal_input_cpu, }, SQMP diff --git a/qmp.c b/qmp.c index bf58b05..e84922b 100644 --- a/qmp.c +++ b/qmp.c @@ -90,3 +90,8 @@ void qmp_system_powerdown(Error **erp) { qemu_system_powerdown_request(); } + +void qmp_cpu(int64_t index, Error **errp) +{ +/* Just do nothing */ +} -- 1.7.7.1.431.g10b2a
[Qemu-devel] [PATCH 11/19] qapi: Convert query-blockstats
Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- block.c | 111 ++ hmp.c| 34 hmp.h|1 + monitor.c| 11 +- qapi-schema.json | 67 qmp-commands.hx |6 +++ 6 files changed, 146 insertions(+), 84 deletions(-) diff --git a/block.c b/block.c index af0ea5e..19024a6 100644 --- a/block.c +++ b/block.c @@ -1925,93 +1925,56 @@ BlockInfoList *qmp_query_block(Error **errp) return head; } -static void bdrv_stats_iter(QObject *data, void *opaque) -{ -QDict *qdict; -Monitor *mon = opaque; - -qdict = qobject_to_qdict(data); -monitor_printf(mon, %s:, qdict_get_str(qdict, device)); - -qdict = qobject_to_qdict(qdict_get(qdict, stats)); -monitor_printf(mon, rd_bytes=% PRId64 - wr_bytes=% PRId64 - rd_operations=% PRId64 - wr_operations=% PRId64 - flush_operations=% PRId64 - wr_total_time_ns=% PRId64 - rd_total_time_ns=% PRId64 - flush_total_time_ns=% PRId64 -\n, -qdict_get_int(qdict, rd_bytes), -qdict_get_int(qdict, wr_bytes), -qdict_get_int(qdict, rd_operations), -qdict_get_int(qdict, wr_operations), -qdict_get_int(qdict, flush_operations), -qdict_get_int(qdict, wr_total_time_ns), -qdict_get_int(qdict, rd_total_time_ns), -qdict_get_int(qdict, flush_total_time_ns)); -} - -void bdrv_stats_print(Monitor *mon, const QObject *data) -{ -qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); -} - -static QObject* bdrv_info_stats_bs(BlockDriverState *bs) -{ -QObject *res; -QDict *dict; - -res = qobject_from_jsonf({ 'stats': { - 'rd_bytes': % PRId64 , - 'wr_bytes': % PRId64 , - 'rd_operations': % PRId64 , - 'wr_operations': % PRId64 , - 'wr_highest_offset': % PRId64 , - 'flush_operations': % PRId64 , - 'wr_total_time_ns': % PRId64 , - 'rd_total_time_ns': % PRId64 , - 'flush_total_time_ns': % PRId64 - } }, - bs-nr_bytes[BDRV_ACCT_READ], - bs-nr_bytes[BDRV_ACCT_WRITE], - bs-nr_ops[BDRV_ACCT_READ], - bs-nr_ops[BDRV_ACCT_WRITE], - bs-wr_highest_sector * - (uint64_t)BDRV_SECTOR_SIZE, - bs-nr_ops[BDRV_ACCT_FLUSH], - bs-total_time_ns[BDRV_ACCT_WRITE], - bs-total_time_ns[BDRV_ACCT_READ], - bs-total_time_ns[BDRV_ACCT_FLUSH]); -dict = qobject_to_qdict(res); - -if (*bs-device_name) { -qdict_put(dict, device, qstring_from_str(bs-device_name)); +/* Consider exposing this as a full fledged QMP command */ +static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp) +{ +BlockStats *s; + +s = g_malloc0(sizeof(*s)); + +if (bs-device_name[0]) { +s-has_device = true; +s-device = g_strdup(bs-device_name); } +s-stats = g_malloc0(sizeof(*s-stats)); +s-stats-rd_bytes = bs-nr_bytes[BDRV_ACCT_READ]; +s-stats-wr_bytes = bs-nr_bytes[BDRV_ACCT_WRITE]; +s-stats-rd_operations = bs-nr_ops[BDRV_ACCT_READ]; +s-stats-wr_operations = bs-nr_ops[BDRV_ACCT_WRITE]; +s-stats-wr_highest_offset = bs-wr_highest_sector * BDRV_SECTOR_SIZE; +s-stats-flush_operations = bs-nr_ops[BDRV_ACCT_FLUSH]; +s-stats-wr_total_time_ns = bs-total_time_ns[BDRV_ACCT_WRITE]; +s-stats-rd_total_time_ns = bs-total_time_ns[BDRV_ACCT_READ]; +s-stats-flush_total_time_ns = bs-total_time_ns[BDRV_ACCT_FLUSH]; + if (bs-file) { -QObject *parent = bdrv_info_stats_bs(bs-file); -qdict_put_obj(dict, parent, parent); +s-has_parent = true; +s-parent = qmp_query_blockstat(bs-file, NULL); } -return res; +return s; } -void bdrv_info_stats(Monitor *mon, QObject **ret_data) +BlockStatsList *qmp_query_blockstats(Error **errp) { -QObject *obj; -QList *devices; +BlockStatsList *head = NULL, *cur_item = NULL; BlockDriverState *bs; -devices = qlist_new(); - QTAILQ_FOREACH(bs, bdrv_states, list) { -obj = bdrv_info_stats_bs(bs); -qlist_append_obj(devices, obj); +BlockStatsList *info = g_malloc0(sizeof(*info));
[Qemu-devel] [PATCH 19/19] Drop qemu-objects.h from modules that don't require it
Previous commits dropped most qobjects usage from qemu modules (now they are a low level interface used by the QAPI). However, some modules still include the qemu-objects.h header file. This commit drops qemu-objects.h from some of those modules and includes qjson.h instead, which is what they actually need. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- block.c |2 +- error.c |3 ++- vl.c|2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 19024a6..1e5ec78 100644 --- a/block.c +++ b/block.c @@ -27,7 +27,7 @@ #include monitor.h #include block_int.h #include module.h -#include qemu-objects.h +#include qjson.h #include qemu-coroutine.h #include qmp-commands.h diff --git a/error.c b/error.c index 68c0039..990050f 100644 --- a/error.c +++ b/error.c @@ -12,8 +12,9 @@ #include qemu-common.h #include error.h +#include qjson.h +#include qdict.h #include error_int.h -#include qemu-objects.h #include qerror.h struct Error diff --git a/vl.c b/vl.c index 66f70fb..3292296 100644 --- a/vl.c +++ b/vl.c @@ -143,9 +143,9 @@ int main(int argc, char **argv) #include audio/audio.h #include migration.h #include kvm.h +#include qjson.h #include qemu-option.h #include qemu-config.h -#include qemu-objects.h #include qemu-options.h #include qmp-commands.h #ifdef CONFIG_VIRTFS -- 1.7.7.1.431.g10b2a
[Qemu-devel] [PATCH 18/19] Monitor: do_info(): Drop QMP command handling code
Previous commits converted all existing QMP commands to the QAPI, now each info command does its own QMP call. Let's then drop all QMP command handling code from do_info(). Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- monitor.c | 32 +--- 1 files changed, 1 insertions(+), 31 deletions(-) diff --git a/monitor.c b/monitor.c index 1e09b91..e3c7d0d 100644 --- a/monitor.c +++ b/monitor.c @@ -123,8 +123,6 @@ typedef struct mon_cmd_t { void (*user_print)(Monitor *mon, const QObject *data); union { void (*info)(Monitor *mon); -void (*info_new)(Monitor *mon, QObject **ret_data); -int (*info_async)(Monitor *mon, MonitorCompletion *cb, void *opaque); void (*cmd)(Monitor *mon, const QDict *qdict); int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data); int (*cmd_async)(Monitor *mon, const QDict *params, @@ -679,21 +677,6 @@ static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd, } } -static void user_async_info_handler(Monitor *mon, const mon_cmd_t *cmd) -{ -int ret; - -MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data)); -cb_data-mon = mon; -cb_data-user_print = cmd-user_print; -monitor_suspend(mon); -ret = cmd-mhandler.info_async(mon, user_monitor_complete, cb_data); -if (ret 0) { -monitor_resume(mon); -g_free(cb_data); -} -} - static void do_info(Monitor *mon, const QDict *qdict) { const mon_cmd_t *cmd; @@ -712,20 +695,7 @@ static void do_info(Monitor *mon, const QDict *qdict) goto help; } -if (handler_is_async(cmd)) { -user_async_info_handler(mon, cmd); -} else if (handler_is_qobject(cmd)) { -QObject *info_data = NULL; - -cmd-mhandler.info_new(mon, info_data); -if (info_data) { -cmd-user_print(mon, info_data); -qobject_decref(info_data); -} -} else { -cmd-mhandler.info(mon); -} - +cmd-mhandler.info(mon); return; help: -- 1.7.7.1.431.g10b2a
Re: [Qemu-devel] [PATCH] This patch adds a new block driver : iSCSI
Am 21.09.2011 11:37, schrieb Ronnie Sahlberg: This provides built-in support for iSCSI to QEMU. This has the advantage that the iSCSI devices need not be made visible to the host, which is useful if you have very many virtual machines and very many iscsi devices. It also has the benefit that non-root users of QEMU can access iSCSI devices across the network without requiring root privilege on the host. This driver interfaces with the multiplatform posix library for iscsi initiator/client access to iscsi devices hosted at git://github.com/sahlberg/libiscsi.git The patch adds the driver to interface with the iscsi library. It also updated the configure script to * by default, probe is libiscsi is available and if so, build qemu against libiscsi. * --enable-libiscsi Force a build against libiscsi. If libiscsi is not available the build will fail. * --disable-libiscsi Do not link against libiscsi, even if it is available. When linked with libiscsi, qemu gains support to access iscsi resources such as disks and cdrom directly, without having to make the devices visible to the host. You can specify devices using a iscsi url of the form : iscsi://[username[:password@]]host[:port]/target-iqn-name/lun When using authentication, the password can optionally be set with LIBISCSI_CHAP_PASSWORD=password to avoid it showing up in the process list Signed-off-by: Ronnie Sahlberg ronniesahlb...@gmail.com I have a few comments, but none of them are really critical and in general the patch looks good to me. So please let me know if you intend to send another version with the comments addressed or if I should commit this version and you'll send fixes/cleanups on top. I don't really mind at this point. --- Makefile.objs |1 + block/iscsi.c | 596 + configure | 31 +++ trace-events |7 + 4 files changed, 635 insertions(+), 0 deletions(-) create mode 100644 block/iscsi.c diff --git a/Makefile.objs b/Makefile.objs index a529a11..8c8e420 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -36,6 +36,7 @@ block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o block-nested-$(CONFIG_WIN32) += raw-win32.o block-nested-$(CONFIG_POSIX) += raw-posix.o +block-nested-$(CONFIG_LIBISCSI) += iscsi.o block-nested-$(CONFIG_CURL) += curl.o block-nested-$(CONFIG_RBD) += rbd.o diff --git a/block/iscsi.c b/block/iscsi.c new file mode 100644 index 000..6517576 --- /dev/null +++ b/block/iscsi.c @@ -0,0 +1,596 @@ +/* + * QEMU Block driver for iSCSI images + * + * Copyright (c) 2010-2011 Ronnie Sahlberg ronniesahlb...@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include config-host.h + +#include poll.h +#include sysemu.h I doubt that you really need sysemu.h. If you did, I think you couldn't successfully build qemu-img and qemu-io. +#include qemu-common.h +#include qemu-error.h +#include block_int.h +#include trace.h + +#include iscsi/iscsi.h +#include iscsi/scsi-lowlevel.h + + +typedef struct IscsiLun { +struct iscsi_context *iscsi; +int lun; +int block_size; +unsigned long num_blocks; +} IscsiLun; + +typedef struct IscsiAIOCB { +BlockDriverAIOCB common; +QEMUIOVector *qiov; +QEMUBH *bh; +IscsiLun *iscsilun; +struct scsi_task *task; +uint8_t *buf; +int canceled; +int status; +size_t read_size; +size_t read_offset; +} IscsiAIOCB; + +struct IscsiTask { +IscsiLun *iscsilun; +int status; +int complete; +}; + +static void +iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data, +void *private_data) +{ +} + +static void +iscsi_aio_cancel(BlockDriverAIOCB *blockacb) +{ +IscsiAIOCB *acb = (IscsiAIOCB
[Qemu-devel] [PATCH 07/19] qapi: Convert query-cpus
Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- cpus.c | 45 hmp.c| 39 + hmp.h|1 + monitor.c| 101 +- qapi-schema.json | 46 qmp-commands.hx |6 +++ 6 files changed, 138 insertions(+), 100 deletions(-) diff --git a/cpus.c b/cpus.c index 5f5b763..b03de67 100644 --- a/cpus.c +++ b/cpus.c @@ -30,6 +30,7 @@ #include gdbstub.h #include dma.h #include kvm.h +#include qmp-commands.h #include qemu-thread.h #include cpus.h @@ -1031,3 +1032,47 @@ void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg) cpu_list(f, cpu_fprintf); /* deprecated */ #endif } + +CpuInfoList *qmp_query_cpus(Error **errp) +{ +CpuInfoList *head = NULL, *cur_item = NULL; +CPUState *env; + +for(env = first_cpu; env != NULL; env = env-next_cpu) { +CpuInfoList *info; + +cpu_synchronize_state(env); + +info = g_malloc0(sizeof(*info)); +info-value = g_malloc0(sizeof(*info-value)); +info-value-CPU = env-cpu_index; +info-value-current = (env == first_cpu); +info-value-halted = env-halted; +info-value-thread_id = env-thread_id; +#if defined(TARGET_I386) +info-value-has_pc = true; +info-value-pc = env-eip + env-segs[R_CS].base; +#elif defined(TARGET_PPC) +info-value-has_nip = true; +info-value-nip = env-nip; +#elif defined(TARGET_SPARC) +info-value-has_pc = true; +info-value-pc = env-pc; +info-value-has_npc = true; +info-value-npc = env-npc; +#elif defined(TARGET_MIPS) +info-value-has_PC = true; +info-value-PC = env-active_tc.PC; +#endif + +/* XXX: waiting for the qapi to support GSList */ +if (!cur_item) { +head = cur_item = info; +} else { +cur_item-next = info; +cur_item = info; +} +} + +return head; +} diff --git a/hmp.c b/hmp.c index 35b0ca0..172fe9c 100644 --- a/hmp.c +++ b/hmp.c @@ -145,6 +145,45 @@ void hmp_info_migrate(Monitor *mon) qapi_free_MigrationInfo(info); } +void hmp_info_cpus(Monitor *mon) +{ +CpuInfoList *cpu_list, *cpu; + +cpu_list = qmp_query_cpus(NULL); + +for (cpu = cpu_list; cpu; cpu = cpu-next) { +int active = ' '; + +if (cpu-value-CPU == monitor_get_cpu_index()) { +active = '*'; +} + +monitor_printf(mon, %c CPU #% PRId64 : , active, cpu-value-CPU); + +if (cpu-value-has_pc) { +monitor_printf(mon, pc=0x%016 PRIx64, cpu-value-pc); +} +if (cpu-value-has_nip) { +monitor_printf(mon, nip=0x%016 PRIx64, cpu-value-nip); +} +if (cpu-value-has_npc) { +monitor_printf(mon, pc=0x%016 PRIx64, cpu-value-pc); +monitor_printf(mon, npc=0x%016 PRIx64, cpu-value-npc); +} +if (cpu-value-has_PC) { +monitor_printf(mon, PC=0x%016 PRIx64, cpu-value-PC); +} + +if (cpu-value-halted) { +monitor_printf(mon, (halted)); +} + +monitor_printf(mon, thread_id=% PRId64 \n, cpu-value-thread_id); +} + +qapi_free_CpuInfoList(cpu_list); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index 9322b7f..d9a83eb 100644 --- a/hmp.h +++ b/hmp.h @@ -25,6 +25,7 @@ void hmp_info_uuid(Monitor *mon); void hmp_info_chardev(Monitor *mon); void hmp_info_mice(Monitor *mon); void hmp_info_migrate(Monitor *mon); +void hmp_info_cpus(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/monitor.c b/monitor.c index 1edb646..2f49c74 100644 --- a/monitor.c +++ b/monitor.c @@ -812,96 +812,6 @@ static void do_info_registers(Monitor *mon) #endif } -static void print_cpu_iter(QObject *obj, void *opaque) -{ -QDict *cpu; -int active = ' '; -Monitor *mon = opaque; - -assert(qobject_type(obj) == QTYPE_QDICT); -cpu = qobject_to_qdict(obj); - -if (qdict_get_bool(cpu, current)) { -active = '*'; -} - -monitor_printf(mon, %c CPU #%d: , active, (int)qdict_get_int(cpu, CPU)); - -#if defined(TARGET_I386) -monitor_printf(mon, pc=0x TARGET_FMT_lx, - (target_ulong) qdict_get_int(cpu, pc)); -#elif defined(TARGET_PPC) -monitor_printf(mon, nip=0x TARGET_FMT_lx, - (target_long) qdict_get_int(cpu, nip)); -#elif defined(TARGET_SPARC) -monitor_printf(mon, pc=0x TARGET_FMT_lx, - (target_long) qdict_get_int(cpu, pc)); -monitor_printf(mon, npc=0x TARGET_FMT_lx, - (target_long) qdict_get_int(cpu, npc)); -#elif defined(TARGET_MIPS) -monitor_printf(mon, PC=0x
[Qemu-devel] [PATCH 09/19] block: Rename the BlockIOStatus enum values
The biggest change is to rename its prefix from BDRV_IOS to BLOCK_DEVICE_IO_STATUS. Next commit will convert the query-block command to the QAPI and that's how the enumeration is going to be generated. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- block.c | 18 ++ block.h |3 ++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/block.c b/block.c index 04f4143..443014e 100644 --- a/block.c +++ b/block.c @@ -1921,10 +1921,10 @@ void bdrv_info_print(Monitor *mon, const QObject *data) qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); } -static const char *const io_status_name[BDRV_IOS_MAX] = { -[BDRV_IOS_OK] = ok, -[BDRV_IOS_FAILED] = failed, -[BDRV_IOS_ENOSPC] = nospace, +static const char *const io_status_name[BLOCK_DEVICE_IO_STATUS_MAX] = { +[BLOCK_DEVICE_IO_STATUS_OK] = ok, +[BLOCK_DEVICE_IO_STATUS_FAILED] = failed, +[BLOCK_DEVICE_IO_STATUS_NOSPACE] = nospace, }; void bdrv_info(Monitor *mon, QObject **ret_data) @@ -3080,7 +3080,7 @@ int bdrv_in_use(BlockDriverState *bs) void bdrv_iostatus_enable(BlockDriverState *bs) { bs-iostatus_enabled = true; -bs-iostatus = BDRV_IOS_OK; +bs-iostatus = BLOCK_DEVICE_IO_STATUS_OK; } /* The I/O status is only enabled if the drive explicitly @@ -3101,7 +3101,7 @@ void bdrv_iostatus_disable(BlockDriverState *bs) void bdrv_iostatus_reset(BlockDriverState *bs) { if (bdrv_iostatus_is_enabled(bs)) { -bs-iostatus = BDRV_IOS_OK; +bs-iostatus = BLOCK_DEVICE_IO_STATUS_OK; } } @@ -3110,9 +3110,11 @@ void bdrv_iostatus_reset(BlockDriverState *bs) possible to implement this without device models being involved */ void bdrv_iostatus_set_err(BlockDriverState *bs, int error) { -if (bdrv_iostatus_is_enabled(bs) bs-iostatus == BDRV_IOS_OK) { +if (bdrv_iostatus_is_enabled(bs) +bs-iostatus == BLOCK_DEVICE_IO_STATUS_OK) { assert(error = 0); -bs-iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED; +bs-iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : + BLOCK_DEVICE_IO_STATUS_FAILED; } } diff --git a/block.h b/block.h index 9c77604..f655686 100644 --- a/block.h +++ b/block.h @@ -78,7 +78,8 @@ typedef enum { } BlockMonEventAction; typedef enum { -BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, BDRV_IOS_MAX +BLOCK_DEVICE_IO_STATUS_OK, BLOCK_DEVICE_IO_STATUS_FAILED, +BLOCK_DEVICE_IO_STATUS_NOSPACE, BLOCK_DEVICE_IO_STATUS_MAX } BlockIOStatus; void bdrv_iostatus_enable(BlockDriverState *bs); -- 1.7.7.1.431.g10b2a
Re: [Qemu-devel] [PATCH v2 2/4] Add access control support to qemu bridge helper
On 10/23/2011 09:10 AM, Blue Swirl wrote: On Fri, Oct 21, 2011 at 15:07, Corey Bryantcor...@linux.vnet.ibm.com wrote: We go to great lengths to restrict ourselves to just cap_net_admin as an OS enforced security mechanism. However, we further restrict what we allow users to do to simply adding a tap device to a bridge interface by virtue of the fact that this is the only functionality we expose. This is not good enough though. An administrator is likely to want to restrict the bridges that an unprivileged user can access, in particular, to restrict an unprivileged user from putting a guest on what should be isolated networks. This patch implements an ACL mechanism that is enforced by qemu-bridge-helper. The ACLs are fairly simple whitelist/blacklist mechanisms with a wildcard of 'all'. All users are blacklisted by default, and deny takes precedence over allow. An interesting feature of this ACL mechanism is that you can include external ACL files. The main reason to support this is so that you can set different file system permissions on those external ACL files. This allows an administrator to implement rather sophisicated ACL policies based on user/group sophisticated Yep, thanks. policies via the file system. As an example: /etc/qemu/bridge.conf root:qemu 0640 allow br0 include /etc/qemu/alice.conf include /etc/qemu/bob.conf include /etc/qemu/charlie.conf /etc/qemu/alice.conf root:alice 0640 allow br1 /etc/qemu/bob.conf root:bob 0640 allow br2 /etc/qemu/charlie.conf root:charlie 0640 deny all I think syntax 'include/etc/qemu/user.d/*.conf' or 'includedir /etc/qemu/user.d' could be also useful. That could be useful, though I'm not sure it's necessary right now. This ACL pattern allows any user in the qemu group to get a tap device connected to br0 (which is bridged to the physical network). Users in the alice group can additionally get a tap device connected to br1. This allows br1 to act as a private bridge for the alice group. Users in the bob group can additionally get a tap device connected to br2. This allows br2 to act as a private bridge for the bob group. Users in the charlie group cannot get a tap device connected to any bridge. Under no circumstance can the bob group get access to br1 or can the alice group get access to br2. And under no cicumstance can the charlie group get access to any bridge. Signed-off-by: Anthony Liguorialigu...@us.ibm.com Signed-off-by: Richa Marwaharmar...@linux.vnet.ibm.com Signed-off-by: Corey Bryantcor...@linux.vnet.ibm.com --- qemu-bridge-helper.c | 141 ++ 1 files changed, 141 insertions(+), 0 deletions(-) diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c index 2ce82fb..db257d5 100644 --- a/qemu-bridge-helper.c +++ b/qemu-bridge-helper.c @@ -33,6 +33,105 @@ #include net/tap-linux.h +#define MAX_ACLS (128) If all users (or groups) in the system have an ACL, this number could be way too low. Please use a list instead. I agree, we shouldn't be hard-coding the limit here. I'll update this. +#define DEFAULT_ACL_FILE CONFIG_QEMU_CONFDIR /bridge.conf + +enum { +ACL_ALLOW = 0, +ACL_ALLOW_ALL, +ACL_DENY, +ACL_DENY_ALL, +}; + +typedef struct ACLRule { +int type; +char iface[IFNAMSIZ]; +} ACLRule; + +static int parse_acl_file(const char *filename, ACLRule *acls, int *pacl_count) +{ +int acl_count = *pacl_count; +FILE *f; +char line[4096]; + +f = fopen(filename, r); +if (f == NULL) { +return -1; +} + +while (acl_count != MAX_ACLS +fgets(line, sizeof(line), f) != NULL) { +char *ptr = line; +char *cmd, *arg, *argend; + +while (isspace(*ptr)) { +ptr++; +} + +/* skip comments and empty lines */ +if (*ptr == '#' || *ptr == 0) { +continue; +} + +cmd = ptr; +arg = strchr(cmd, ' '); +if (arg == NULL) { +arg = strchr(cmd, '\t'); +} + +if (arg == NULL) { +fprintf(stderr, Invalid config line:\n %s\n, line); +fclose(f); +errno = EINVAL; +return -1; +} + +*arg = 0; +arg++; +while (isspace(*arg)) { +arg++; +} + +argend = arg + strlen(arg); +while (arg != argend isspace(*(argend - 1))) { +argend--; +} These while loops to skip spaces are repeated, but the comment skipping part is not, so it is not possible to have comments after rules or split rules to several lines. I'd add a simple state variable to track at which stage we are in parsing instead. That could be useful too, but again not sure it's
[Qemu-devel] [PATCH 10/19] qapi: Convert query-block
Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- block.c | 112 ++--- block.h |5 -- block_int.h |3 +- hmp.c| 42 hmp.h|1 + monitor.c| 11 +- qapi-schema.json | 85 + qmp-commands.hx |6 +++ 8 files changed, 167 insertions(+), 98 deletions(-) diff --git a/block.c b/block.c index 443014e..af0ea5e 100644 --- a/block.c +++ b/block.c @@ -29,6 +29,7 @@ #include module.h #include qemu-objects.h #include qemu-coroutine.h +#include qmp-commands.h #ifdef CONFIG_BSD #include sys/types.h @@ -1875,106 +1876,53 @@ void bdrv_mon_event(const BlockDriverState *bdrv, qobject_decref(data); } -static void bdrv_print_dict(QObject *obj, void *opaque) +BlockInfoList *qmp_query_block(Error **errp) { -QDict *bs_dict; -Monitor *mon = opaque; - -bs_dict = qobject_to_qdict(obj); - -monitor_printf(mon, %s: removable=%d, -qdict_get_str(bs_dict, device), -qdict_get_bool(bs_dict, removable)); - -if (qdict_get_bool(bs_dict, removable)) { -monitor_printf(mon, locked=%d, qdict_get_bool(bs_dict, locked)); -monitor_printf(mon, tray-open=%d, - qdict_get_bool(bs_dict, tray-open)); -} - -if (qdict_haskey(bs_dict, io-status)) { -monitor_printf(mon, io-status=%s, qdict_get_str(bs_dict, io-status)); -} - -if (qdict_haskey(bs_dict, inserted)) { -QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, inserted)); - -monitor_printf(mon, file=); -monitor_print_filename(mon, qdict_get_str(qdict, file)); -if (qdict_haskey(qdict, backing_file)) { -monitor_printf(mon, backing_file=); -monitor_print_filename(mon, qdict_get_str(qdict, backing_file)); -} -monitor_printf(mon, ro=%d drv=%s encrypted=%d, -qdict_get_bool(qdict, ro), -qdict_get_str(qdict, drv), -qdict_get_bool(qdict, encrypted)); -} else { -monitor_printf(mon, [not inserted]); -} - -monitor_printf(mon, \n); -} - -void bdrv_info_print(Monitor *mon, const QObject *data) -{ -qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); -} - -static const char *const io_status_name[BLOCK_DEVICE_IO_STATUS_MAX] = { -[BLOCK_DEVICE_IO_STATUS_OK] = ok, -[BLOCK_DEVICE_IO_STATUS_FAILED] = failed, -[BLOCK_DEVICE_IO_STATUS_NOSPACE] = nospace, -}; - -void bdrv_info(Monitor *mon, QObject **ret_data) -{ -QList *bs_list; +BlockInfoList *head = NULL, *cur_item = NULL; BlockDriverState *bs; -bs_list = qlist_new(); - QTAILQ_FOREACH(bs, bdrv_states, list) { -QObject *bs_obj; -QDict *bs_dict; +BlockInfoList *info = g_malloc0(sizeof(*info)); -bs_obj = qobject_from_jsonf({ 'device': %s, 'type': 'unknown', -'removable': %i, 'locked': %i }, -bs-device_name, -bdrv_dev_has_removable_media(bs), -bdrv_dev_is_medium_locked(bs)); -bs_dict = qobject_to_qdict(bs_obj); +info-value = g_malloc0(sizeof(*info-value)); +info-value-device = g_strdup(bs-device_name); +info-value-type = g_strdup(unknown); +info-value-locked = bdrv_dev_is_medium_locked(bs); +info-value-removable = bdrv_dev_has_removable_media(bs); if (bdrv_dev_has_removable_media(bs)) { -qdict_put(bs_dict, tray-open, - qbool_from_int(bdrv_dev_is_tray_open(bs))); +info-value-has_tray_open = true; +info-value-tray_open = bdrv_dev_is_tray_open(bs); } if (bdrv_iostatus_is_enabled(bs)) { -qdict_put(bs_dict, io-status, - qstring_from_str(io_status_name[bs-iostatus])); +info-value-has_io_status = true; +info-value-io_status = bs-iostatus; } if (bs-drv) { -QObject *obj; - -obj = qobject_from_jsonf({ 'file': %s, 'ro': %i, 'drv': %s, - 'encrypted': %i }, - bs-filename, bs-read_only, - bs-drv-format_name, - bdrv_is_encrypted(bs)); -if (bs-backing_file[0] != '\0') { -QDict *qdict = qobject_to_qdict(obj); -qdict_put(qdict, backing_file, - qstring_from_str(bs-backing_file)); +info-value-has_inserted = true; +info-value-inserted = g_malloc0(sizeof(*info-value-inserted)); +info-value-inserted-file = g_strdup(bs-filename); +
Re: [Qemu-devel] [PATCH V2 01/10] configure: Introduce --enable-xen-pci-passthrough.
On Thu, Oct 20, 2011 at 11:57, Stefano Stabellini stefano.stabell...@eu.citrix.com wrote: diff --git a/Makefile.target b/Makefile.target index 417f23e..c518103 100644 --- a/Makefile.target +++ b/Makefile.target @@ -208,6 +208,8 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o obj-i386-$(CONFIG_XEN) += xen_platform.o +# Xen PCI Passthrough + why? To reserve a space for futur addition. So on the next patch, I'll just add the object to compile and not this comment. And why not ? -- Anthony PERARD
[Qemu-devel] [PATCH 12/19] qerror: Add a user string for QERR_FEATURE_DISABLED
Missing from commit 821601ea5b. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- qerror.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/qerror.c b/qerror.c index 68998d4..4b48b39 100644 --- a/qerror.c +++ b/qerror.c @@ -117,6 +117,10 @@ static const QErrorStringTable qerror_table[] = { .desc = No file descriptor supplied via SCM_RIGHTS, }, { +.error_fmt = QERR_FEATURE_DISABLED, +.desc = The feature '%(name)' is not enabled, +}, +{ .error_fmt = QERR_INVALID_BLOCK_FORMAT, .desc = Invalid block format '%(name)', }, -- 1.7.7.1.431.g10b2a
[Qemu-devel] [PATCH 08/19] block: iostatus: Drop BDRV_IOS_INVAL
A future commit will convert bdrv_info() to the QAPI and it won't provide IOS_INVAL. Luckily all we have to do is to add a new 'iostatus_enabled' member to BlockDriverState and use it instead. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- block.c |5 +++-- block.h |3 +-- block_int.h |1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/block.c b/block.c index 9873b57..04f4143 100644 --- a/block.c +++ b/block.c @@ -3079,6 +3079,7 @@ int bdrv_in_use(BlockDriverState *bs) void bdrv_iostatus_enable(BlockDriverState *bs) { +bs-iostatus_enabled = true; bs-iostatus = BDRV_IOS_OK; } @@ -3086,7 +3087,7 @@ void bdrv_iostatus_enable(BlockDriverState *bs) * enables it _and_ the VM is configured to stop on errors */ bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) { -return (bs-iostatus != BDRV_IOS_INVAL +return (bs-iostatus_enabled (bs-on_write_error == BLOCK_ERR_STOP_ENOSPC || bs-on_write_error == BLOCK_ERR_STOP_ANY|| bs-on_read_error == BLOCK_ERR_STOP_ANY)); @@ -3094,7 +3095,7 @@ bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) void bdrv_iostatus_disable(BlockDriverState *bs) { -bs-iostatus = BDRV_IOS_INVAL; +bs-iostatus_enabled = false; } void bdrv_iostatus_reset(BlockDriverState *bs) diff --git a/block.h b/block.h index e77988e..9c77604 100644 --- a/block.h +++ b/block.h @@ -78,8 +78,7 @@ typedef enum { } BlockMonEventAction; typedef enum { -BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, -BDRV_IOS_MAX +BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC, BDRV_IOS_MAX } BlockIOStatus; void bdrv_iostatus_enable(BlockDriverState *bs); diff --git a/block_int.h b/block_int.h index f2f4f2d..7ce2150 100644 --- a/block_int.h +++ b/block_int.h @@ -199,6 +199,7 @@ struct BlockDriverState { drivers. They are not used by the block driver */ int cyls, heads, secs, translation; BlockErrorAction on_read_error, on_write_error; +bool iostatus_enabled; BlockIOStatus iostatus; char device_name[32]; unsigned long *dirty_bitmap; -- 1.7.7.1.431.g10b2a
[Qemu-devel] [PATCH 01/19] qapi-commands.py: Don't call the output marshal on error
Today we generate something like this: int qmp_marshal_input_query_foo(...) ... retval = qmp_query_foo(errp); qmp_marshal_output_query_foo(retval, ret, errp); ... However, if qmp_query_foo() fails 'retval' will probably be NULL, which can cause a segfault as not all visitors check if 'retval' is valid. This commit fixes that by changing the code generator to only call the output marshal if qmp_query_foo() succeeds, like this: retval = qmp_query_foo(errp); if (!error_is_set(errp)) { qmp_marshal_output_query_foo(retval, ret, errp); } Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- scripts/qapi-commands.py |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index c947ba4..f7def16 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -62,7 +62,9 @@ def gen_sync_call(name, args, ret_type, indent=0): name=c_var(name), args=arglist, retval=retval).rstrip() if ret_type: ret += \n + mcgen( -%(marshal_output_call)s +if (!error_is_set(errp)) { +%(marshal_output_call)s +} ''', marshal_output_call=gen_marshal_output_call(name, ret_type)).rstrip() pop_indent(indent) -- 1.7.7.1.431.g10b2a
Re: [Qemu-devel] [PATCH] Add Qemu A15 minimal support for ARM KVM
On 29 September 2011 08:30, bill4car...@gmail.com wrote: From: Bill Carson bill4car...@gmail.com This patch add some A15 codes which enables ARM KVM could run Guest OS build with Versatile Express Cortex-A15x4 tile. Thanks for sending this; I have somewhat belatedly written up some comments on it. I see the a15mpcore.c code is based on a version of mpcore.c which predates the MemoryRegion API changes -- we'll need to update it to use MemoryRegions. There are some relics of 11MPCore peripherals lurking in there which need to be taken out. (I think we should probably clean up mpcore.c to separate out A9 from 11MPCore, incidentally.) The vexpress A9 and A15 init functions can probably share code although I haven't looked too closely there. For QEMU TCG we're going to want to model at least some of the cp15 registers (although probably mostly dummy implementations). The A15 generic timer is accessed via cp15 registers rather than being memory mapped -- we need to decide which side of the KVM/QEMU boundary the model of that should live. (I'm guessing the right answer is qemu side which means we'll need an ABI between KVM and QEMU to pass (some) cp15 accesses through.) thanks again -- PMM
[Qemu-devel] [PATCH 17/19] QMP: Drop the query commands dispatch table
Because QMP development originated in the monitor, it has inherited the monitor's distinction between query- and non-query commands. However, previous commits unified both commands and the distinction is gone. This commit drops the query commands dispatch table and does some simplifications along the way. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- monitor.c | 63 1 files changed, 5 insertions(+), 58 deletions(-) diff --git a/monitor.c b/monitor.c index edcacda..1e09b91 100644 --- a/monitor.c +++ b/monitor.c @@ -205,7 +205,6 @@ static const mon_cmd_t mon_cmds[]; static const mon_cmd_t info_cmds[]; static const mon_cmd_t qmp_cmds[]; -static const mon_cmd_t qmp_query_cmds[]; Monitor *cur_mon; Monitor *default_mon; @@ -663,11 +662,6 @@ static int qmp_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd, return cmd-mhandler.cmd_async(mon, params, qmp_monitor_complete, mon); } -static void qmp_async_info_handler(Monitor *mon, const mon_cmd_t *cmd) -{ -cmd-mhandler.info_async(mon, qmp_monitor_complete, mon); -} - static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd, const QDict *params) { @@ -738,32 +732,16 @@ help: help_cmd(mon, info); } -static CommandInfoList *alloc_cmd_entry(const char *cmd_name) -{ -CommandInfoList *info; - -info = g_malloc0(sizeof(*info)); -info-value = g_malloc0(sizeof(*info-value)); -info-value-name = g_strdup(cmd_name); - -return info; -} - CommandInfoList *qmp_query_commands(Error **errp) { CommandInfoList *info, *cmd_list = NULL; const mon_cmd_t *cmd; for (cmd = qmp_cmds; cmd-name != NULL; cmd++) { -info = alloc_cmd_entry(cmd-name); -info-next = cmd_list; -cmd_list = info; -} +info = g_malloc0(sizeof(*info)); +info-value = g_malloc0(sizeof(*info-value)); +info-value-name = g_strdup(cmd-name); -for (cmd = qmp_query_cmds; cmd-name != NULL; cmd++) { -char buf[128]; -snprintf(buf, sizeof(buf), query-%s, cmd-name); -info = alloc_cmd_entry(buf); info-next = cmd_list; cmd_list = info; } @@ -2952,10 +2930,6 @@ static const mon_cmd_t qmp_cmds[] = { { /* NULL */ }, }; -static const mon_cmd_t qmp_query_cmds[] = { -{ /* NULL */ }, -}; - /***/ static const char *pch; @@ -3750,11 +3724,6 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname) return search_dispatch_table(mon_cmds, cmdname); } -static const mon_cmd_t *qmp_find_query_cmd(const char *info_item) -{ -return search_dispatch_table(qmp_query_cmds, info_item); -} - static const mon_cmd_t *qmp_find_cmd(const char *cmdname) { return search_dispatch_table(qmp_cmds, cmdname); @@ -4678,22 +4647,6 @@ static QDict *qmp_check_input_obj(QObject *input_obj) return input_dict; } -static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd) -{ -QObject *ret_data = NULL; - -if (handler_is_async(cmd)) { -qmp_async_info_handler(mon, cmd); -if (monitor_has_error(mon)) { -monitor_protocol_emitter(mon, NULL); -} -} else { -cmd-mhandler.info_new(mon, ret_data); -monitor_protocol_emitter(mon, ret_data); -qobject_decref(ret_data); -} -} - static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd, const QDict *params) { @@ -4714,10 +4667,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) QObject *obj; QDict *input, *args; const mon_cmd_t *cmd; +const char *cmd_name; Monitor *mon = cur_mon; -const char *cmd_name, *query_cmd; -query_cmd = NULL; args = input = NULL; obj = json_parser_parse(tokens, NULL); @@ -4744,9 +4696,6 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) } cmd = qmp_find_cmd(cmd_name); -if (!cmd strstart(cmd_name, query-, query_cmd)) { -cmd = qmp_find_query_cmd(query_cmd); -} if (!cmd) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_out; @@ -4765,9 +4714,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } -if (query_cmd) { -qmp_call_query_cmd(mon, cmd); -} else if (handler_is_async(cmd)) { +if (handler_is_async(cmd)) { err = qmp_async_cmd_handler(mon, cmd, args); if (err) { /* emit the error response */ -- 1.7.7.1.431.g10b2a
[Qemu-devel] [PATCH 03/19] qapi: Convert query-migrate
Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- hmp.c| 31 hmp.h|1 + migration.c | 82 +++-- monitor.c| 11 +-- qapi-schema.json | 50 + qmp-commands.hx |6 6 files changed, 112 insertions(+), 69 deletions(-) diff --git a/hmp.c b/hmp.c index 9c6d896..619b8ba 100644 --- a/hmp.c +++ b/hmp.c @@ -114,6 +114,37 @@ void hmp_info_mice(Monitor *mon) qapi_free_MouseInfoList(mice_list); } +void hmp_info_migrate(Monitor *mon) +{ +MigrationInfo *info; + +info = qmp_query_migrate(NULL); + +if (info-has_status) { +monitor_printf(mon, Migration status: %s\n, info-status); +} + +if (info-has_ram) { +monitor_printf(mon, transferred ram: % PRIu64 kbytes\n, + info-ram-transferred 10); +monitor_printf(mon, remaining ram: % PRIu64 kbytes\n, + info-ram-remaining 10); +monitor_printf(mon, total ram: % PRIu64 kbytes\n, + info-ram-total 10); +} + +if (info-has_disk) { +monitor_printf(mon, transferred disk: % PRIu64 kbytes\n, + info-disk-transferred 10); +monitor_printf(mon, remaining disk: % PRIu64 kbytes\n, + info-disk-remaining 10); +monitor_printf(mon, total disk: % PRIu64 kbytes\n, + info-disk-total 10); +} + +qapi_free_MigrationInfo(info); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index 4e6697d..49d9662 100644 --- a/hmp.h +++ b/hmp.h @@ -24,6 +24,7 @@ void hmp_info_status(Monitor *mon); void hmp_info_uuid(Monitor *mon); void hmp_info_chardev(Monitor *mon); void hmp_info_mice(Monitor *mon); +void hmp_info_migrate(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/migration.c b/migration.c index bdca72e..6c70f72 100644 --- a/migration.c +++ b/migration.c @@ -19,7 +19,7 @@ #include block.h #include qemu_socket.h #include block-migration.h -#include qemu-objects.h +#include qmp-commands.h //#define DEBUG_MIGRATION @@ -107,53 +107,9 @@ uint64_t migrate_max_downtime(void) return max_downtime; } -static void migrate_print_status(Monitor *mon, const char *name, - const QDict *status_dict) +MigrationInfo *qmp_query_migrate(Error **errp) { -QDict *qdict; - -qdict = qobject_to_qdict(qdict_get(status_dict, name)); - -monitor_printf(mon, transferred %s: % PRIu64 kbytes\n, name, -qdict_get_int(qdict, transferred) 10); -monitor_printf(mon, remaining %s: % PRIu64 kbytes\n, name, -qdict_get_int(qdict, remaining) 10); -monitor_printf(mon, total %s: % PRIu64 kbytes\n, name, -qdict_get_int(qdict, total) 10); -} - -void do_info_migrate_print(Monitor *mon, const QObject *data) -{ -QDict *qdict; - -qdict = qobject_to_qdict(data); - -monitor_printf(mon, Migration status: %s\n, - qdict_get_str(qdict, status)); - -if (qdict_haskey(qdict, ram)) { -migrate_print_status(mon, ram, qdict); -} - -if (qdict_haskey(qdict, disk)) { -migrate_print_status(mon, disk, qdict); -} -} - -static void migrate_put_status(QDict *qdict, const char *name, - uint64_t trans, uint64_t rem, uint64_t total) -{ -QObject *obj; - -obj = qobject_from_jsonf({ 'transferred': % PRId64 , - 'remaining': % PRId64 , - 'total': % PRId64 }, trans, rem, total); -qdict_put_obj(qdict, name, obj); -} - -void do_info_migrate(Monitor *mon, QObject **ret_data) -{ -QDict *qdict; +MigrationInfo *info = g_malloc0(sizeof(*info)); MigrationState *s = migrate_get_current(); switch (s-state) { @@ -161,30 +117,38 @@ void do_info_migrate(Monitor *mon, QObject **ret_data) /* no migration has happened ever */ break; case MIG_STATE_ACTIVE: -qdict = qdict_new(); -qdict_put(qdict, status, qstring_from_str(active)); +info-has_status = true; +info-status = g_strdup(active); -migrate_put_status(qdict, ram, ram_bytes_transferred(), - ram_bytes_remaining(), ram_bytes_total()); +info-has_ram = true; +info-ram = g_malloc0(sizeof(*info-ram)); +info-ram-transferred = ram_bytes_transferred(); +info-ram-remaining = ram_bytes_remaining(); +info-ram-total = ram_bytes_total(); if (blk_mig_active()) { -migrate_put_status(qdict, disk, blk_mig_bytes_transferred(), -
Re: [Qemu-devel] [PATCH v2 3/4] Add cap reduction support to enable use as SUID
On 10/23/2011 09:22 AM, Blue Swirl wrote: On Fri, Oct 21, 2011 at 15:07, Corey Bryantcor...@linux.vnet.ibm.com wrote: The ideal way to use qemu-bridge-helper is to give it an fscap of using: setcap cap_net_admin=ep qemu-bridge-helper Unfortunately, most distros still do not have a mechanism to package files with fscaps applied. This means they'll have to SUID the qemu-bridge-helper binary. To improve security, use libcap to reduce our capability set to just cap_net_admin, then reduce privileges down to the calling user. This is hopefully close to equivalent to fscap support from a security perspective. Signed-off-by: Anthony Liguorialigu...@us.ibm.com Signed-off-by: Richa Marwaharmar...@linux.vnet.ibm.com Signed-off-by: Corey Bryantcor...@linux.vnet.ibm.com --- configure| 34 ++ qemu-bridge-helper.c | 39 +++ 2 files changed, 73 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 6c8b659..fed66b0 100755 --- a/configure +++ b/configure @@ -128,6 +128,7 @@ vnc_thread=no xen= xen_ctrl_version= linux_aio= +cap= attr= xfs= @@ -653,6 +654,10 @@ for opt do ;; --enable-kvm) kvm=yes ;; + --disable-cap) cap=no + ;; + --enable-cap) cap=yes + ;; --disable-spice) spice=no ;; --enable-spice) spice=yes @@ -1032,6 +1037,8 @@ echo --disable-vdedisable support for vde network echo --enable-vde enable support for vde network echo --disable-linux-aio disable Linux AIO support echo --enable-linux-aio enable Linux AIO support +echo --disable-capdisable libcap-ng support +echo --enable-cap enable libcap-ng support echo --disable-attr disables attr and xattr support echo --enable-attrenable attr and xattr support echo --disable-blobs disable installing provided firmware blobs @@ -1638,6 +1645,29 @@ EOF fi ## +# libcap-ng library probe +if test $cap != no ; then + cap_libs=-lcap-ng + cat $TMPC EOF +#includecap-ng.h +int main(void) +{ +capng_capability_to_name(CAPNG_EFFECTIVE); +return 0; +} +EOF + if compile_prog $cap_libs ; then +cap=yes +libs_tools=$cap_libs $libs_tools + else +if test $cap = yes ; then + feature_not_found cap +fi +cap=no + fi +fi + +## # Sound support libraries probe audio_drv_probe() @@ -2735,6 +2765,7 @@ echo fdatasync $fdatasync echo madvise $madvise echo posix_madvise $posix_madvise echo uuid support $uuid +echo libcap-ng support $cap echo vhost-net support $vhost_net echo Trace backend $trace_backend echo Trace output file $trace_file-pid @@ -2846,6 +2877,9 @@ fi if test $vde = yes ; then echo CONFIG_VDE=y $config_host_mak fi +if test $cap = yes ; then + echo CONFIG_LIBCAP=y $config_host_mak +fi for card in $audio_card_list; do def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'` echo $def=y $config_host_mak diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c index db257d5..b1562eb 100644 --- a/qemu-bridge-helper.c +++ b/qemu-bridge-helper.c @@ -33,6 +33,10 @@ #include net/tap-linux.h +#ifdef CONFIG_LIBCAP +#includecap-ng.h +#endif + #define MAX_ACLS (128) #define DEFAULT_ACL_FILE CONFIG_QEMU_CONFDIR /bridge.conf @@ -185,6 +189,27 @@ static int send_fd(int c, int fd) return sendmsg(c,msg, 0); } +#ifdef CONFIG_LIBCAP +static int drop_privileges(void) +{ +/* clear all capabilities */ +capng_clear(CAPNG_SELECT_BOTH); + +if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, + CAP_NET_ADMIN) 0) { +return -1; +} + +/* change to calling user's real uid and gid, retaining supplemental + * groups and CAP_NET_ADMIN */ +if (capng_change_id(getuid(), getgid(), CAPNG_CLEAR_BOUNDING)) { +return -1; +} + +return 0; +} +#endif + int main(int argc, char **argv) { struct ifreq ifr; @@ -198,6 +223,20 @@ int main(int argc, char **argv) int acl_count = 0; int i, access_allowed, access_denied; +/* if we're run from an suid binary, immediately drop privileges preserving + * cap_net_admin -- exit immediately if libcap not configured */ +if (geteuid() == 0 getuid() != geteuid()) { +#ifdef CONFIG_LIBCAP +if (drop_privileges() == -1) { +fprintf(stderr, failed to drop privileges\n); +return 1; +} +#else +fprintf(stderr, failed to drop privileges\n); This makes the tool useless without CONFIG_LIBCAP. Wouldn't it be possible to use setfsuid() instead for Linux? Some fork+setuid helper could be used for other Unix and for the lame OSes without any file system DAC capabilities, a different syntax that does not rely on underlying FS may need to be introduced. Again, I don't know if the
[Qemu-devel] [PATCH 04/19] Monitor: Make mon_set_cpu() public
Also rename it to monitor_set_cpu(). Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- monitor.c | 11 +-- monitor.h |1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/monitor.c b/monitor.c index ea5ccd8..3f99ea0 100644 --- a/monitor.c +++ b/monitor.c @@ -514,7 +514,6 @@ static int do_qmp_capabilities(Monitor *mon, const QDict *params, return 0; } -static int mon_set_cpu(int cpu_index); static void handle_user_command(Monitor *mon, const char *cmdline); static int do_hmp_passthrough(Monitor *mon, const QDict *params, @@ -532,7 +531,7 @@ static int do_hmp_passthrough(Monitor *mon, const QDict *params, cur_mon = hmp; if (qdict_haskey(params, cpu-index)) { -ret = mon_set_cpu(qdict_get_int(params, cpu-index)); +ret = monitor_set_cpu(qdict_get_int(params, cpu-index)); if (ret 0) { cur_mon = old_mon; qerror_report(QERR_INVALID_PARAMETER_VALUE, cpu-index, a CPU number); @@ -772,8 +771,8 @@ CommandInfoList *qmp_query_commands(Error **errp) return cmd_list; } -/* get the current CPU defined by the user */ -static int mon_set_cpu(int cpu_index) +/* set the current CPU defined by the user */ +int monitor_set_cpu(int cpu_index) { CPUState *env; @@ -789,7 +788,7 @@ static int mon_set_cpu(int cpu_index) static CPUState *mon_get_cpu(void) { if (!cur_mon-mon_cpu) { -mon_set_cpu(0); +monitor_set_cpu(0); } cpu_synchronize_state(cur_mon-mon_cpu); return cur_mon-mon_cpu; @@ -901,7 +900,7 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data) static int do_cpu_set(Monitor *mon, const QDict *qdict, QObject **ret_data) { int index = qdict_get_int(qdict, index); -if (mon_set_cpu(index) 0) { +if (monitor_set_cpu(index) 0) { qerror_report(QERR_INVALID_PARAMETER_VALUE, index, a CPU number); return -1; diff --git a/monitor.h b/monitor.h index 4f2d328..9b723b2 100644 --- a/monitor.h +++ b/monitor.h @@ -57,6 +57,7 @@ void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void monitor_print_filename(Monitor *mon, const char *filename); void monitor_flush(Monitor *mon); +int monitor_set_cpu(int cpu_index); typedef void (MonitorCompletion)(void *opaque, QObject *ret_data); -- 1.7.7.1.431.g10b2a
[Qemu-devel] [PATCH 14/19] qapi: Convert query-spice
Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- hmp.c| 43 + hmp.h|1 + monitor.c| 13 +- qapi-schema.json | 74 + qmp-commands.hx |8 +++ qmp.c| 12 + ui/spice-core.c | 139 ++--- 7 files changed, 197 insertions(+), 93 deletions(-) diff --git a/hmp.c b/hmp.c index 6d86fe3..aae13c0 100644 --- a/hmp.c +++ b/hmp.c @@ -306,6 +306,49 @@ out: qapi_free_VncInfo(info); } +void hmp_info_spice(Monitor *mon) +{ +SpiceChannelList *chan; +SpiceInfo *info; + +info = qmp_query_spice(NULL); + +if (!info-enabled) { +monitor_printf(mon, Server: disabled\n); +goto out; +} + +monitor_printf(mon, Server:\n); +if (info-has_port) { +monitor_printf(mon, address: %s:% PRId64 \n, + info-host, info-port); +} +if (info-has_tls_port) { +monitor_printf(mon, address: %s:% PRId64 [tls]\n, + info-host, info-tls_port); +} +monitor_printf(mon, auth: %s\n, info-auth); +monitor_printf(mon, compiled: %s\n, info-compiled_version); + +if (!info-has_channels || info-channels == NULL) { +monitor_printf(mon, Channels: none\n); +} else { +for (chan = info-channels; chan; chan = chan-next) { +monitor_printf(mon, Channel:\n); +monitor_printf(mon, address: %s:%s%s\n, + chan-value-host, chan-value-port, + chan-value-tls ? [tls] : ); +monitor_printf(mon, session: % PRId64 \n, + chan-value-connection_id); +monitor_printf(mon, channel: % PRId64 :% PRId64 \n, + chan-value-channel_type, chan-value-channel_id); +} +} + +out: +qapi_free_SpiceInfo(info); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index 7713348..09f3a01 100644 --- a/hmp.h +++ b/hmp.h @@ -29,6 +29,7 @@ void hmp_info_cpus(Monitor *mon); void hmp_info_block(Monitor *mon); void hmp_info_blockstats(Monitor *mon); void hmp_info_vnc(Monitor *mon); +void hmp_info_spice(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/monitor.c b/monitor.c index d7c72bb..fc3da38 100644 --- a/monitor.c +++ b/monitor.c @@ -2857,8 +2857,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = , .params = , .help = show the spice server status, -.user_print = do_info_spice_print, -.mhandler.info_new = do_info_spice, +.mhandler.info = hmp_info_spice, }, #endif { @@ -2965,16 +2964,6 @@ static const mon_cmd_t qmp_query_cmds[] = { .user_print = do_pci_info_print, .mhandler.info_new = do_pci_info, }, -#if defined(CONFIG_SPICE) -{ -.name = spice, -.args_type = , -.params = , -.help = show the spice server status, -.user_print = do_info_spice_print, -.mhandler.info_new = do_info_spice, -}, -#endif { .name = balloon, .args_type = , diff --git a/qapi-schema.json b/qapi-schema.json index 23be143..087a463 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -585,6 +585,80 @@ { 'command': 'query-vnc', 'returns': 'VncInfo' } ## +# @SpiceChannel +# +# Information about a SPICE client channel. +# +# @host: The host name of the client. QEMU tries to resolve this to a DNS name +#when possible. +# +# @family: 'ipv6' if the client is connected via IPv6 and TCP +# 'ipv4' if the client is connected via IPv4 and TCP +# 'unix' if the client is connected via a unix domain socket +# 'unknown' otherwise +# +# @port: The client's port number. +# +# @connection-id: SPICE connection id number. All channels with the same id +# belong to the same SPICE session. +# +# @connection-type: SPICE channel type number. 1 is the main control channel, +# filter for this one if you want track spice sessions only +# +# @channel-id: SPICE channel ID number. Usually 0, might be different needed +# when multiple channels of the same type exist, such as multiple +# display channels in a multihead setup +# +# @tls: true if the channel is encrypted, false otherwise. +# +# Since: 0.14.0 +## +{ 'type': 'SpiceChannel', + 'data': {'host': 'str', 'family': 'str', 'port': 'str', + 'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int', + 'tls': 'bool'} } + +## +# @SpiceInfo +# +# Information about the SPICE session. +# +# @enabled: true if the SPICE server is
Re: [Qemu-devel] [Question] dump memory when host pci device is used by guest
- Original Message - The question is that: 'virsh dump' can not be used when host pci device is used by guest. We are discussing how to fix the problem. We have determined that introduce a new monitor command dump. Jan suggested that the core file's format is gdb standard core format. Does crash support such format? If no, is it possible to support such format? If you are talking about an ELF core dump of the user-space qemu-kvm process running on the host, then it's certainly not supported. As to whether it's possible, I suppose it could be done if a phyical-memory-read function could be created for it, similar to what I asked about for live analysis of a guest kernel run on/from the KVM host. Dave
Re: [Qemu-devel] [PATCH V2 02/10] Introduce HostPCIDevice to access a pci device on the host.
On Thu, Oct 20, 2011 at 11:57, Stefano Stabellini stefano.stabell...@eu.citrix.com wrote: On Wed, 19 Oct 2011, Anthony PERARD wrote: Signed-off-by: Anthony PERARD anthony.per...@citrix.com --- Makefile.target | 1 + hw/host-pci-device.c | 245 ++ hw/host-pci-device.h | 75 +++ 3 files changed, 321 insertions(+), 0 deletions(-) create mode 100644 hw/host-pci-device.c create mode 100644 hw/host-pci-device.h diff --git a/Makefile.target b/Makefile.target index c518103..ca3420d 100644 --- a/Makefile.target +++ b/Makefile.target @@ -209,6 +209,7 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o obj-i386-$(CONFIG_XEN) += xen_platform.o # Xen PCI Passthrough +obj-i386-$(CONFIG_XEN_PCI_PASSTHROUGH) += host-pci-device.o # Inter-VM PCI shared memory CONFIG_IVSHMEM = diff --git a/hw/host-pci-device.c b/hw/host-pci-device.c new file mode 100644 index 000..0f25fcf --- /dev/null +++ b/hw/host-pci-device.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2011 Citrix Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include qemu-common.h +#include host-pci-device.h + +static int path_to(const HostPCIDevice *d, + const char *name, char *buf, ssize_t size) +{ + return snprintf(buf, size, /sys/bus/pci/devices/%04x:%02x:%02x.%x/%s, + d-domain, d-bus, d-dev, d-func, name); +} + +static int get_resource(HostPCIDevice *d) +{ + int i, rc = 0; + FILE *f; + char path[PATH_MAX]; + unsigned long long start, end, flags, size; + + path_to(d, resource, path, sizeof (path)); + f = fopen(path, r); + if (!f) { + fprintf(stderr, Error: Can't open %s: %s\n, path, strerror(errno)); + return -1; it would be better to return a proper error code, rather than just -1 probably -errno will do it. + } + + for (i = 0; i PCI_NUM_REGIONS; i++) { + if (fscanf(f, %llx %llx %llx, start, end, flags) != 3) { + fprintf(stderr, Error: Syntax error in %s\n, path); + rc = -1; Ditto probably 1 with a define on the top of the file. + break; + } + if (start) { + size = end - start + 1; + } else { + size = 0; + } + + if (i PCI_ROM_SLOT) { + d-io_regions[i].base_addr = start; + d-io_regions[i].size = size; + d-io_regions[i].flags = flags; + } else { + d-rom.base_addr = start; + d-rom.size = size; + d-rom.flags = flags; + } + } + + fclose(f); + return rc; +} [...] + +uint32_t host_pci_find_ext_cap_offset(HostPCIDevice *d, uint32_t cap) +{ + uint32_t header = 0; + int max_cap = 480; + int pos = 0x100; could you used some defined constants here? Yes, I will. + do { + header = host_pci_get_long(d, pos); + /* + * If we have no capabilities, this is indicated by cap ID, + * cap version and next pointer all being 0. + */ + if (header == 0) { + break; + } + + if (PCI_EXT_CAP_ID(header) == cap) { + return pos; + } + + pos = PCI_EXT_CAP_NEXT(header); + if (pos 0x100) { + break; + } + + max_cap--; + } while (max_cap 0); + + return 0; +} -- Anthony PERARD
[Qemu-devel] [PATCH 02/19] qapi: Convert query-mice
Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- hmp.c| 20 hmp.h|1 + input.c | 64 + monitor.c| 11 + qapi-schema.json | 30 + qmp-commands.hx |6 + 6 files changed, 74 insertions(+), 58 deletions(-) diff --git a/hmp.c b/hmp.c index 34416fc..9c6d896 100644 --- a/hmp.c +++ b/hmp.c @@ -94,6 +94,26 @@ void hmp_info_chardev(Monitor *mon) qapi_free_ChardevInfoList(char_info); } +void hmp_info_mice(Monitor *mon) +{ +MouseInfoList *mice_list, *mouse; + +mice_list = qmp_query_mice(NULL); +if (!mice_list) { +monitor_printf(mon, No mouse devices connected\n); +return; +} + +for (mouse = mice_list; mouse; mouse = mouse-next) { +monitor_printf(mon, %c Mouse #% PRId64 : %s%s\n, + mouse-value-current ? '*' : ' ', + mouse-value-index, mouse-value-name, + mouse-value-absolute ? (absolute) : ); +} + +qapi_free_MouseInfoList(mice_list); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index 92433cf..4e6697d 100644 --- a/hmp.h +++ b/hmp.h @@ -23,6 +23,7 @@ void hmp_info_kvm(Monitor *mon); void hmp_info_status(Monitor *mon); void hmp_info_uuid(Monitor *mon); void hmp_info_chardev(Monitor *mon); +void hmp_info_mice(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/input.c b/input.c index e2f7c92..9ade63f 100644 --- a/input.c +++ b/input.c @@ -26,7 +26,8 @@ #include net.h #include monitor.h #include console.h -#include qjson.h +#include error.h +#include qmp-commands.h static QEMUPutKBDEvent *qemu_put_kbd_event; static void *qemu_put_kbd_event_opaque; @@ -211,60 +212,27 @@ int kbd_mouse_has_absolute(void) return 0; } -static void info_mice_iter(QObject *data, void *opaque) -{ -QDict *mouse; -Monitor *mon = opaque; - -mouse = qobject_to_qdict(data); -monitor_printf(mon, %c Mouse #% PRId64 : %s%s\n, - (qdict_get_bool(mouse, current) ? '*' : ' '), - qdict_get_int(mouse, index), qdict_get_str(mouse, name), - qdict_get_bool(mouse, absolute) ? (absolute) : ); -} - -void do_info_mice_print(Monitor *mon, const QObject *data) -{ -QList *mice_list; - -mice_list = qobject_to_qlist(data); -if (qlist_empty(mice_list)) { -monitor_printf(mon, No mouse devices connected\n); -return; -} - -qlist_iter(mice_list, info_mice_iter, mon); -} - -void do_info_mice(Monitor *mon, QObject **ret_data) +MouseInfoList *qmp_query_mice(Error **errp) { +MouseInfoList *mice_list = NULL; QEMUPutMouseEntry *cursor; -QList *mice_list; -int current; - -mice_list = qlist_new(); +bool current = true; -if (QTAILQ_EMPTY(mouse_handlers)) { -goto out; -} +QTAILQ_FOREACH(cursor, mouse_handlers, node) { +MouseInfoList *info = g_malloc0(sizeof(*info)); +info-value = g_malloc0(sizeof(*info-value)); +info-value-name = g_strdup(cursor-qemu_put_mouse_event_name); +info-value-index = cursor-index; +info-value-absolute = !!cursor-qemu_put_mouse_event_absolute; +info-value-current = current; -current = QTAILQ_FIRST(mouse_handlers)-index; +current = false; -QTAILQ_FOREACH(cursor, mouse_handlers, node) { -QObject *obj; -obj = qobject_from_jsonf({ 'name': %s, - 'index': %d, - 'current': %i, - 'absolute': %i }, - cursor-qemu_put_mouse_event_name, - cursor-index, - cursor-index == current, - !!cursor-qemu_put_mouse_event_absolute); -qlist_append_obj(mice_list, obj); +info-next = mice_list; +mice_list = info; } -out: -*ret_data = QOBJECT(mice_list); +return mice_list; } void do_mouse_set(Monitor *mon, const QDict *qdict) diff --git a/monitor.c b/monitor.c index ffda0fe..d95abce 100644 --- a/monitor.c +++ b/monitor.c @@ -2942,8 +2942,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = , .params = , .help = show which guest mouse is receiving events, -.user_print = do_info_mice_print, -.mhandler.info_new = do_info_mice, +.mhandler.info = hmp_info_mice, }, { .name = vnc, @@ -3093,14 +3092,6 @@ static const mon_cmd_t qmp_query_cmds[] = { .mhandler.info_new = do_pci_info, }, { -.name = mice, -
Re: [Qemu-devel] [PATCH V2 08/10] Introduce Xen PCI Passthrough, qdevice (1/3)
On Thu, Oct 20, 2011 at 11:59, Stefano Stabellini stefano.stabell...@eu.citrix.com wrote: + if (s-pm_state != NULL s-pm_state-flags PT_FLAG_TRANSITING) { + qemu_mod_timer(s-pm_state-pm_timer, + qemu_get_clock_ms(rt_clock) + s-pm_state-pm_delay); + } where is this allocated? The allocation is in the next patch, the long file that handle the config space. -- Anthony PERARD
[Qemu-devel] [PATCH 15/19] qapi: Convert query-balloon
Please, note that some of the code supporting memory statistics is still around (eg. virtio_balloon_receive_stats() and reset_stats()). Also, the qmp_query_balloon() function is synchronous and thus doesn't make any use of the (not fully working) monitor's asynchronous command support (the old non-qapi implementation did). Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- balloon.c | 72 +-- balloon.h |6 +-- hmp.c | 39 + hmp.h |1 + hw/virtio-balloon.c | 78 +- monitor.c | 13 + qapi-schema.json| 44 qmp-commands.hx |5 +++ 8 files changed, 120 insertions(+), 138 deletions(-) diff --git a/balloon.c b/balloon.c index a2133db..e1cd5fa 100644 --- a/balloon.c +++ b/balloon.c @@ -25,12 +25,11 @@ */ #include monitor.h -#include qjson.h -#include qint.h #include cpu-common.h #include kvm.h #include balloon.h #include trace.h +#include qmp-commands.h static QEMUBalloonEvent *balloon_event_fn; static QEMUBalloonStatus *balloon_stat_fn; @@ -72,76 +71,33 @@ static int qemu_balloon(ram_addr_t target) return 1; } -static int qemu_balloon_status(MonitorCompletion cb, void *opaque) +static int qemu_balloon_status(BalloonInfo *info) { if (!balloon_stat_fn) { return 0; } -balloon_stat_fn(balloon_opaque, cb, opaque); +balloon_stat_fn(balloon_opaque, info); return 1; } -static void print_balloon_stat(const char *key, QObject *obj, void *opaque) +BalloonInfo *qmp_query_balloon(Error **errp) { -Monitor *mon = opaque; - -if (strcmp(key, actual)) { -monitor_printf(mon, ,%s=% PRId64, key, - qint_get_int(qobject_to_qint(obj))); -} -} - -void monitor_print_balloon(Monitor *mon, const QObject *data) -{ -QDict *qdict; - -qdict = qobject_to_qdict(data); -if (!qdict_haskey(qdict, actual)) { -return; -} -monitor_printf(mon, balloon: actual=% PRId64, - qdict_get_int(qdict, actual) 20); -qdict_iter(qdict, print_balloon_stat, mon); -monitor_printf(mon, \n); -} - -/** - * do_info_balloon(): Balloon information - * - * Make an asynchronous request for balloon info. When the request completes - * a QDict will be returned according to the following specification: - * - * - actual: current balloon value in bytes - * The following fields may or may not be present: - * - mem_swapped_in: Amount of memory swapped in (bytes) - * - mem_swapped_out: Amount of memory swapped out (bytes) - * - major_page_faults: Number of major faults - * - minor_page_faults: Number of minor faults - * - free_mem: Total amount of free and unused memory (bytes) - * - total_mem: Total amount of available memory (bytes) - * - * Example: - * - * { actual: 1073741824, mem_swapped_in: 0, mem_swapped_out: 0, - * major_page_faults: 142, minor_page_faults: 239245, - * free_mem: 1014185984, total_mem: 1044668416 } - */ -int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque) -{ -int ret; +BalloonInfo *info; if (kvm_enabled() !kvm_has_sync_mmu()) { -qerror_report(QERR_KVM_MISSING_CAP, synchronous MMU, balloon); -return -1; +error_set(errp, QERR_KVM_MISSING_CAP, synchronous MMU, balloon); +return NULL; } -ret = qemu_balloon_status(cb, opaque); -if (!ret) { -qerror_report(QERR_DEVICE_NOT_ACTIVE, balloon); -return -1; +info = g_malloc0(sizeof(*info)); + +if (qemu_balloon_status(info) == 0) { +error_set(errp, QERR_DEVICE_NOT_ACTIVE, balloon); +qapi_free_BalloonInfo(info); +return NULL; } -return 0; +return info; } /** diff --git a/balloon.h b/balloon.h index f59e288..b36abea 100644 --- a/balloon.h +++ b/balloon.h @@ -15,17 +15,15 @@ #define _QEMU_BALLOON_H #include monitor.h +#include qapi-types.h typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target); -typedef void (QEMUBalloonStatus)(void *opaque, MonitorCompletion cb, - void *cb_data); +typedef void (QEMUBalloonStatus)(void *opaque, BalloonInfo *info); int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, QEMUBalloonStatus *stat_func, void *opaque); void qemu_remove_balloon_handler(void *opaque); -void monitor_print_balloon(Monitor *mon, const QObject *data); -int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque); int do_balloon(Monitor *mon, const QDict *params, MonitorCompletion cb, void *opaque); diff --git a/hmp.c b/hmp.c index aae13c0..e0b40b1 100644 --- a/hmp.c +++ b/hmp.c @@ -349,6 +349,45 @@ out: qapi_free_SpiceInfo(info); } +void hmp_info_balloon(Monitor *mon) +{ +BalloonInfo *info; +
Re: [Qemu-devel] [PATCH V2 09/10] Introduce Xen PCI Passthrough, PCI config space helpers (2/3)
On Thu, Oct 20, 2011 at 12:01, Stefano Stabellini stefano.stabell...@eu.citrix.com wrote: + /* disable MSI/MSI-X and MSI-INTx translation */ + if (s-msi) { + pt_msi_disable(s); + } + if (s-msix) { + pt_msix_disable(s); + } these msi functions are not implemented yet Ok, I will remove all msi related call and define, and move them to the next patch. -- Anthony PERARD
[Qemu-devel] [PATCH 16/19] qapi: Convert query-pci
This also fixes a bug with the old version: QMP would invert device id and vendor id. This would look ok on HMP because it was printing device:vendor instead of vendor:device. Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- hmp.c| 101 + hmp.h|1 + hw/pci-stub.c| 15 +-- hw/pci.c | 322 -- hw/pci.h |4 - monitor.c| 11 +-- qapi-schema.json | 128 + qmp-commands.hx |6 + 8 files changed, 363 insertions(+), 225 deletions(-) diff --git a/hmp.c b/hmp.c index e0b40b1..443d3a7 100644 --- a/hmp.c +++ b/hmp.c @@ -388,6 +388,107 @@ void hmp_info_balloon(Monitor *mon) qapi_free_BalloonInfo(info); } +static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev) +{ +PciMemoryRegionList *region; + +monitor_printf(mon, Bus %2 PRId64 , , dev-bus); +monitor_printf(mon, device %3 PRId64 , function % PRId64 :\n, + dev-slot, dev-function); +monitor_printf(mon, ); + +if (dev-class_info.has_desc) { +monitor_printf(mon, %s, dev-class_info.desc); +} else { +monitor_printf(mon, Class %04 PRId64, dev-class_info.class); +} + +monitor_printf(mon, : PCI device %04 PRIx64 :%04 PRIx64 \n, + dev-id.vendor, dev-id.device); + +if (dev-has_irq) { +monitor_printf(mon, IRQ % PRId64 .\n, dev-irq); +} + +if (dev-has_pci_bridge) { +monitor_printf(mon, BUS % PRId64 .\n, + dev-pci_bridge-bus.number); +monitor_printf(mon, secondary bus % PRId64 .\n, + dev-pci_bridge-bus.secondary); +monitor_printf(mon, subordinate bus % PRId64 .\n, + dev-pci_bridge-bus.subordinate); + +monitor_printf(mon, IO range [0x%04PRIx64, 0x%04PRIx64]\n, + dev-pci_bridge-bus.io_range-base, + dev-pci_bridge-bus.io_range-limit); + +monitor_printf(mon, + memory range [0x%08PRIx64, 0x%08PRIx64]\n, + dev-pci_bridge-bus.memory_range-base, + dev-pci_bridge-bus.memory_range-limit); + +monitor_printf(mon, prefetchable memory range + [0x%08PRIx64, 0x%08PRIx64]\n, + dev-pci_bridge-bus.prefetchable_range-base, + dev-pci_bridge-bus.prefetchable_range-limit); +} + +for (region = dev-regions; region; region = region-next) { +uint64_t addr, size; + +addr = region-value-address; +size = region-value-size; + +monitor_printf(mon, BAR% PRId64 : , region-value-bar); + +if (!strcmp(region-value-type, io)) { +monitor_printf(mon, I/O at 0x%04 PRIx64 + [0x%04 PRIx64 ].\n, + addr, addr + size - 1); +} else { +monitor_printf(mon, %d bit%s memory at 0x%08 PRIx64 +[0x%08 PRIx64 ].\n, + region-value-mem_type_64 ? 64 : 32, + region-value-prefetch ? prefetchable : , + addr, addr + size - 1); +} +} + +monitor_printf(mon, id \%s\\n, dev-qdev_id); + +if (dev-has_pci_bridge) { +if (dev-pci_bridge-has_devices) { +PciDeviceInfoList *cdev; +for (cdev = dev-pci_bridge-devices; cdev; cdev = cdev-next) { +hmp_info_pci_device(mon, cdev-value); +} +} +} +} + +void hmp_info_pci(Monitor *mon) +{ +PciInfoList *info; +Error *err = NULL; + +info = qmp_query_pci(err); +if (err) { +monitor_printf(mon, PCI devices not supported\n); +error_free(err); +return; +} + +for (; info; info = info-next) { +PciDeviceInfoList *dev; + +for (dev = info-value-devices; dev; dev = dev-next) { +hmp_info_pci_device(mon, dev-value); +} +} + +qapi_free_PciInfoList(info); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index d2c2d88..4422578 100644 --- a/hmp.h +++ b/hmp.h @@ -31,6 +31,7 @@ void hmp_info_blockstats(Monitor *mon); void hmp_info_vnc(Monitor *mon); void hmp_info_spice(Monitor *mon); void hmp_info_balloon(Monitor *mon); +void hmp_info_pci(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/hw/pci-stub.c b/hw/pci-stub.c index 1fb105d..636171c 100644 --- a/hw/pci-stub.c +++ b/hw/pci-stub.c @@ -21,20 +21,17 @@ #include sysemu.h #include monitor.h #include pci.h +#include qmp-commands.h -static void pci_error_message(Monitor
[Qemu-devel] [PATCH 13/19] qapi: Convert query-vnc
There are three important remarks in relation to the non-qapi command: 1. This commit also fixes the behavior of the 'query-vnc' and 'info vnc' commands to return an error when qemu is built without VNC support (ie. --disable-vnc). The non-qapi command would return the OK response in QMP and no response in HMP 2. The qapi version explicitly marks the fields 'host', 'family', 'service' and 'auth' as optional. Their are not documented as optional in the non-qapi command doc, but they would not be returned if vnc support is disabled. The qapi version maintains the same semantics, but documents those fields correctly 3. The 'clients' field, which is a list, is marked as optional but is always returned. If there are no clients connected an empty list is returned. This is not the Right Way to this in the qapi but it's how the non-qapi command used to work Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- console.h|9 hmp.c| 46 ++ hmp.h|1 + monitor.c| 11 + qapi-schema.json | 81 qmp-commands.hx |6 ++ qmp.c| 10 ui/vnc.c | 135 +- 8 files changed, 228 insertions(+), 71 deletions(-) diff --git a/console.h b/console.h index 9c1487e..6ac4ed3 100644 --- a/console.h +++ b/console.h @@ -383,8 +383,6 @@ char *vnc_display_local_addr(DisplayState *ds); #ifdef CONFIG_VNC int vnc_display_password(DisplayState *ds, const char *password); int vnc_display_pw_expire(DisplayState *ds, time_t expires); -void do_info_vnc_print(Monitor *mon, const QObject *data); -void do_info_vnc(Monitor *mon, QObject **ret_data); #else static inline int vnc_display_password(DisplayState *ds, const char *password) { @@ -396,13 +394,6 @@ static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires) qerror_report(QERR_FEATURE_DISABLED, vnc); return -ENODEV; }; -static inline void do_info_vnc(Monitor *mon, QObject **ret_data) -{ -}; -static inline void do_info_vnc_print(Monitor *mon, const QObject *data) -{ -monitor_printf(mon, VNC support disabled\n); -}; #endif /* curses.c */ diff --git a/hmp.c b/hmp.c index eab2ddf..6d86fe3 100644 --- a/hmp.c +++ b/hmp.c @@ -260,6 +260,52 @@ void hmp_info_blockstats(Monitor *mon) qapi_free_BlockStatsList(stats_list); } +void hmp_info_vnc(Monitor *mon) +{ +VncInfo *info; +Error *err = NULL; +VncClientInfoList *client; + +info = qmp_query_vnc(err); +if (err) { +monitor_printf(mon, %s\n, error_get_pretty(err)); +error_free(err); +return; +} + +if (!info-enabled) { +monitor_printf(mon, Server: disabled\n); +goto out; +} + +monitor_printf(mon, Server:\n); +if (info-has_host info-has_service) { +monitor_printf(mon, address: %s:%s\n, info-host, info-service); +} +if (info-has_auth) { +monitor_printf(mon, auth: %s\n, info-auth); +} + +if (!info-has_clients || info-clients == NULL) { +monitor_printf(mon, Client: none\n); +} else { +for (client = info-clients; client; client = client-next) { +monitor_printf(mon, Client:\n); +monitor_printf(mon, address: %s:%s\n, + client-value-host, client-value-service); +monitor_printf(mon, x509_dname: %s\n, + client-value-x509_dname ? + client-value-x509_dname : none); +monitor_printf(mon, username: %s\n, + client-value-has_sasl_username ? + client-value-sasl_username : none); +} +} + +out: +qapi_free_VncInfo(info); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index f8c50d4..7713348 100644 --- a/hmp.h +++ b/hmp.h @@ -28,6 +28,7 @@ void hmp_info_migrate(Monitor *mon); void hmp_info_cpus(Monitor *mon); void hmp_info_block(Monitor *mon); void hmp_info_blockstats(Monitor *mon); +void hmp_info_vnc(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/monitor.c b/monitor.c index 70e5460..d7c72bb 100644 --- a/monitor.c +++ b/monitor.c @@ -2849,8 +2849,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = , .params = , .help = show the vnc server status, -.user_print = do_info_vnc_print, -.mhandler.info_new = do_info_vnc, +.mhandler.info = hmp_info_vnc, }, #if defined(CONFIG_SPICE) { @@ -2966,14 +2965,6 @@ static const mon_cmd_t qmp_query_cmds[] = { .user_print = do_pci_info_print, .mhandler.info_new =
[Qemu-devel] [PATCH 05/19] Monitor: Introduce monitor_get_cpu_index()
Returns 'cur_mons's CPU index. A future commit will use it. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- monitor.c |5 + monitor.h |1 + 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index 3f99ea0..3e1cd33 100644 --- a/monitor.c +++ b/monitor.c @@ -794,6 +794,11 @@ static CPUState *mon_get_cpu(void) return cur_mon-mon_cpu; } +int monitor_get_cpu_index(void) +{ +return mon_get_cpu()-cpu_index; +} + static void do_info_registers(Monitor *mon) { CPUState *env; diff --git a/monitor.h b/monitor.h index 9b723b2..e76795f 100644 --- a/monitor.h +++ b/monitor.h @@ -58,6 +58,7 @@ void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void monitor_print_filename(Monitor *mon, const char *filename); void monitor_flush(Monitor *mon); int monitor_set_cpu(int cpu_index); +int monitor_get_cpu_index(void); typedef void (MonitorCompletion)(void *opaque, QObject *ret_data); -- 1.7.7.1.431.g10b2a
[Qemu-devel] [PATCH v1 00/19]: QAPI conversions round 2
This series completes the conversion of current QMP query commands to the QAPI framework. IOW, with this series applied no single query command will be building QObjects by hand. This series also contains two fixes and some cleanups. One of the fixes solves a problem with the generated code which ignores errors. The other fixes a missing error declaration in QError. There are two important details about this series that should be observed: 1. This is a bit late in the development process. Although there's a lot of code churn involved, query commands are relatively simple: most of them don't return errors and they don't take parameters. I've also tested them as much as I could. I'm not saying it's bug-free, but I believe we have enough time for fixing any outstanding issues. 2. Most query commands makes use of QAPI's list type. Unfortunately, the simplest way to build a list reverses the order of listings in HMP (ie. the info cpus command starts at the last CPU). To avoid this, I'm building lists by hand the old way for now. In the short term the QAPI will be changed to use glib's list support. balloon.c| 72 +- balloon.h|6 +- block.c | 234 ++ block.h |5 - block_int.h |4 +- console.h|9 - cpus.c | 45 error.c |3 +- hmp-commands.hx |3 +- hmp.c| 407 ++ hmp.h| 10 + hw/pci-stub.c| 15 +- hw/pci.c | 322 +--- hw/pci.h |4 - hw/virtio-balloon.c | 78 +- input.c | 64 ++ migration.c | 82 ++- monitor.c| 313 ++-- monitor.h|2 + qapi-schema.json | 616 ++ qerror.c |4 + qmp-commands.hx | 60 +- qmp.c| 27 ++ scripts/qapi-commands.py |4 +- ui/spice-core.c | 139 +-- ui/vnc.c | 135 +++ vl.c |2 +- 27 files changed, 1611 insertions(+), 1054 deletions(-)
Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
Kai Tietz wrote: Hi, For trunk-version I have a tentative patch for this issue. On 4.6.x and older branches this doesn't work, as here we can't differenciate that easy between ms- and sysv-abi. But could somebody give this patch a try? Regards, Kai ChangeLog * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of frame-pointer for 32-bit ms-abi, if setjmp is used. Index: i386.c === --- i386.c (revision 180099) +++ i386.c (working copy) @@ -8391,6 +8391,10 @@ if (SUBTARGET_FRAME_POINTER_REQUIRED) return true; + /* For older 32-bit runtimes setjmp requires valid frame-pointer. */ + if (TARGET_32BIT_MS_ABI cfun-calls_setjmp) +return true; + /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER turns off the frame pointer by default. Turn it back on now if we've not got a leaf function. */ For a gcc 4.7 snapshot, this does fix the longjmp problem that I encountered. So aside from specifying -fno-omit-frame-pointer for affected files, what can be done for 4.6? Bob
Re: [Qemu-devel] [Question] dump memory when host pci device is used by guest
On 10/24/2011 04:25 PM, Dave Anderson wrote: The question is that: 'virsh dump' can not be used when host pci device is used by guest. We are discussing how to fix the problem. We have determined that introduce a new monitor command dump. Jan suggested that the core file's format is gdb standard core format. Does crash support such format? If no, is it possible to support such format? If you are talking about an ELF core dump of the user-space qemu-kvm process running on the host, then it's certainly not supported. No, an ELF image of the guest's physical memory. As to whether it's possible, I suppose it could be done if a phyical-memory-read function could be created for it, similar to what I asked about for live analysis of a guest kernel run on/from the KVM host. We could use the gdb protocol for this. Currently it reads/writes virtual memory, but we could extend the gdbserver command to make these commands apply to physical memory. -- I have a truly marvellous patch that fixes the bug which this signature is too narrow to contain.
Re: [Qemu-devel] [PATCH 29/35] scsi-disk: remove cluster_size
Am 13.10.2011 13:03, schrieb Paolo Bonzini: This field is redundant, and its presence makes it more complicated to share reqops between the upcoming scsi-block and scsi-generic. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/scsi-disk.c | 45 ++--- 1 files changed, 22 insertions(+), 23 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 5e3ef51..7f2f67f 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -65,9 +65,6 @@ typedef struct SCSIDiskReq { struct SCSIDiskState { SCSIDevice qdev; -/* The qemu block layer uses a fixed 512 byte sector size. - This is the number of 512 byte blocks in a single scsi sector. */ -int cluster_size; uint32_t removable; uint64_t max_lba; bool media_changed; @@ -862,7 +859,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, bdrv_get_geometry_hint(bdrv, cylinders, heads, secs); p[4] = heads 0xff; p[5] = secs 0xff; -p[6] = s-cluster_size * 2; +p[6] = s-qdev.blocksize 8; p[8] = (cylinders 8) 0xff; p[9] = cylinders 0xff; /* Write precomp start cylinder, disabled */ @@ -991,7 +988,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf) } else { /* MODE_SENSE_10 */ outbuf[7] = 8; /* Block descriptor length */ } -nb_sectors /= s-cluster_size; +nb_sectors /= (s-qdev.blocksize / 512); if (nb_sectors 0xff) nb_sectors = 0; p[0] = 0; /* media density code */ @@ -1000,7 +997,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf) p[3] = nb_sectors 0xff; p[4] = 0; /* reserved */ p[5] = 0; /* bytes 5-7 are the sector size in bytes */ -p[6] = s-cluster_size * 2; +p[6] = s-qdev.blocksize 8; p[7] = 0; p += 8; } @@ -1050,7 +1047,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) start_track = req-cmd.buf[6]; bdrv_get_geometry(s-qdev.conf.bs, nb_sectors); DPRINTF(Read TOC (track %d format %d msf %d)\n, start_track, format, msf 1); -nb_sectors /= s-cluster_size; +nb_sectors /= s-qdev.blocksize / 512; switch (format) { case 0: toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track); @@ -1176,7 +1173,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) if ((req-cmd.buf[8] 1) == 0 req-cmd.lba) { goto illegal_request; } -nb_sectors /= s-cluster_size; +nb_sectors /= s-qdev.blocksize / 512; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ @@ -1190,7 +1187,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) outbuf[3] = nb_sectors 0xff; outbuf[4] = 0; outbuf[5] = 0; -outbuf[6] = s-cluster_size * 2; +outbuf[6] = s-qdev.blocksize 8; outbuf[7] = 0; buflen = 8; break; @@ -1226,7 +1223,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) if ((req-cmd.buf[14] 1) == 0 req-cmd.lba) { goto illegal_request; } -nb_sectors /= s-cluster_size; +nb_sectors /= s-qdev.blocksize / 512; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ @@ -1241,7 +1238,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) outbuf[7] = nb_sectors 0xff; outbuf[8] = 0; outbuf[9] = 0; -outbuf[10] = s-cluster_size * 2; +outbuf[10] = s-qdev.blocksize 8; outbuf[11] = 0; outbuf[12] = 0; outbuf[13] = get_physical_block_exp(s-qdev.conf); @@ -1349,8 +1346,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) DPRINTF(Read (sector % PRId64 , count %d)\n, r-req.cmd.lba, len); if (r-req.cmd.lba s-max_lba) goto illegal_lba; -r-sector = r-req.cmd.lba * s-cluster_size; -r-sector_count = len * s-cluster_size; +r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512); +r-sector_count = len * (s-qdev.blocksize / 512); break; case WRITE_6: case WRITE_10: @@ -1365,8 +1362,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) r-req.cmd.lba, len); if (r-req.cmd.lba s-max_lba) goto illegal_lba; -r-sector = r-req.cmd.lba * s-cluster_size; -r-sector_count = len * s-cluster_size; +r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512); +r-sector_count = len *
Re: [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines
This commit (1c9805a398cc1125b4defa6367172c8c2c0bca9f in Git) breaks qemu-nbd for me. I cannot mount any VM image (raw or qcow2 format) with this commit or today's HEAD. Previous commit c5fbe57111ef59c315a71cd80e8b0af59e36ff21 works fine. The qemu-nbd process hangs while reading disk: 31175 ?Ss 0:00 qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw 31176 ?S 0:00 \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw 31177 ?D 0:00 \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw In dmesg I see only: [18304.541058] nbd0: Then, if I pkill -9 nbd, dmesg gets more verbose: [18467.288183] nbd (pid 31175: qemu-nbd) got signal 9 [18467.303175] nbd0: shutting down socket [18467.314446] nbd0: Receive control failed (result -4) [18467.329354] end_request: I/O error, dev nbd0, sector 0 [18467.344771] __ratelimit: 38 callbacks suppressed [18467.358620] Buffer I/O error on device nbd0, logical block 0 [18467.375591] Buffer I/O error on device nbd0, logical block 1 [18467.392560] Buffer I/O error on device nbd0, logical block 2 [18467.409530] Buffer I/O error on device nbd0, logical block 3 [18467.426508] nbd0: queue cleared [18467.435962] nbd0: Attempted send on closed socket [18467.450095] end_request: I/O error, dev nbd0, sector 0 [18467.465527] Buffer I/O error on device nbd0, logical block 0 [18467.482496] Buffer I/O error on device nbd0, logical block 1 [18467.499464] Buffer I/O error on device nbd0, logical block 2 [18467.516433] Buffer I/O error on device nbd0, logical block 3 [18467.533418] nbd0: Attempted send on closed socket [18467.547539] end_request: I/O error, dev nbd0, sector 0 [18467.562945] Buffer I/O error on device nbd0, logical block 0 [18467.579917] Buffer I/O error on device nbd0, logical block 1 [18467.596897] nbd0: Attempted send on closed socket [18467.611022] end_request: I/O error, dev nbd0, sector 0 [18467.626442] nbd0: Attempted send on closed socket [18467.640569] end_request: I/O error, dev nbd0, sector 0 [18467.655984] ldm_validate_partition_table(): Disk read failed. [18467.673242] nbd0: Attempted send on closed socket [18467.687369] end_request: I/O error, dev nbd0, sector 0 [18467.702788] nbd0: Attempted send on closed socket [18467.716915] end_request: I/O error, dev nbd0, sector 0 [18467.732359] nbd0: Attempted send on closed socket [18467.746487] end_request: I/O error, dev nbd0, sector 0 [18467.761931] nbd0: Attempted send on closed socket [18467.776058] end_request: I/O error, dev nbd0, sector 0 [18467.791473] Dev nbd0: unable to read RDB block 0 [18467.805348] nbd0: Attempted send on closed socket [18467.819479] end_request: I/O error, dev nbd0, sector 0 [18467.834897] nbd0: Attempted send on closed socket [18467.849025] end_request: I/O error, dev nbd0, sector 0 [18467.864446] nbd0: Attempted send on closed socket [18467.878572] end_request: I/O error, dev nbd0, sector 0 [18467.893985] unable to read partition table -- Pierre Riteau -- PhD student, Myriads team, IRISA, Rennes, France http://perso.univ-rennes1.fr/pierre.riteau/ On 14 oct. 2011, at 18:49, Kevin Wolf wrote: From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com The bdrv_read()/bdrv_write() functions call .bdrv_read()/.bdrv_write(). They should go through bdrv_co_do_readv() and bdrv_co_do_writev() instead in order to unify request processing code across sync, aio, and coroutine interfaces. This is also an important step towards removing BlockDriverState .bdrv_read()/.bdrv_write() in the future. Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com Signed-off-by: Kevin Wolf kw...@redhat.com --- block.c | 112 +++ 1 files changed, 62 insertions(+), 50 deletions(-) diff --git a/block.c b/block.c index f4731ec..ae8fc80 100644 --- a/block.c +++ b/block.c @@ -44,6 +44,8 @@ #include windows.h #endif +#define NOT_DONE 0x7fff /* used while emulated sync operation in progress */ + static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load); static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, @@ -74,6 +76,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs); static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); +static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, +int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); static QTAILQ_HEAD(, BlockDriverState) bdrv_states = QTAILQ_HEAD_INITIALIZER(bdrv_states); @@ -1042,30 +1046,69 @@ static inline bool bdrv_has_async_flush(BlockDriver *drv) return drv-bdrv_aio_flush != bdrv_aio_flush_em; } -/* return 0 if error. See bdrv_write() for the return codes */ -int bdrv_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors)
Re: [Qemu-devel] [PATCH 1/5] monitor: screen_dump async
On 10/24/11 14:02, Alon Levy wrote: Make screen_dump monitor command an async command to allow next for qxl to implement it as a initiating call to red_worker and completion on callback, to fix a deadlock when issueing a screendump command via libvirt while connected with a libvirt controlled spice-gtk client. Approach looks reasonable to me. Patch breaks the build though, you've missed a bunch of screen_dump functions in non-x86 targets. cheers, Gerd
Re: [Qemu-devel] [Question] dump memory when host pci device is used by guest
- Original Message - On 10/24/2011 04:25 PM, Dave Anderson wrote: The question is that: 'virsh dump' can not be used when host pci device is used by guest. We are discussing how to fix the problem. We have determined that introduce a new monitor command dump. Jan suggested that the core file's format is gdb standard core format. Does crash support such format? If no, is it possible to support such format? If you are talking about an ELF core dump of the user-space qemu-kvm process running on the host, then it's certainly not supported. No, an ELF image of the guest's physical memory. Well then that should be pretty straight forward to support. Depending upon how similar it would be to the standard kdump ELF format, the only other issue is how to determine the physical base address at which the kernel is loaded, in order to be able to translate the mapped kernel-text/static-data virtual region of the x86_64 arch (the __START_KERNEL_map region). As to whether it's possible, I suppose it could be done if a phyical-memory-read function could be created for it, similar to what I asked about for live analysis of a guest kernel run on/from the KVM host. We could use the gdb protocol for this. Currently it reads/writes virtual memory, but we could extend the gdbserver command to make these commands apply to physical memory.
Re: [Qemu-devel] [PATCH 35/35] scsi-disk: add scsi-block for device passthrough
Am 13.10.2011 13:04, schrieb Paolo Bonzini: scsi-block is a new device that supports device passthrough of Linux block devices (i.e. /dev/sda, not /dev/sg0). It uses SG_IO for commands other than I/O commands, and regular AIO read/writes for I/O commands. Besides being simpler to configure (no mapping required to scsi-generic device names), this removes the need for a large bounce buffer and, in the future, will get scatter/gather support for free from scsi-disk. Signed-off-by: Paolo Bonzini pbonz...@redhat.com This doesn't seem to use much of scsi-disk, so what about exporting scsi_disk_reqops and adding a separate file scsi-block.c? Would make things a bit more symmetrical between scsi-disk and scsi-generic. Or will future patches add code that depends on internal interfaces of scsi-disk? Kevin
Re: [Qemu-devel] [PATCH 3/5] qxl: support concurrent async commands
Hi, +SpiceAsyncCommand *push_spice_async_command(PCIQXLDevice *qxl, +uint32_t async_io, int size) +/* caller must call g_free */ +static SpiceAsyncCommand *pop_spice_async_command(PCIQXLDevice *qxl, + uint64_t cookie) +{ push/pop naming implies stack-like operation, which isn't true though. pop will lookup by cookie. Also an explicit release function would be good (list unlink and g_free call can go there). Maybe have spice_async_cmd_{alloc,lookup,free} ? Have you considered passing down a SpiceAsyncCommand pointer instead of the cookie value everywhere? Seems to be a bit cleaner and more future-proof to me. Not sure it buys us much in practice though, so maybe it isn't worth the trouble. cheers, Gerd
Re: [Qemu-devel] [PATCH 35/35] scsi-disk: add scsi-block for device passthrough
On 10/24/2011 05:28 PM, Kevin Wolf wrote: scsi-block is a new device that supports device passthrough of Linux block devices (i.e. /dev/sda, not /dev/sg0). It uses SG_IO for commands other than I/O commands, and regular AIO read/writes for I/O commands. Besides being simpler to configure (no mapping required to scsi-generic device names), this removes the need for a large bounce buffer and, in the future, will get scatter/gather support for free from scsi-disk. Signed-off-by: Paolo Bonzinipbonz...@redhat.com This doesn't seem to use much of scsi-disk, so what about exporting scsi_disk_reqops and adding a separate file scsi-block.c? Would make things a bit more symmetrical between scsi-disk and scsi-generic. Or will future patches add code that depends on internal interfaces of scsi-disk? It already uses some internal interfaces: scsi_initfn, scsi_disk_reset, scsi_destroy, sizeof(SCSIDiskState). Paolo
Re: [Qemu-devel] [PATCH 5/5] qxl: support async monitor screen dump
On 10/24/11 14:02, Alon Levy wrote: Split qxl_spice_update_area_complete from qxl_render_update, use SPICE_INTERFACE_QXL_MINOR 2 introduced spice_qxl_update_area_dirty_async to retrive the dirty rectangles asyncronously (the previous spice_qxl_update_area_async did not accept a dirty rectangles array). Introduce SpiceAsyncMonitorScreenDump for a screen_dump. That one conflicts with the screendump/SDL fixes pushed to the spice.v44 branch. Have you seen the mail? Had you time to look at the patches? cheers, Gerd
Re: [Qemu-devel] [Question] dump memory when host pci device is used by guest
On 10/24/2011 05:25 PM, Dave Anderson wrote: - Original Message - On 10/24/2011 04:25 PM, Dave Anderson wrote: The question is that: 'virsh dump' can not be used when host pci device is used by guest. We are discussing how to fix the problem. We have determined that introduce a new monitor command dump. Jan suggested that the core file's format is gdb standard core format. Does crash support such format? If no, is it possible to support such format? If you are talking about an ELF core dump of the user-space qemu-kvm process running on the host, then it's certainly not supported. No, an ELF image of the guest's physical memory. Well then that should be pretty straight forward to support. Depending upon how similar it would be to the standard kdump ELF format, the only other issue is how to determine the physical base address at which the kernel is loaded, in order to be able to translate the mapped kernel-text/static-data virtual region of the x86_64 arch (the __START_KERNEL_map region). I guess an elf note would work for that? -- I have a truly marvellous patch that fixes the bug which this signature is too narrow to contain.
Re: [Qemu-devel] KVM call agenda for October 25
On Mon, 24 Oct 2011 13:02:05 +0100 Peter Maydell peter.mayd...@linaro.org wrote: On 24 October 2011 12:35, Paolo Bonzini pbonz...@redhat.com wrote: On 10/24/2011 01:04 PM, Juan Quintela wrote: Please send in any agenda items you are interested in covering. - What's left to merge for 1.0. Things on my list, FWIW: * current target-arm pullreq * PL041 support (needs another patch round to fix a minor bug Andrzej spotted) * cpu_single_env must be thread-local I submitted today the second round of QAPI conversions, which converts all existing QMP query commands to the QAPI (plus some fixes). I expect that to make 1.0.
Re: [Qemu-devel] [PATCH 35/35] scsi-disk: add scsi-block for device passthrough
Am 24.10.2011 17:28, schrieb Paolo Bonzini: On 10/24/2011 05:28 PM, Kevin Wolf wrote: scsi-block is a new device that supports device passthrough of Linux block devices (i.e. /dev/sda, not /dev/sg0). It uses SG_IO for commands other than I/O commands, and regular AIO read/writes for I/O commands. Besides being simpler to configure (no mapping required to scsi-generic device names), this removes the need for a large bounce buffer and, in the future, will get scatter/gather support for free from scsi-disk. Signed-off-by: Paolo Bonzinipbonz...@redhat.com This doesn't seem to use much of scsi-disk, so what about exporting scsi_disk_reqops and adding a separate file scsi-block.c? Would make things a bit more symmetrical between scsi-disk and scsi-generic. Or will future patches add code that depends on internal interfaces of scsi-disk? It already uses some internal interfaces: scsi_initfn, scsi_disk_reset, scsi_destroy, sizeof(SCSIDiskState). Right... I don't like it much in scsi-disk.c, but what can you do. Exporting everything wouldn't be nicer. Kevin
Re: [Qemu-devel] [PATCH 29/35] scsi-disk: remove cluster_size
On 10/24/2011 05:10 PM, Kevin Wolf wrote: -bdrv_get_geometry(s-qdev.conf.bs,nb_sectors); -nb_sectors /= s-cluster_size; -if (nb_sectors) { -nb_sectors--; +if (s-qdev.blocksize) { When would it be 0? And wouldn't we crash with a zero blocksize anyway? blocksize can be zero when passing through a removable medium and no medium has ever been inserted in the disk since the guest was started. In practice it won't crash because the guest will always send READ CAPACITY first, will see a unit attention condition, and will not attempt a read. A more complete solution involves asking raw-posix for the logical block size (right now logical_block_size acts as both the emulated and host block size). This would also be useful to make cache=none work with 4k-sector disks without manually specifying logical_block_size. However, it's not 1.0 material. Paolo
Re: [Qemu-devel] [PATCH 1/5] monitor: screen_dump async
On Mon, 24 Oct 2011 17:13:14 +0200 Gerd Hoffmann kra...@redhat.com wrote: On 10/24/11 14:02, Alon Levy wrote: Make screen_dump monitor command an async command to allow next for qxl to implement it as a initiating call to red_worker and completion on callback, to fix a deadlock when issueing a screendump command via libvirt while connected with a libvirt controlled spice-gtk client. Approach looks reasonable to me. Patch breaks the build though, you've missed a bunch of screen_dump functions in non-x86 targets. There are two problems actually. The first one is that changing an existing command from synchronous to asynchronous is an incompatible change because asynchronous commands semantics is different. For an example of possible problems please check: https://bugzilla.redhat.com/show_bug.cgi?id=623903. The second problem is that the existing asynchronous interface in the monitor is incomplete and has never been used for real. Our plan is to use QAPI's async support, but that has not landed in master yet and iirc there wasn't consensus about it. I also think it's a bit late for its inclusion in 1.0 (and certainly not a candidate for stable). If all you need here is to delay sending the response, then maybe the current interface could work (although I honestly don't trust it and regret not having dropped it). Otherwise our only choice would be to work on getting the QAPI async support merged.
Re: [Qemu-devel] [Question] dump memory when host pci device is used by guest
- Original Message - No, an ELF image of the guest's physical memory. Well then that should be pretty straight forward to support. Depending upon how similar it would be to the standard kdump ELF format, the only other issue is how to determine the physical base address at which the kernel is loaded, in order to be able to translate the mapped kernel-text/static-data virtual region of the x86_64 arch (the __START_KERNEL_map region). I guess an elf note would work for that? Right -- here is an example of a RHEL6 ELF kdump header: $ readelf -a vmcore ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI:UNIX - System V ABI Version: 0 Type: CORE (Core file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 64 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 6 Size of section headers: 0 (bytes) Number of section headers: 0 Section header string table index: 0 There are no sections in this file. There are no sections in this file. Program Headers: Type Offset VirtAddr PhysAddr FileSizMemSiz Flags Align NOTE 0x0190 0x 0x 0x083c 0x083c 0 LOAD 0x09cc 0x8100 0x0100 0x00ba3000 0x00ba3000 RWE0 LOAD 0x00ba39cc 0x8100 0x 0x000a 0x000a RWE0 LOAD 0x00c439cc 0x8110 0x0010 0x01f0 0x01f0 RWE0 LOAD 0x02b439cc 0x81000a00 0x0a00 0xc5fc2840 0xc5fc2840 RWE0 LOAD 0xc8b0620c 0x8101 0x0001 0x3000 0x3000 RWE0 There is no dynamic section in this file. There are no relocations in this file. There are no unwind sections in this file. No version information found in this file. Notes at offset 0x0190 with length 0x083c: Owner Data size Description CORE 0x0150 NT_PRSTATUS (prstatus structure) CORE 0x0150 NT_PRSTATUS (prstatus structure) VMCOREINFO0x055b Unknown note type: (0x) $ In this example, the phys_base (of zero) can be determined by looking at the first PT_LOAD segment, and comparing the PhysAddr and the VirtAddr values -- given that __START_KERNEL_map region is based at 8. The remaining physical memory chunks are described by the subsequent unity-mapped segments. The NT_PRSTATUS notes are register dumps of each cpu, where this vmcore was from a 2-cpu system. But the crash utility is capable of surviving without them. It can also get by without the VMCOREINFO note, which is primarily there for use by the makedumpfile utility, which is used to compress ELF kdumps and filter out unwanted pages, and then make a different dumpfile format entirely. This may be another stupid question -- but does the guest failure mode render it incapable of using kdump? Dave
Re: [Qemu-devel] gcc auto-omit-frame-pointer vs msvc longjmp
2011/10/24 Bob Breuer breu...@mc.net: Kai Tietz wrote: Hi, For trunk-version I have a tentative patch for this issue. On 4.6.x and older branches this doesn't work, as here we can't differenciate that easy between ms- and sysv-abi. But could somebody give this patch a try? Regards, Kai ChangeLog * config/i386/i386.c (ix86_frame_pointer_required): Enforce use of frame-pointer for 32-bit ms-abi, if setjmp is used. Index: i386.c === --- i386.c (revision 180099) +++ i386.c (working copy) @@ -8391,6 +8391,10 @@ if (SUBTARGET_FRAME_POINTER_REQUIRED) return true; + /* For older 32-bit runtimes setjmp requires valid frame-pointer. */ + if (TARGET_32BIT_MS_ABI cfun-calls_setjmp) + return true; + /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER turns off the frame pointer by default. Turn it back on now if we've not got a leaf function. */ For a gcc 4.7 snapshot, this does fix the longjmp problem that I encountered. So aside from specifying -fno-omit-frame-pointer for affected files, what can be done for 4.6? Bob Well, for 4.6.x (or older) we just can use the mingw32.h header in gcc/config/i386/ and define here a subtarget-macro to indicate that. The only incompatible point here might be for Wine using the linux-compiler to build Windows related code. A possible patch for 4.6 gcc versions I attached to this mail. Regards, Kai Index: mingw32.h === --- mingw32.h (revision 180393) +++ mingw32.h (working copy) @@ -239,3 +239,8 @@ /* We should find a way to not have to update this manually. */ #define LIBGCJ_SONAME libgcj /*LIBGCC_EH_EXTN*/ -12.dll +/* For 32-bit Windows we need valid frame-pointer for function using + setjmp. */ +#define SUBTARGET_SETJMP_NEED_FRAME_POINTER \ + (!TARGET_64BIT cfun-calls_setjmp) + Index: i386.c === --- i386.c (revision 180393) +++ i386.c (working copy) @@ -8741,6 +8741,12 @@ if (SUBTARGET_FRAME_POINTER_REQUIRED) return true; +#ifdef SUBTARGET_SETJMP_NEED_FRAME_POINTER + /* For older 32-bit runtimes setjmp requires valid frame-pointer. */ + if (SUBTARGET_SETJMP_NEED_FRAME_POINTER) +return true; +#endif + /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER turns off the frame pointer by default. Turn it back on now if we've not got a leaf function. */
Re: [Qemu-devel] [PULL v3 00/13] allow tools to use the QEMU main loop
On 10/21/2011 11:26 AM, Paolo Bonzini wrote: The following changes since commit c76eaf13975130768070ecd2d4f3107eb69ab757: hw/9pfs: Fix broken compilation caused by wrong trace events (2011-10-20 15:30:59 -0500) are available in the git repository at: git://github.com/bonzini/qemu.git split-main-loop-for-anthony Pulled. Thanks. Regards, Anthony Liguori This patch series makes the QEMU main loop usable out of the executable, and especially in tools and possibly unit tests. This is cleaner because it avoids introducing partial transitions to GIOChannel. Interfacing with the glib main loop is still possible. The main loop code is currently split in cpus.c and vl.c. Moving it to a new file is easy; the problem is that the main loop depends on the timer infrastructure in qemu-timer.c, and that file currently contains the implementation of icount and the vm_clock. This is bad for the perspective of linking qemu-timer.c into the tools. Luckily, it is relatively easy to untie them and move them out of the way. This is what the largest part of the series does (patches 1-9). Patches 10-13 complete the refactoring and cleanup some surrounding code. v2-v3 Rebased, added documentation v1-v2 Rebased Paolo Bonzini (13): remove unused function qemu-timer: remove active_timers array qemu-timer: move common code to qemu_rearm_alarm_timer qemu-timer: more clock functions qemu-timer: move icount to cpus.c qemu-timer: do not refer to runstate_is_running() qemu-timer: use atexit for quit_timers qemu-timer: move more stuff out of qemu-timer.c qemu-timer: do not use RunState change handlers main-loop: create main-loop.h main-loop: create main-loop.c Revert to a hand-made select loop simplify main loop functions Makefile.objs |2 +- async.c |1 + cpus.c| 497 - cpus.h|3 +- exec-all.h| 14 ++ exec.c|3 - hw/mac_dbdma.c|5 - hw/mac_dbdma.h|1 - iohandler.c | 55 +-- main-loop.c | 495 main-loop.h | 351 ++ os-win32.c| 123 qemu-char.h | 12 +- qemu-common.h | 37 + qemu-coroutine-lock.c |1 + qemu-os-posix.h |4 - qemu-os-win32.h | 17 +-- qemu-timer.c | 489 +--- qemu-timer.h | 31 +--- savevm.c | 25 +++ slirp/libslirp.h | 11 - sysemu.h |3 +- vl.c | 189 --- 23 files changed, 1309 insertions(+), 1060 deletions(-) create mode 100644 main-loop.c create mode 100644 main-loop.h
Re: [Qemu-devel] [PULL 00/19] Block patches
On 10/21/2011 12:18 PM, Kevin Wolf wrote: The following changes since commit c2e2343e1faae7bbc77574c12a25881b1b696808: hw/arm_gic.c: Fix save/load of irq_target array (2011-10-21 17:19:56 +0200) are available in the git repository at: git://repo.or.cz/qemu/kevin.git for-anthony Pulled. Thanks. Regards, Anthony Liguori Alex Jia (1): fix memory leak in aio_write_f Kevin Wolf (5): xen_disk: Always set feature-barrier = 1 fdc: Fix floppy port I/O qemu-img: Don't allow preallocation and compression at the same time qcow2: Fix bdrv_write_compressed error handling pc: Fix floppy drives with if=none Paolo Bonzini (12): sheepdog: add coroutine_fn markers add socket_set_block block: rename bdrv_co_rw_bh block: unify flush implementations block: add bdrv_co_discard and bdrv_aio_discard support vmdk: fix return values of vmdk_parent_open vmdk: clean up open block: add a CoMutex to synchronous read drivers block: take lock around bdrv_read implementations block: take lock around bdrv_write implementations block: change flush to co_flush block: change discard to co_discard Stefan Hajnoczi (1): block: drop redundant bdrv_flush implementation block.c | 258 ++--- block.h |5 + block/blkdebug.c |6 - block/blkverify.c |9 -- block/bochs.c | 15 +++- block/cloop.c | 15 +++- block/cow.c | 34 ++- block/dmg.c | 15 +++- block/nbd.c | 28 +- block/parallels.c | 15 +++- block/qcow.c | 17 +--- block/qcow2-cluster.c |6 +- block/qcow2.c | 72 ++ block/qed.c |6 - block/raw-posix.c | 23 + block/raw-win32.c |4 +- block/raw.c | 23 ++--- block/rbd.c |4 +- block/sheepdog.c | 14 ++-- block/vdi.c |6 +- block/vmdk.c | 82 ++-- block/vpc.c | 34 ++- block/vvfat.c | 28 +- block_int.h |9 +- hw/fdc.c | 14 +++ hw/fdc.h |9 ++- hw/pc.c | 25 +++-- hw/pc.h |3 +- hw/pc_piix.c |5 +- hw/xen_disk.c |5 +- oslib-posix.c |7 ++ oslib-win32.c |6 + qemu-img.c| 11 ++ qemu-io.c |1 + qemu_socket.h |1 + trace-events |1 + 36 files changed, 524 insertions(+), 292 deletions(-)
Re: [Qemu-devel] [PATCH v2 2/4] Add access control support to qemu bridge helper
On Mon, Oct 24, 2011 at 13:44, Corey Bryant cor...@linux.vnet.ibm.com wrote: On 10/23/2011 09:10 AM, Blue Swirl wrote: On Fri, Oct 21, 2011 at 15:07, Corey Bryantcor...@linux.vnet.ibm.com wrote: We go to great lengths to restrict ourselves to just cap_net_admin as an OS enforced security mechanism. However, we further restrict what we allow users to do to simply adding a tap device to a bridge interface by virtue of the fact that this is the only functionality we expose. This is not good enough though. An administrator is likely to want to restrict the bridges that an unprivileged user can access, in particular, to restrict an unprivileged user from putting a guest on what should be isolated networks. This patch implements an ACL mechanism that is enforced by qemu-bridge-helper. The ACLs are fairly simple whitelist/blacklist mechanisms with a wildcard of 'all'. All users are blacklisted by default, and deny takes precedence over allow. An interesting feature of this ACL mechanism is that you can include external ACL files. The main reason to support this is so that you can set different file system permissions on those external ACL files. This allows an administrator to implement rather sophisicated ACL policies based on user/group sophisticated Yep, thanks. policies via the file system. As an example: /etc/qemu/bridge.conf root:qemu 0640 allow br0 include /etc/qemu/alice.conf include /etc/qemu/bob.conf include /etc/qemu/charlie.conf /etc/qemu/alice.conf root:alice 0640 allow br1 /etc/qemu/bob.conf root:bob 0640 allow br2 /etc/qemu/charlie.conf root:charlie 0640 deny all I think syntax 'include/etc/qemu/user.d/*.conf' or 'includedir /etc/qemu/user.d' could be also useful. That could be useful, though I'm not sure it's necessary right now. It can be added later. This ACL pattern allows any user in the qemu group to get a tap device connected to br0 (which is bridged to the physical network). Users in the alice group can additionally get a tap device connected to br1. This allows br1 to act as a private bridge for the alice group. Users in the bob group can additionally get a tap device connected to br2. This allows br2 to act as a private bridge for the bob group. Users in the charlie group cannot get a tap device connected to any bridge. Under no circumstance can the bob group get access to br1 or can the alice group get access to br2. And under no cicumstance can the charlie group get access to any bridge. Signed-off-by: Anthony Liguorialigu...@us.ibm.com Signed-off-by: Richa Marwaharmar...@linux.vnet.ibm.com Signed-off-by: Corey Bryantcor...@linux.vnet.ibm.com --- qemu-bridge-helper.c | 141 ++ 1 files changed, 141 insertions(+), 0 deletions(-) diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c index 2ce82fb..db257d5 100644 --- a/qemu-bridge-helper.c +++ b/qemu-bridge-helper.c @@ -33,6 +33,105 @@ #include net/tap-linux.h +#define MAX_ACLS (128) If all users (or groups) in the system have an ACL, this number could be way too low. Please use a list instead. I agree, we shouldn't be hard-coding the limit here. I'll update this. +#define DEFAULT_ACL_FILE CONFIG_QEMU_CONFDIR /bridge.conf + +enum { + ACL_ALLOW = 0, + ACL_ALLOW_ALL, + ACL_DENY, + ACL_DENY_ALL, +}; + +typedef struct ACLRule { + int type; + char iface[IFNAMSIZ]; +} ACLRule; + +static int parse_acl_file(const char *filename, ACLRule *acls, int *pacl_count) +{ + int acl_count = *pacl_count; + FILE *f; + char line[4096]; + + f = fopen(filename, r); + if (f == NULL) { + return -1; + } + + while (acl_count != MAX_ACLS + fgets(line, sizeof(line), f) != NULL) { + char *ptr = line; + char *cmd, *arg, *argend; + + while (isspace(*ptr)) { + ptr++; + } + + /* skip comments and empty lines */ + if (*ptr == '#' || *ptr == 0) { + continue; + } + + cmd = ptr; + arg = strchr(cmd, ' '); + if (arg == NULL) { + arg = strchr(cmd, '\t'); + } + + if (arg == NULL) { + fprintf(stderr, Invalid config line:\n %s\n, line); + fclose(f); + errno = EINVAL; + return -1; + } + + *arg = 0; + arg++; + while (isspace(*arg)) { + arg++; + } + + argend = arg + strlen(arg); + while (arg != argend isspace(*(argend - 1))) { + argend--; + } These while loops to skip spaces are
Re: [Qemu-devel] [PATCH v2 3/4] Add cap reduction support to enable use as SUID
On Mon, Oct 24, 2011 at 14:13, Corey Bryant cor...@linux.vnet.ibm.com wrote: On 10/23/2011 09:22 AM, Blue Swirl wrote: On Fri, Oct 21, 2011 at 15:07, Corey Bryantcor...@linux.vnet.ibm.com wrote: The ideal way to use qemu-bridge-helper is to give it an fscap of using: setcap cap_net_admin=ep qemu-bridge-helper Unfortunately, most distros still do not have a mechanism to package files with fscaps applied. This means they'll have to SUID the qemu-bridge-helper binary. To improve security, use libcap to reduce our capability set to just cap_net_admin, then reduce privileges down to the calling user. This is hopefully close to equivalent to fscap support from a security perspective. Signed-off-by: Anthony Liguorialigu...@us.ibm.com Signed-off-by: Richa Marwaharmar...@linux.vnet.ibm.com Signed-off-by: Corey Bryantcor...@linux.vnet.ibm.com --- configure | 34 ++ qemu-bridge-helper.c | 39 +++ 2 files changed, 73 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 6c8b659..fed66b0 100755 --- a/configure +++ b/configure @@ -128,6 +128,7 @@ vnc_thread=no xen= xen_ctrl_version= linux_aio= +cap= attr= xfs= @@ -653,6 +654,10 @@ for opt do ;; --enable-kvm) kvm=yes ;; + --disable-cap) cap=no + ;; + --enable-cap) cap=yes + ;; --disable-spice) spice=no ;; --enable-spice) spice=yes @@ -1032,6 +1037,8 @@ echo --disable-vde disable support for vde network echo --enable-vde enable support for vde network echo --disable-linux-aio disable Linux AIO support echo --enable-linux-aio enable Linux AIO support +echo --disable-cap disable libcap-ng support +echo --enable-cap enable libcap-ng support echo --disable-attr disables attr and xattr support echo --enable-attr enable attr and xattr support echo --disable-blobs disable installing provided firmware blobs @@ -1638,6 +1645,29 @@ EOF fi ## +# libcap-ng library probe +if test $cap != no ; then + cap_libs=-lcap-ng + cat $TMPC EOF +#includecap-ng.h +int main(void) +{ + capng_capability_to_name(CAPNG_EFFECTIVE); + return 0; +} +EOF + if compile_prog $cap_libs ; then + cap=yes + libs_tools=$cap_libs $libs_tools + else + if test $cap = yes ; then + feature_not_found cap + fi + cap=no + fi +fi + +## # Sound support libraries probe audio_drv_probe() @@ -2735,6 +2765,7 @@ echo fdatasync $fdatasync echo madvise $madvise echo posix_madvise $posix_madvise echo uuid support $uuid +echo libcap-ng support $cap echo vhost-net support $vhost_net echo Trace backend $trace_backend echo Trace output file $trace_file-pid @@ -2846,6 +2877,9 @@ fi if test $vde = yes ; then echo CONFIG_VDE=y $config_host_mak fi +if test $cap = yes ; then + echo CONFIG_LIBCAP=y $config_host_mak +fi for card in $audio_card_list; do def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'` echo $def=y $config_host_mak diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c index db257d5..b1562eb 100644 --- a/qemu-bridge-helper.c +++ b/qemu-bridge-helper.c @@ -33,6 +33,10 @@ #include net/tap-linux.h +#ifdef CONFIG_LIBCAP +#includecap-ng.h +#endif + #define MAX_ACLS (128) #define DEFAULT_ACL_FILE CONFIG_QEMU_CONFDIR /bridge.conf @@ -185,6 +189,27 @@ static int send_fd(int c, int fd) return sendmsg(c,msg, 0); } +#ifdef CONFIG_LIBCAP +static int drop_privileges(void) +{ + /* clear all capabilities */ + capng_clear(CAPNG_SELECT_BOTH); + + if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, + CAP_NET_ADMIN) 0) { + return -1; + } + + /* change to calling user's real uid and gid, retaining supplemental + * groups and CAP_NET_ADMIN */ + if (capng_change_id(getuid(), getgid(), CAPNG_CLEAR_BOUNDING)) { + return -1; + } + + return 0; +} +#endif + int main(int argc, char **argv) { struct ifreq ifr; @@ -198,6 +223,20 @@ int main(int argc, char **argv) int acl_count = 0; int i, access_allowed, access_denied; + /* if we're run from an suid binary, immediately drop privileges preserving + * cap_net_admin -- exit immediately if libcap not configured */ + if (geteuid() == 0 getuid() != geteuid()) { +#ifdef CONFIG_LIBCAP + if (drop_privileges() == -1) { + fprintf(stderr, failed to drop privileges\n); + return 1; + } +#else + fprintf(stderr, failed to drop privileges\n); This makes the tool useless without CONFIG_LIBCAP. Wouldn't it be possible to use setfsuid() instead for Linux? Some fork+setuid helper could be used for
Re: [Qemu-devel] [Qemu-ppc] [PATCH] pseries: Correct vmx/dfp handling in both KVM and TCG cases
On 23.10.2011, at 22:29, David Gibson wrote: On Thu, Oct 20, 2011 at 11:49:40PM -0700, Alexander Graf wrote: On 20.10.2011, at 22:06, David Gibson wrote: On Thu, Oct 20, 2011 at 07:40:00PM -0700, Alexander Graf wrote: On 20.10.2011, at 17:41, David Gibson da...@gibson.dropbear.id.au wrote: On Thu, Oct 20, 2011 at 10:12:51AM -0700, Alexander Graf wrote: On 17.10.2011, at 21:15, David Gibson wrote: [snip] So, I really don't follow what the logic you want is. It sounds more like what I have already, so I'm not sure how -cpu host comes into this. Well, I want something very simple, layered: -cpu host only searches for pvr matches and selects a different CPU -type based on this Hrm, ok, well I can do this if you like, but note that this is quite different from how -cpu host behaves on x86. There it builds the CPU spec from scratch based on querying the host cpuid, rather than selecting from an existing list of cpus. I selected from the existing table based on host PVR because that was the easiest source for some of the info in the cpu_spec, but my intention was that anything we _can_ query directly from the host would override the table. It seems to be your approach is giving up on the possibility of allowing -cpu host to work (and give you full access to the host features) when qemu doesn't recognize the precise PVR of the host cpu. I disagree :). This is what x86 does: * -cpu host fetches CPUID info from host, puts it into vcpu * vcpu CPUID info gets ANDed with KVM capability CPUIDs I want basically the same thing. I want to have 2 different layers for 2 different semantics. One for what the host CPU would be able to do and one for what we can emulate, and two different steps to ensure control over them. The thing I think I'm apparently not bringing over yet is that I'm more than happy to get rid of the PVR searching step for -cpu host and instead use a full host capability inquiry mechanism. But that inquiry should indicate what the host CPU can do. It has nothing to do with KVM yet. The masking with KVM capabilities should be the next separate step. My goal is really to separate different layers into actual different layers :). Hrm. I think I see what you're getting at. Although nothing in that patch is about kvm capabilities - it's all about working out what the host's cpu can do. Reading through the patch again I think I see your point now :). Yes, the kvmppc_host_cpu_def function only tries to fetch the host CPU capabilities. So yes, there is basically only the masking part with what we can actually virtualize missing. But for now we can just assume that every feature the host CPU supports is available. I'll apply your patch for now, as it certainly is better than what we had before. This gets further complicated in the case of the w-i-p patch I have to properly advertise page sizes, where it's not just presence or absence of a feature, but the specific SLB and HPTE encodings must be advertised to the guest. Yup, so we'd read out the host dt to find the host possible encodings (probably a bad idea, but that's a different story) Um, a different story perhaps, but one I kind of need an answer to in the near future... I can query the host cpu's page sizes easily enough, but I'm really not sure where this should be stashed before filtering as suggested below. Page sizes are usually powers of 2, so we should be ok with just having a bitmap there with each bit meaning 1 (n + 12). Alex
Re: [Qemu-devel] [PATCH 1/5] monitor: screen_dump async
On Mon, Oct 24, 2011 at 01:45:16PM -0200, Luiz Capitulino wrote: On Mon, 24 Oct 2011 17:13:14 +0200 Gerd Hoffmann kra...@redhat.com wrote: On 10/24/11 14:02, Alon Levy wrote: Make screen_dump monitor command an async command to allow next for qxl to implement it as a initiating call to red_worker and completion on callback, to fix a deadlock when issueing a screendump command via libvirt while connected with a libvirt controlled spice-gtk client. Approach looks reasonable to me. Patch breaks the build though, you've missed a bunch of screen_dump functions in non-x86 targets. There are two problems actually. The first one is that changing an existing command from synchronous to asynchronous is an incompatible change because asynchronous commands semantics is different. For an example of possible problems please check: https://bugzilla.redhat.com/show_bug.cgi?id=623903. The second problem is that the existing asynchronous interface in the monitor is incomplete and has never been used for real. Our plan is to use QAPI's async support, but that has not landed in master yet and iirc there wasn't consensus about it. I also think it's a bit late for its inclusion in 1.0 (and certainly not a candidate for stable). If all you need here is to delay sending the response, then maybe the current interface could work (although I honestly don't trust it and regret not having dropped it). Otherwise our only choice would be to work on getting the QAPI async support merged. My problem is that the io thread keeps the global mutex during the wait, that's why the async monitor is perfect for what I want - this is exactly what it does. I haven't looked at QAPI async support, but I understand it's a bit in the future.
Re: [Qemu-devel] [PATCH 5/5] qxl: support async monitor screen dump
On Mon, Oct 24, 2011 at 05:29:47PM +0200, Gerd Hoffmann wrote: On 10/24/11 14:02, Alon Levy wrote: Split qxl_spice_update_area_complete from qxl_render_update, use SPICE_INTERFACE_QXL_MINOR 2 introduced spice_qxl_update_area_dirty_async to retrive the dirty rectangles asyncronously (the previous spice_qxl_update_area_async did not accept a dirty rectangles array). Introduce SpiceAsyncMonitorScreenDump for a screen_dump. That one conflicts with the screendump/SDL fixes pushed to the spice.v44 branch. Have you seen the mail? Had you time to look at the patches? Yes and no. I will. cheers, Gerd
Re: [Qemu-devel] [Qemu-ppc] [PATCH] pseries: Correct vmx/dfp handling in both KVM and TCG cases
On 24.10.2011, at 10:25, Alexander Graf wrote: On 23.10.2011, at 22:29, David Gibson wrote: On Thu, Oct 20, 2011 at 11:49:40PM -0700, Alexander Graf wrote: On 20.10.2011, at 22:06, David Gibson wrote: On Thu, Oct 20, 2011 at 07:40:00PM -0700, Alexander Graf wrote: On 20.10.2011, at 17:41, David Gibson da...@gibson.dropbear.id.au wrote: On Thu, Oct 20, 2011 at 10:12:51AM -0700, Alexander Graf wrote: On 17.10.2011, at 21:15, David Gibson wrote: [snip] So, I really don't follow what the logic you want is. It sounds more like what I have already, so I'm not sure how -cpu host comes into this. Well, I want something very simple, layered: -cpu host only searches for pvr matches and selects a different CPU -type based on this Hrm, ok, well I can do this if you like, but note that this is quite different from how -cpu host behaves on x86. There it builds the CPU spec from scratch based on querying the host cpuid, rather than selecting from an existing list of cpus. I selected from the existing table based on host PVR because that was the easiest source for some of the info in the cpu_spec, but my intention was that anything we _can_ query directly from the host would override the table. It seems to be your approach is giving up on the possibility of allowing -cpu host to work (and give you full access to the host features) when qemu doesn't recognize the precise PVR of the host cpu. I disagree :). This is what x86 does: * -cpu host fetches CPUID info from host, puts it into vcpu * vcpu CPUID info gets ANDed with KVM capability CPUIDs I want basically the same thing. I want to have 2 different layers for 2 different semantics. One for what the host CPU would be able to do and one for what we can emulate, and two different steps to ensure control over them. The thing I think I'm apparently not bringing over yet is that I'm more than happy to get rid of the PVR searching step for -cpu host and instead use a full host capability inquiry mechanism. But that inquiry should indicate what the host CPU can do. It has nothing to do with KVM yet. The masking with KVM capabilities should be the next separate step. My goal is really to separate different layers into actual different layers :). Hrm. I think I see what you're getting at. Although nothing in that patch is about kvm capabilities - it's all about working out what the host's cpu can do. Reading through the patch again I think I see your point now :). Yes, the kvmppc_host_cpu_def function only tries to fetch the host CPU capabilities. So yes, there is basically only the masking part with what we can actually virtualize missing. But for now we can just assume that every feature the host CPU supports is available. I'll apply your patch for now, as it certainly is better than what we had before. This breaks on 970mp (PowerStation). kvmppc_get_vmx returns -1 because ibm,vmx doesn't exist in the host dt, but the CPU still supports Altivec. Any alternative way to enumerate VMX availability? Alex