| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QEMU System Emulator | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2003-2008 Fabrice Bellard | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-29 17:50:00 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:08 +02:00
										 |  |  | #include "qemu-common.h"
 | 
					
						
							| 
									
										
										
										
											2012-09-17 18:43:51 +02:00
										 |  |  | #include "clients.h"
 | 
					
						
							| 
									
										
											  
											
												include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef.  Since then, we've moved to include qemu/osdep.h
everywhere.  Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h.  That's in excess of
100KiB of crap most .c files don't actually need.
Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h.  Include qapi/error.h in .c files that need it and don't
get it now.  Include qapi-types.h in qom/object.h for uint16List.
Update scripts/clean-includes accordingly.  Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h.  Update the list of includes in the qemu/osdep.h
comment quoted above similarly.
This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third.  Unfortunately, the number depending on
qapi-types.h shrinks only a little.  More work is needed for that one.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
											
										 
											2016-03-14 09:01:28 +01:00
										 |  |  | #include "qapi/error.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:00 +01:00
										 |  |  | #include "qemu/error-report.h"
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:39:58 +02:00
										 |  |  | #include "qemu/iov.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:00 +01:00
										 |  |  | #include "qemu/timer.h"
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  | #include "qapi/visitor.h"
 | 
					
						
							|  |  |  | #include "net/filter.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct DumpState { | 
					
						
							| 
									
										
										
										
											2011-11-30 21:35:38 +01:00
										 |  |  |     int64_t start_ts; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |     int fd; | 
					
						
							|  |  |  |     int pcap_caplen; | 
					
						
							|  |  |  | } DumpState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PCAP_MAGIC 0xa1b2c3d4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct pcap_file_hdr { | 
					
						
							|  |  |  |     uint32_t magic; | 
					
						
							|  |  |  |     uint16_t version_major; | 
					
						
							|  |  |  |     uint16_t version_minor; | 
					
						
							|  |  |  |     int32_t thiszone; | 
					
						
							|  |  |  |     uint32_t sigfigs; | 
					
						
							|  |  |  |     uint32_t snaplen; | 
					
						
							|  |  |  |     uint32_t linktype; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct pcap_sf_pkthdr { | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |         int32_t tv_sec; | 
					
						
							|  |  |  |         int32_t tv_usec; | 
					
						
							|  |  |  |     } ts; | 
					
						
							|  |  |  |     uint32_t caplen; | 
					
						
							|  |  |  |     uint32_t len; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:00 +02:00
										 |  |  | static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt) | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct pcap_sf_pkthdr hdr; | 
					
						
							|  |  |  |     int64_t ts; | 
					
						
							|  |  |  |     int caplen; | 
					
						
							| 
									
										
										
										
											2015-10-13 12:39:58 +02:00
										 |  |  |     size_t size = iov_size(iov, cnt); | 
					
						
							|  |  |  |     struct iovec dumpiov[cnt + 1]; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Early return in case of previous error. */ | 
					
						
							|  |  |  |     if (s->fd < 0) { | 
					
						
							|  |  |  |         return size; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 17:24:39 +02:00
										 |  |  |     ts = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL); | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |     caplen = size > s->pcap_caplen ? s->pcap_caplen : size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-30 21:35:38 +01:00
										 |  |  |     hdr.ts.tv_sec = ts / 1000000 + s->start_ts; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |     hdr.ts.tv_usec = ts % 1000000; | 
					
						
							|  |  |  |     hdr.caplen = caplen; | 
					
						
							|  |  |  |     hdr.len = size; | 
					
						
							| 
									
										
										
										
											2015-10-13 12:39:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     dumpiov[0].iov_base = &hdr; | 
					
						
							|  |  |  |     dumpiov[0].iov_len = sizeof(hdr); | 
					
						
							|  |  |  |     cnt = iov_copy(&dumpiov[1], cnt, iov, cnt, 0, caplen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (writev(s->fd, dumpiov, cnt + 1) != sizeof(hdr) + caplen) { | 
					
						
							| 
									
										
										
										
											2015-12-04 13:38:46 +01:00
										 |  |  |         error_report("network dump write error - stopping dump"); | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |         close(s->fd); | 
					
						
							|  |  |  |         s->fd = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:00 +02:00
										 |  |  | static void dump_cleanup(DumpState *s) | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     close(s->fd); | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:00 +02:00
										 |  |  |     s->fd = -1; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:39:59 +02:00
										 |  |  | static int net_dump_state_init(DumpState *s, const char *filename, | 
					
						
							|  |  |  |                                int len, Error **errp) | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct pcap_file_hdr hdr; | 
					
						
							| 
									
										
										
										
											2011-11-30 21:35:38 +01:00
										 |  |  |     struct tm tm; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:49:09 +00:00
										 |  |  |     int fd; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-30 21:35:37 +01:00
										 |  |  |     fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644); | 
					
						
							| 
									
										
										
										
											2009-11-25 18:49:09 +00:00
										 |  |  |     if (fd < 0) { | 
					
						
							| 
									
										
										
										
											2018-02-21 11:18:34 +01:00
										 |  |  |         error_setg_errno(errp, errno, "net dump: can't open %s", filename); | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hdr.magic = PCAP_MAGIC; | 
					
						
							|  |  |  |     hdr.version_major = 2; | 
					
						
							|  |  |  |     hdr.version_minor = 4; | 
					
						
							|  |  |  |     hdr.thiszone = 0; | 
					
						
							|  |  |  |     hdr.sigfigs = 0; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:49:09 +00:00
										 |  |  |     hdr.snaplen = len; | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |     hdr.linktype = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-25 18:49:09 +00:00
										 |  |  |     if (write(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) { | 
					
						
							| 
									
										
										
										
											2018-02-21 11:18:34 +01:00
										 |  |  |         error_setg_errno(errp, errno, "net dump write error"); | 
					
						
							| 
									
										
										
										
											2009-11-25 18:49:09 +00:00
										 |  |  |         close(fd); | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-25 18:49:09 +00:00
										 |  |  |     s->fd = fd; | 
					
						
							|  |  |  |     s->pcap_caplen = len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-30 21:35:38 +01:00
										 |  |  |     qemu_get_timedate(&tm, 0); | 
					
						
							|  |  |  |     s->start_ts = mktime(&tm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-25 18:48:57 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  | #define TYPE_FILTER_DUMP "filter-dump"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(NetFilterDumpState, FILTER_DUMP) | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct NetFilterDumpState { | 
					
						
							|  |  |  |     NetFilterState nfs; | 
					
						
							|  |  |  |     DumpState ds; | 
					
						
							|  |  |  |     char *filename; | 
					
						
							|  |  |  |     uint32_t maxlen; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static ssize_t filter_dump_receive_iov(NetFilterState *nf, NetClientState *sndr, | 
					
						
							|  |  |  |                                        unsigned flags, const struct iovec *iov, | 
					
						
							|  |  |  |                                        int iovcnt, NetPacketSent *sent_cb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(nf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dump_receive_iov(&nfds->ds, iov, iovcnt); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void filter_dump_cleanup(NetFilterState *nf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(nf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dump_cleanup(&nfds->ds); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void filter_dump_setup(NetFilterState *nf, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(nf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!nfds->filename) { | 
					
						
							|  |  |  |         error_setg(errp, "dump filter needs 'file' property set!"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     net_dump_state_init(&nfds->ds, nfds->filename, nfds->maxlen, errp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												qom: Swap 'name' next to visitor in ObjectPropertyAccessor
Similar to the previous patch, it's nice to have all functions
in the tree that involve a visitor and a name for conversion to
or from QAPI to consistently stick the 'name' parameter next
to the Visitor parameter.
Done by manually changing include/qom/object.h and qom/object.c,
then running this Coccinelle script and touching up the fallout
(Coccinelle insisted on adding some trailing whitespace).
    @ rule1 @
    identifier fn;
    typedef Object, Visitor, Error;
    identifier obj, v, opaque, name, errp;
    @@
     void fn
    - (Object *obj, Visitor *v, void *opaque, const char *name,
    + (Object *obj, Visitor *v, const char *name, void *opaque,
       Error **errp) { ... }
    @@
    identifier rule1.fn;
    expression obj, v, opaque, name, errp;
    @@
     fn(obj, v,
    -   opaque, name,
    +   name, opaque,
        errp)
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <1454075341-13658-20-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
											
										 
											2016-01-29 06:48:55 -07:00
										 |  |  | static void filter_dump_get_maxlen(Object *obj, Visitor *v, const char *name, | 
					
						
							|  |  |  |                                    void *opaque, Error **errp) | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(obj); | 
					
						
							|  |  |  |     uint32_t value = nfds->maxlen; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												qapi: Swap visit_* arguments for consistent 'name' placement
JSON uses "name":value, but many of our visitor interfaces were
called with visit_type_FOO(v, &value, name, errp).  This can be
a bit confusing to have to mentally swap the parameter order to
match JSON order.  It's particularly bad for visit_start_struct(),
where the 'name' parameter is smack in the middle of the
otherwise-related group of 'obj, kind, size' parameters! It's
time to do a global swap of the parameter ordering, so that the
'name' parameter is always immediately after the Visitor argument.
Additional reason in favor of the swap: the existing include/qjson.h
prefers listing 'name' first in json_prop_*(), and I have plans to
unify that file with the qapi visitors; listing 'name' first in
qapi will minimize churn to the (admittedly few) qjson.h clients.
Later patches will then fix docs, object.h, visitor-impl.h, and
those clients to match.
Done by first patching scripts/qapi*.py by hand to make generated
files do what I want, then by running the following Coccinelle
script to affect the rest of the code base:
 $ spatch --sp-file script `git grep -l '\bvisit_' -- '**/*.[ch]'`
I then had to apply some touchups (Coccinelle insisted on TAB
indentation in visitor.h, and botched the signature of
visit_type_enum() by rewriting 'const char *const strings[]' to
the syntactically invalid 'const char*const[] strings').  The
movement of parameters is sufficient to provoke compiler errors
if any callers were missed.
    // Part 1: Swap declaration order
    @@
    type TV, TErr, TObj, T1, T2;
    identifier OBJ, ARG1, ARG2;
    @@
     void visit_start_struct
    -(TV v, TObj OBJ, T1 ARG1, const char *name, T2 ARG2, TErr errp)
    +(TV v, const char *name, TObj OBJ, T1 ARG1, T2 ARG2, TErr errp)
     { ... }
    @@
    type bool, TV, T1;
    identifier ARG1;
    @@
     bool visit_optional
    -(TV v, T1 ARG1, const char *name)
    +(TV v, const char *name, T1 ARG1)
     { ... }
    @@
    type TV, TErr, TObj, T1;
    identifier OBJ, ARG1;
    @@
     void visit_get_next_type
    -(TV v, TObj OBJ, T1 ARG1, const char *name, TErr errp)
    +(TV v, const char *name, TObj OBJ, T1 ARG1, TErr errp)
     { ... }
    @@
    type TV, TErr, TObj, T1, T2;
    identifier OBJ, ARG1, ARG2;
    @@
     void visit_type_enum
    -(TV v, TObj OBJ, T1 ARG1, T2 ARG2, const char *name, TErr errp)
    +(TV v, const char *name, TObj OBJ, T1 ARG1, T2 ARG2, TErr errp)
     { ... }
    @@
    type TV, TErr, TObj;
    identifier OBJ;
    identifier VISIT_TYPE =~ "^visit_type_";
    @@
     void VISIT_TYPE
    -(TV v, TObj OBJ, const char *name, TErr errp)
    +(TV v, const char *name, TObj OBJ, TErr errp)
     { ... }
    // Part 2: swap caller order
    @@
    expression V, NAME, OBJ, ARG1, ARG2, ERR;
    identifier VISIT_TYPE =~ "^visit_type_";
    @@
    (
    -visit_start_struct(V, OBJ, ARG1, NAME, ARG2, ERR)
    +visit_start_struct(V, NAME, OBJ, ARG1, ARG2, ERR)
    |
    -visit_optional(V, ARG1, NAME)
    +visit_optional(V, NAME, ARG1)
    |
    -visit_get_next_type(V, OBJ, ARG1, NAME, ERR)
    +visit_get_next_type(V, NAME, OBJ, ARG1, ERR)
    |
    -visit_type_enum(V, OBJ, ARG1, ARG2, NAME, ERR)
    +visit_type_enum(V, NAME, OBJ, ARG1, ARG2, ERR)
    |
    -VISIT_TYPE(V, OBJ, NAME, ERR)
    +VISIT_TYPE(V, NAME, OBJ, ERR)
    )
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <1454075341-13658-19-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
											
										 
											2016-01-29 06:48:54 -07:00
										 |  |  |     visit_type_uint32(v, name, &value, errp); | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												qom: Swap 'name' next to visitor in ObjectPropertyAccessor
Similar to the previous patch, it's nice to have all functions
in the tree that involve a visitor and a name for conversion to
or from QAPI to consistently stick the 'name' parameter next
to the Visitor parameter.
Done by manually changing include/qom/object.h and qom/object.c,
then running this Coccinelle script and touching up the fallout
(Coccinelle insisted on adding some trailing whitespace).
    @ rule1 @
    identifier fn;
    typedef Object, Visitor, Error;
    identifier obj, v, opaque, name, errp;
    @@
     void fn
    - (Object *obj, Visitor *v, void *opaque, const char *name,
    + (Object *obj, Visitor *v, const char *name, void *opaque,
       Error **errp) { ... }
    @@
    identifier rule1.fn;
    expression obj, v, opaque, name, errp;
    @@
     fn(obj, v,
    -   opaque, name,
    +   name, opaque,
        errp)
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <1454075341-13658-20-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
											
										 
											2016-01-29 06:48:55 -07:00
										 |  |  | static void filter_dump_set_maxlen(Object *obj, Visitor *v, const char *name, | 
					
						
							|  |  |  |                                    void *opaque, Error **errp) | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(obj); | 
					
						
							|  |  |  |     uint32_t value; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												error: Eliminate error_propagate() with Coccinelle, part 1
When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away.  Convert
    if (!foo(..., &err)) {
        ...
        error_propagate(errp, err);
        ...
        return ...
    }
to
    if (!foo(..., errp)) {
        ...
        ...
        return ...
    }
where nothing else needs @err.  Coccinelle script:
    @rule1 forall@
    identifier fun, err, errp, lbl;
    expression list args, args2;
    binary operator op;
    constant c1, c2;
    symbol false;
    @@
         if (
    (
    -        fun(args, &err, args2)
    +        fun(args, errp, args2)
    |
    -        !fun(args, &err, args2)
    +        !fun(args, errp, args2)
    |
    -        fun(args, &err, args2) op c1
    +        fun(args, errp, args2) op c1
    )
            )
         {
             ... when != err
                 when != lbl:
                 when strict
    -        error_propagate(errp, err);
             ... when != err
    (
             return;
    |
             return c2;
    |
             return false;
    )
         }
    @rule2 forall@
    identifier fun, err, errp, lbl;
    expression list args, args2;
    expression var;
    binary operator op;
    constant c1, c2;
    symbol false;
    @@
    -    var = fun(args, &err, args2);
    +    var = fun(args, errp, args2);
         ... when != err
         if (
    (
             var
    |
             !var
    |
             var op c1
    )
            )
         {
             ... when != err
                 when != lbl:
                 when strict
    -        error_propagate(errp, err);
             ... when != err
    (
             return;
    |
             return c2;
    |
             return false;
    |
             return var;
    )
         }
    @depends on rule1 || rule2@
    identifier err;
    @@
    -    Error *err = NULL;
         ... when != err
Not exactly elegant, I'm afraid.
The "when != lbl:" is necessary to avoid transforming
         if (fun(args, &err)) {
             goto out
         }
         ...
     out:
         error_propagate(errp, err);
even though other paths to label out still need the error_propagate().
For an actual example, see sclp_realize().
Without the "when strict", Coccinelle transforms vfio_msix_setup(),
incorrectly.  I don't know what exactly "when strict" does, only that
it helps here.
The match of return is narrower than what I want, but I can't figure
out how to express "return where the operand doesn't use @err".  For
an example where it's too narrow, see vfio_intx_enable().
Silently fails to convert hw/arm/armsse.c, because Coccinelle gets
confused by ARMSSE being used both as typedef and function-like macro
there.  Converted manually.
Line breaks tidied up manually.  One nested declaration of @local_err
deleted manually.  Preexisting unwanted blank line dropped in
hw/riscv/sifive_e.c.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200707160613.848843-35-armbru@redhat.com>
											
										 
											2020-07-07 18:06:02 +02:00
										 |  |  |     if (!visit_type_uint32(v, name, &value, errp)) { | 
					
						
							| 
									
										
											  
											
												error: Avoid unnecessary error_propagate() after error_setg()
Replace
    error_setg(&err, ...);
    error_propagate(errp, err);
by
    error_setg(errp, ...);
Related pattern:
    if (...) {
        error_setg(&err, ...);
        goto out;
    }
    ...
 out:
    error_propagate(errp, err);
    return;
When all paths to label out are that way, replace by
    if (...) {
        error_setg(errp, ...);
        return;
    }
and delete the label along with the error_propagate().
When we have at most one other path that actually needs to propagate,
and maybe one at the end that where propagation is unnecessary, e.g.
    foo(..., &err);
    if (err) {
        goto out;
    }
    ...
    bar(..., &err);
 out:
    error_propagate(errp, err);
    return;
move the error_propagate() to where it's needed, like
    if (...) {
        foo(..., &err);
        error_propagate(errp, err);
        return;
    }
    ...
    bar(..., errp);
    return;
and transform the error_setg() as above.
In some places, the transformation results in obviously unnecessary
error_propagate().  The next few commits will eliminate them.
Bonus: the elimination of gotos will make later patches in this series
easier to review.
Candidates for conversion tracked down with this Coccinelle script:
    @@
    identifier err, errp;
    expression list args;
    @@
    -    error_setg(&err, args);
    +    error_setg(errp, args);
         ... when != err
         error_propagate(errp, err);
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200707160613.848843-34-armbru@redhat.com>
											
										 
											2020-07-07 18:06:01 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (value == 0) { | 
					
						
							| 
									
										
											  
											
												error: Avoid unnecessary error_propagate() after error_setg()
Replace
    error_setg(&err, ...);
    error_propagate(errp, err);
by
    error_setg(errp, ...);
Related pattern:
    if (...) {
        error_setg(&err, ...);
        goto out;
    }
    ...
 out:
    error_propagate(errp, err);
    return;
When all paths to label out are that way, replace by
    if (...) {
        error_setg(errp, ...);
        return;
    }
and delete the label along with the error_propagate().
When we have at most one other path that actually needs to propagate,
and maybe one at the end that where propagation is unnecessary, e.g.
    foo(..., &err);
    if (err) {
        goto out;
    }
    ...
    bar(..., &err);
 out:
    error_propagate(errp, err);
    return;
move the error_propagate() to where it's needed, like
    if (...) {
        foo(..., &err);
        error_propagate(errp, err);
        return;
    }
    ...
    bar(..., errp);
    return;
and transform the error_setg() as above.
In some places, the transformation results in obviously unnecessary
error_propagate().  The next few commits will eliminate them.
Bonus: the elimination of gotos will make later patches in this series
easier to review.
Candidates for conversion tracked down with this Coccinelle script:
    @@
    identifier err, errp;
    expression list args;
    @@
    -    error_setg(&err, args);
    +    error_setg(errp, args);
         ... when != err
         error_propagate(errp, err);
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200707160613.848843-34-armbru@redhat.com>
											
										 
											2020-07-07 18:06:01 +02:00
										 |  |  |         error_setg(errp, "Property '%s.%s' doesn't take value '%u'", | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  |                    object_get_typename(obj), name, value); | 
					
						
							| 
									
										
											  
											
												error: Avoid unnecessary error_propagate() after error_setg()
Replace
    error_setg(&err, ...);
    error_propagate(errp, err);
by
    error_setg(errp, ...);
Related pattern:
    if (...) {
        error_setg(&err, ...);
        goto out;
    }
    ...
 out:
    error_propagate(errp, err);
    return;
When all paths to label out are that way, replace by
    if (...) {
        error_setg(errp, ...);
        return;
    }
and delete the label along with the error_propagate().
When we have at most one other path that actually needs to propagate,
and maybe one at the end that where propagation is unnecessary, e.g.
    foo(..., &err);
    if (err) {
        goto out;
    }
    ...
    bar(..., &err);
 out:
    error_propagate(errp, err);
    return;
move the error_propagate() to where it's needed, like
    if (...) {
        foo(..., &err);
        error_propagate(errp, err);
        return;
    }
    ...
    bar(..., errp);
    return;
and transform the error_setg() as above.
In some places, the transformation results in obviously unnecessary
error_propagate().  The next few commits will eliminate them.
Bonus: the elimination of gotos will make later patches in this series
easier to review.
Candidates for conversion tracked down with this Coccinelle script:
    @@
    identifier err, errp;
    expression list args;
    @@
    -    error_setg(&err, args);
    +    error_setg(errp, args);
         ... when != err
         error_propagate(errp, err);
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200707160613.848843-34-armbru@redhat.com>
											
										 
											2020-07-07 18:06:01 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     nfds->maxlen = value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *file_dump_get_filename(Object *obj, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return g_strdup(nfds->filename); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void file_dump_set_filename(Object *obj, const char *value, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |    NetFilterDumpState *nfds = FILTER_DUMP(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     g_free(nfds->filename); | 
					
						
							|  |  |  |     nfds->filename = g_strdup(value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void filter_dump_instance_init(Object *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     nfds->maxlen = 65536; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-23 15:43:19 +08:00
										 |  |  | static void filter_dump_instance_finalize(Object *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NetFilterDumpState *nfds = FILTER_DUMP(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     g_free(nfds->filename); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  | static void filter_dump_class_init(ObjectClass *oc, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NetFilterClass *nfc = NETFILTER_CLASS(oc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 13:38:22 -05:00
										 |  |  |     object_class_property_add(oc, "maxlen", "uint32", filter_dump_get_maxlen, | 
					
						
							|  |  |  |                               filter_dump_set_maxlen, NULL, NULL); | 
					
						
							|  |  |  |     object_class_property_add_str(oc, "file", file_dump_get_filename, | 
					
						
							|  |  |  |                                   file_dump_set_filename); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  |     nfc->setup = filter_dump_setup; | 
					
						
							|  |  |  |     nfc->cleanup = filter_dump_cleanup; | 
					
						
							|  |  |  |     nfc->receive_iov = filter_dump_receive_iov; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const TypeInfo filter_dump_info = { | 
					
						
							|  |  |  |     .name = TYPE_FILTER_DUMP, | 
					
						
							|  |  |  |     .parent = TYPE_NETFILTER, | 
					
						
							|  |  |  |     .class_init = filter_dump_class_init, | 
					
						
							|  |  |  |     .instance_init = filter_dump_instance_init, | 
					
						
							| 
									
										
										
										
											2015-12-23 15:43:19 +08:00
										 |  |  |     .instance_finalize = filter_dump_instance_finalize, | 
					
						
							| 
									
										
										
										
											2015-10-13 12:40:01 +02:00
										 |  |  |     .instance_size = sizeof(NetFilterDumpState), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void filter_dump_register_types(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     type_register_static(&filter_dump_info); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type_init(filter_dump_register_types); |