From 41c2346716ff41df78062753128a87124f78ea29 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 26 Aug 2014 21:31:08 +0100 Subject: [PATCH 01/10] curl: The macro that you have to uncomment to get debugging is DEBUG_CURL. Signed-off-by: Richard W.M. Jones Signed-off-by: Michael Tokarev --- block/curl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/curl.c b/block/curl.c index 025833994c..938f9d94e8 100644 --- a/block/curl.c +++ b/block/curl.c @@ -26,7 +26,7 @@ #include "qapi/qmp/qbool.h" #include -// #define DEBUG +// #define DEBUG_CURL // #define DEBUG_VERBOSE #ifdef DEBUG_CURL From c5539cb4269edf15d96bd0d75594757a80a39fa5 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Mon, 25 Aug 2014 10:01:27 +0800 Subject: [PATCH 02/10] Fix debug print warning Steps: 1.enable qemu debug print, using simply scprit as below: grep "//#define DEBUG" * -rl | xargs sed -i "s/\/\/#define DEBUG/#define DEBUG/g" 2. make -j 3. get some warning: hw/i2c/pm_smbus.c: In function 'smb_ioport_writeb': hw/i2c/pm_smbus.c:142: warning: format '%04x' expects type 'unsigned int', but argument 2 has type 'hwaddr' hw/i2c/pm_smbus.c:142: warning: format '%02x' expects type 'unsigned int', but argument 3 has type 'uint64_t' hw/i2c/pm_smbus.c: In function 'smb_ioport_readb': hw/i2c/pm_smbus.c:209: warning: format '%04x' expects type 'unsigned int', but argument 2 has type 'hwaddr' hw/intc/i8259.c: In function 'pic_ioport_read': hw/intc/i8259.c:373: warning: format '%02x' expects type 'unsigned int', but argument 2 has type 'hwaddr' hw/input/pckbd.c: In function 'kbd_write_command': hw/input/pckbd.c:232: warning: format '%02x' expects type 'unsigned int', but argument 2 has type 'uint64_t' hw/input/pckbd.c: In function 'kbd_write_data': hw/input/pckbd.c:333: warning: format '%02x' expects type 'unsigned int', but argument 2 has type 'uint64_t' hw/isa/apm.c: In function 'apm_ioport_writeb': hw/isa/apm.c:44: warning: format '%x' expects type 'unsigned int', but argument 2 has type 'hwaddr' hw/isa/apm.c:44: warning: format '%02x' expects type 'unsigned int', but argument 3 has type 'uint64_t' hw/isa/apm.c: In function 'apm_ioport_readb': hw/isa/apm.c:67: warning: format '%x' expects type 'unsigned int', but argument 2 has type 'hwaddr' hw/timer/mc146818rtc.c: In function 'cmos_ioport_write': hw/timer/mc146818rtc.c:394: warning: format '%02x' expects type 'unsigned int', but argument 3 has type 'uint64_t' hw/i386/pc.c: In function 'port92_write': hw/i386/pc.c:479: warning: format '%02x' expects type 'unsigned int', but argument 2 has type 'uint64_t' Fix them. Cc: qemu-trivial@nongnu.org Signed-off-by: Gonglei Signed-off-by: Michael Tokarev --- hw/i2c/pm_smbus.c | 5 +++-- hw/i386/pc.c | 2 +- hw/input/pckbd.c | 4 ++-- hw/intc/i8259.c | 2 +- hw/isa/apm.c | 5 +++-- hw/timer/mc146818rtc.c | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c index fedb5fb4d4..ce1713d267 100644 --- a/hw/i2c/pm_smbus.c +++ b/hw/i2c/pm_smbus.c @@ -139,7 +139,8 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val, { PMSMBus *s = opaque; - SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val); + SMBUS_DPRINTF("SMB writeb port=0x%04" HWADDR_PRIx + " val=0x%02" PRIx64 "\n", addr, val); switch(addr) { case SMBHSTSTS: s->smb_stat = (~(val & 0xff)) & s->smb_stat; @@ -206,7 +207,7 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width) val = 0; break; } - SMBUS_DPRINTF("SMB readb port=0x%04x val=0x%02x\n", addr, val); + SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n", addr, val); return val; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0ca4deb1b3..b6c9b61801 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -481,7 +481,7 @@ static void port92_write(void *opaque, hwaddr addr, uint64_t val, Port92State *s = opaque; int oldval = s->outport; - DPRINTF("port92: write 0x%02x\n", val); + DPRINTF("port92: write 0x%02" PRIx64 "\n", val); s->outport = val; qemu_set_irq(*s->a20_out, (val >> 1) & 1); if ((val & 1) && !(oldval & 1)) { diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index ca1cffcc05..2ab8c873b6 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -229,7 +229,7 @@ static void kbd_write_command(void *opaque, hwaddr addr, { KBDState *s = opaque; - DPRINTF("kbd: write cmd=0x%02x\n", val); + DPRINTF("kbd: write cmd=0x%02" PRIx64 "\n", val); /* Bits 3-0 of the output port P2 of the keyboard controller may be pulsed * low for approximately 6 micro seconds. Bits 3-0 of the KBD_CCMD_PULSE @@ -330,7 +330,7 @@ static void kbd_write_data(void *opaque, hwaddr addr, { KBDState *s = opaque; - DPRINTF("kbd: write data=0x%02x\n", val); + DPRINTF("kbd: write data=0x%02" PRIx64 "\n", val); switch(s->write_cmd) { case 0: diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index a563b82c4e..c51901bfb6 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c @@ -370,7 +370,7 @@ static uint64_t pic_ioport_read(void *opaque, hwaddr addr, ret = s->imr; } } - DPRINTF("read: addr=0x%02x val=0x%02x\n", addr, ret); + DPRINTF("read: addr=0x%02" HWADDR_PRIx " val=0x%02x\n", addr, ret); return ret; } diff --git a/hw/isa/apm.c b/hw/isa/apm.c index 054d529b8b..26ab170215 100644 --- a/hw/isa/apm.c +++ b/hw/isa/apm.c @@ -41,7 +41,8 @@ static void apm_ioport_writeb(void *opaque, hwaddr addr, uint64_t val, { APMState *apm = opaque; addr &= 1; - APM_DPRINTF("apm_ioport_writeb addr=0x%x val=0x%02x\n", addr, val); + APM_DPRINTF("apm_ioport_writeb addr=0x%" HWADDR_PRIx + " val=0x%02" PRIx64 "\n", addr, val); if (addr == 0) { apm->apmc = val; @@ -64,7 +65,7 @@ static uint64_t apm_ioport_readb(void *opaque, hwaddr addr, unsigned size) } else { val = apm->apms; } - APM_DPRINTF("apm_ioport_readb addr=0x%x val=0x%02x\n", addr, val); + APM_DPRINTF("apm_ioport_readb addr=0x%" HWADDR_PRIx " val=0x%02x\n", addr, val); return val; } diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 4df650f450..17912b847f 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -391,7 +391,7 @@ static void cmos_ioport_write(void *opaque, hwaddr addr, if ((addr & 1) == 0) { s->cmos_index = data & 0x7f; } else { - CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n", + CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02" PRIx64 "\n", s->cmos_index, data); switch(s->cmos_index) { case RTC_SECONDS_ALARM: From 7d2ff422cac3e6d5dc7df9072e54bb8dfbd8b589 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Wed, 27 Aug 2014 11:11:55 +0800 Subject: [PATCH 03/10] scripts: Remove scripts/qtest This is a dummy file with no user, drop it. Signed-off-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Signed-off-by: Michael Tokarev --- scripts/qtest | 5 ----- 1 file changed, 5 deletions(-) delete mode 100755 scripts/qtest diff --git a/scripts/qtest b/scripts/qtest deleted file mode 100755 index 4ef6c1c500..0000000000 --- a/scripts/qtest +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -export QTEST_QEMU_BINARY=$1 -shift -"$@" From db013f81b206f19297200a78ecd02d6c2c01d383 Mon Sep 17 00:00:00 2001 From: Li Liu Date: Tue, 26 Aug 2014 14:38:02 +0800 Subject: [PATCH 04/10] device_tree.c: redirect load_device_tree err message to stderr Reviewed-by: Peter Crosthwaite Signed-off-by: Li Liu Signed-off-by: Michael Tokarev --- device_tree.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/device_tree.c b/device_tree.c index ca83504819..9d47195587 100644 --- a/device_tree.c +++ b/device_tree.c @@ -20,6 +20,7 @@ #include "config.h" #include "qemu-common.h" +#include "qemu/error-report.h" #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" #include "hw/loader.h" @@ -79,8 +80,8 @@ void *load_device_tree(const char *filename_path, int *sizep) *sizep = 0; dt_size = get_image_size(filename_path); if (dt_size < 0) { - printf("Unable to get size of device tree file '%s'\n", - filename_path); + error_report("Unable to get size of device tree file '%s'", + filename_path); goto fail; } @@ -92,21 +93,21 @@ void *load_device_tree(const char *filename_path, int *sizep) dt_file_load_size = load_image(filename_path, fdt); if (dt_file_load_size < 0) { - printf("Unable to open device tree file '%s'\n", - filename_path); + error_report("Unable to open device tree file '%s'", + filename_path); goto fail; } ret = fdt_open_into(fdt, fdt, dt_size); if (ret) { - printf("Unable to copy device tree in memory\n"); + error_report("Unable to copy device tree in memory"); goto fail; } /* Check sanity of device tree */ if (fdt_check_header(fdt)) { - printf ("Device tree file loaded into memory is invalid: %s\n", - filename_path); + error_report("Device tree file loaded into memory is invalid: %s", + filename_path); goto fail; } *sizep = dt_size; From 508e221f2ca72871340032641ed1ee82284b4c1d Mon Sep 17 00:00:00 2001 From: Li Liu Date: Tue, 26 Aug 2014 14:38:03 +0800 Subject: [PATCH 05/10] device_tree.c: dump all err mesages with error_report Signed-off-by: Li Liu Signed-off-by: Michael Tokarev --- device_tree.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/device_tree.c b/device_tree.c index 9d47195587..df9eed9cbc 100644 --- a/device_tree.c +++ b/device_tree.c @@ -60,13 +60,13 @@ void *create_device_tree(int *sizep) } ret = fdt_open_into(fdt, fdt, *sizep); if (ret) { - fprintf(stderr, "Unable to copy device tree in memory\n"); + error_report("Unable to copy device tree in memory"); exit(1); } return fdt; fail: - fprintf(stderr, "%s Couldn't create dt: %s\n", __func__, fdt_strerror(ret)); + error_report("%s Couldn't create dt: %s", __func__, fdt_strerror(ret)); exit(1); } @@ -124,8 +124,8 @@ static int findnode_nofail(void *fdt, const char *node_path) offset = fdt_path_offset(fdt, node_path); if (offset < 0) { - fprintf(stderr, "%s Couldn't find node %s: %s\n", __func__, node_path, - fdt_strerror(offset)); + error_report("%s Couldn't find node %s: %s", __func__, node_path, + fdt_strerror(offset)); exit(1); } @@ -139,8 +139,8 @@ int qemu_fdt_setprop(void *fdt, const char *node_path, r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val, size); if (r < 0) { - fprintf(stderr, "%s: Couldn't set %s/%s: %s\n", __func__, node_path, - property, fdt_strerror(r)); + error_report("%s: Couldn't set %s/%s: %s", __func__, node_path, + property, fdt_strerror(r)); exit(1); } @@ -154,8 +154,8 @@ int qemu_fdt_setprop_cell(void *fdt, const char *node_path, r = fdt_setprop_cell(fdt, findnode_nofail(fdt, node_path), property, val); if (r < 0) { - fprintf(stderr, "%s: Couldn't set %s/%s = %#08x: %s\n", __func__, - node_path, property, val, fdt_strerror(r)); + error_report("%s: Couldn't set %s/%s = %#08x: %s", __func__, + node_path, property, val, fdt_strerror(r)); exit(1); } @@ -176,8 +176,8 @@ int qemu_fdt_setprop_string(void *fdt, const char *node_path, r = fdt_setprop_string(fdt, findnode_nofail(fdt, node_path), property, string); if (r < 0) { - fprintf(stderr, "%s: Couldn't set %s/%s = %s: %s\n", __func__, - node_path, property, string, fdt_strerror(r)); + error_report("%s: Couldn't set %s/%s = %s: %s", __func__, + node_path, property, string, fdt_strerror(r)); exit(1); } @@ -194,8 +194,8 @@ const void *qemu_fdt_getprop(void *fdt, const char *node_path, } r = fdt_getprop(fdt, findnode_nofail(fdt, node_path), property, lenp); if (!r) { - fprintf(stderr, "%s: Couldn't get %s/%s: %s\n", __func__, - node_path, property, fdt_strerror(*lenp)); + error_report("%s: Couldn't get %s/%s: %s", __func__, + node_path, property, fdt_strerror(*lenp)); exit(1); } return r; @@ -207,8 +207,8 @@ uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path, int len; const uint32_t *p = qemu_fdt_getprop(fdt, node_path, property, &len); if (len != 4) { - fprintf(stderr, "%s: %s/%s not 4 bytes long (not a cell?)\n", - __func__, node_path, property); + error_report("%s: %s/%s not 4 bytes long (not a cell?)", + __func__, node_path, property); exit(1); } return be32_to_cpu(*p); @@ -220,8 +220,8 @@ uint32_t qemu_fdt_get_phandle(void *fdt, const char *path) r = fdt_get_phandle(fdt, findnode_nofail(fdt, path)); if (r == 0) { - fprintf(stderr, "%s: Couldn't get phandle for %s: %s\n", __func__, - path, fdt_strerror(r)); + error_report("%s: Couldn't get phandle for %s: %s", __func__, + path, fdt_strerror(r)); exit(1); } @@ -266,8 +266,8 @@ int qemu_fdt_nop_node(void *fdt, const char *node_path) r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path)); if (r < 0) { - fprintf(stderr, "%s: Couldn't nop node %s: %s\n", __func__, node_path, - fdt_strerror(r)); + error_report("%s: Couldn't nop node %s: %s", __func__, node_path, + fdt_strerror(r)); exit(1); } @@ -295,8 +295,8 @@ int qemu_fdt_add_subnode(void *fdt, const char *name) retval = fdt_add_subnode(fdt, parent, basename); if (retval < 0) { - fprintf(stderr, "FDT: Failed to create subnode %s: %s\n", name, - fdt_strerror(retval)); + error_report("FDT: Failed to create subnode %s: %s", name, + fdt_strerror(retval)); exit(1); } From 622fb504c402cc222f6c4b6f292d402c4d78a86e Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 27 Aug 2014 08:58:43 +0300 Subject: [PATCH 06/10] MAINTAINERS: Add VMWare devices maintainer Signed-off-by: Dmitry Fleytman Reviewed-by: Stefan Hajnoczi Signed-off-by: Michael Tokarev --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 142f68a689..8622e019fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -684,6 +684,12 @@ S: Maintained F: hw/*/xilinx_* F: include/hw/xilinx.h +Vmware +M: Dmitry Fleytman +S: Maintained +F: hw/net/vmxnet* +F: hw/scsi/vmw_pvscsi* + Subsystems ---------- Audio From b0e90181e4d7244a9466447703acdb2cdd7abdaa Mon Sep 17 00:00:00 2001 From: Chen Fan Date: Mon, 18 Aug 2014 14:46:33 +0800 Subject: [PATCH 07/10] query-memdev: fix potential memory leaks Signed-off-by: Chen Fan Reviewed-by: Peter Crosthwaite Reviewed-by: Hu Tao Signed-off-by: Michael Tokarev --- numa.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/numa.c b/numa.c index c78cec96a8..aa772aafad 100644 --- a/numa.c +++ b/numa.c @@ -318,10 +318,11 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, static int query_memdev(Object *obj, void *opaque) { MemdevList **list = opaque; + MemdevList *m = NULL; Error *err = NULL; if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { - MemdevList *m = g_malloc0(sizeof(*m)); + m = g_malloc0(sizeof(*m)); m->value = g_malloc0(sizeof(*m->value)); @@ -369,6 +370,9 @@ static int query_memdev(Object *obj, void *opaque) return 0; error: + g_free(m->value); + g_free(m); + return -1; } From 976620ac4018db142d82cd42bb7774f40290ce7e Mon Sep 17 00:00:00 2001 From: Chen Fan Date: Mon, 18 Aug 2014 14:46:34 +0800 Subject: [PATCH 08/10] qom/object.c, hmp.c: fix string_output_get_string() memory leak string_output_get_string() uses g_string_free(str, false) to transfer the 'str' pointer to callers and never free it. Signed-off-by: Chen Fan Reviewed-by: Peter Crosthwaite Reviewed-by: Hu Tao Signed-off-by: Michael Tokarev --- hmp.c | 6 ++++-- qom/object.c | 12 ++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/hmp.c b/hmp.c index 4d1838e9ea..ba40c75005 100644 --- a/hmp.c +++ b/hmp.c @@ -1687,6 +1687,7 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) MemdevList *memdev_list = qmp_query_memdev(&err); MemdevList *m = memdev_list; StringOutputVisitor *ov; + char *str; int i = 0; @@ -1704,9 +1705,10 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) m->value->prealloc ? "true" : "false"); monitor_printf(mon, " policy: %s\n", HostMemPolicy_lookup[m->value->policy]); - monitor_printf(mon, " host nodes: %s\n", - string_output_get_string(ov)); + str = string_output_get_string(ov); + monitor_printf(mon, " host nodes: %s\n", str); + g_free(str); string_output_visitor_cleanup(ov); m = m->next; i++; diff --git a/qom/object.c b/qom/object.c index 1b00831efc..79bd0cc474 100644 --- a/qom/object.c +++ b/qom/object.c @@ -938,14 +938,18 @@ int object_property_get_enum(Object *obj, const char *name, { StringOutputVisitor *sov; StringInputVisitor *siv; + char *str; int ret; sov = string_output_visitor_new(false); object_property_get(obj, string_output_get_visitor(sov), name, errp); - siv = string_input_visitor_new(string_output_get_string(sov)); + str = string_output_get_string(sov); + siv = string_input_visitor_new(str); string_output_visitor_cleanup(sov); visit_type_enum(string_input_get_visitor(siv), &ret, strings, NULL, name, errp); + + g_free(str); string_input_visitor_cleanup(siv); return ret; @@ -956,13 +960,17 @@ void object_property_get_uint16List(Object *obj, const char *name, { StringOutputVisitor *ov; StringInputVisitor *iv; + char *str; ov = string_output_visitor_new(false); object_property_get(obj, string_output_get_visitor(ov), name, errp); - iv = string_input_visitor_new(string_output_get_string(ov)); + str = string_output_get_string(ov); + iv = string_input_visitor_new(str); visit_type_uint16List(string_input_get_visitor(iv), list, NULL, errp); + + g_free(str); string_output_visitor_cleanup(ov); string_input_visitor_cleanup(iv); } From ecaf54a052c357e0bacb93c3f178fed34e4821ec Mon Sep 17 00:00:00 2001 From: Chen Fan Date: Mon, 18 Aug 2014 14:46:35 +0800 Subject: [PATCH 09/10] hmp: fix MemdevList memory leak the memdev_list in hmp_info_memdev() is never freed. so we use existent method qapi_free_MemdevList() to free it. and also we can use qapi_free_MemdevList() to replace list loops to clean up the memdev list in error path. Signed-off-by: Chen Fan Reviewed-by: Peter Crosthwaite Reviewed-by: Hu Tao Signed-off-by: Michael Tokarev --- hmp.c | 2 ++ numa.c | 9 ++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/hmp.c b/hmp.c index ba40c75005..40a90dae70 100644 --- a/hmp.c +++ b/hmp.c @@ -1715,4 +1715,6 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) } monitor_printf(mon, "\n"); + + qapi_free_MemdevList(memdev_list); } diff --git a/numa.c b/numa.c index aa772aafad..f07149b12d 100644 --- a/numa.c +++ b/numa.c @@ -379,7 +379,7 @@ error: MemdevList *qmp_query_memdev(Error **errp) { Object *obj; - MemdevList *list = NULL, *m; + MemdevList *list = NULL; obj = object_resolve_path("/objects", NULL); if (obj == NULL) { @@ -393,11 +393,6 @@ MemdevList *qmp_query_memdev(Error **errp) return list; error: - while (list) { - m = list; - list = list->next; - g_free(m->value); - g_free(m); - } + qapi_free_MemdevList(list); return NULL; } From 70381662aa97b294f3c81a085ed143f37f0ab0cb Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 16 Jun 2014 16:47:49 +0100 Subject: [PATCH 10/10] slirp: Honour vlan/stack in hostfwd_remove commands The hostfwd_add and hostfwd_remove monitor commands allow the user to optionally specify a vlan/stack tuple. hostfwd_add honours this, but hostfwd_remove does not (it looks up the tuple but then ignores the SlirpState it has looked up and always uses the first stack in the list anyway). Correct this to honour what the user requested. Signed-off-by: Peter Maydell Signed-off-by: Michael Tokarev --- net/slirp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/slirp.c b/net/slirp.c index 647039ec39..c171119dad 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -345,8 +345,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict) host_port = atoi(p); - err = slirp_remove_hostfwd(QTAILQ_FIRST(&slirp_stacks)->slirp, is_udp, - host_addr, host_port); + err = slirp_remove_hostfwd(s->slirp, is_udp, host_addr, host_port); monitor_printf(mon, "host forwarding rule for %s %s\n", src_str, err ? "not found" : "removed");