Blame SOURCES/0004-avahi-core-reserve-space-for-record-data-when-size-e.patch

e1f8e0
From 86e213fbd0d24b5b2e58d474d27d47b222011936 Mon Sep 17 00:00:00 2001
e1f8e0
From: "Lee, Chun-Yi" <jlee at suse.com>
e1f8e0
Date: Mon, 10 Sep 2012 10:27:56 +0800
e1f8e0
Subject: [PATCH 4/4] avahi-core: reserve space for record data when size
e1f8e0
 estimate
e1f8e0
e1f8e0
When we tested put a lot of airprint service files(have 45 to 60 flies), found
e1f8e0
there have cpu loadinghigh problem when start avahi-daemon with those service
e1f8e0
files.
e1f8e0
e1f8e0
After traced source code, there have problem in probe-sched.c::elapse_callback
e1f8e0
causes doesn't have any probe job set to DONE so the daemon unlimited send out
e1f8e0
DNS package.
e1f8e0
e1f8e0
The root cause is when compare with the free package space in
e1f8e0
packet_add_probe_query before attach job key, the free package space doesn't
e1f8e0
include any record data that will attached after all keys attached. This defect
e1f8e0
causes whole DNS package is filled by job key, but doesn't remain enough space
e1f8e0
for any rdata. Then, that means have no job set to DONE.
e1f8e0
e1f8e0
This patch add a new res_size member to AvahiDnsPacket, it used to sum the
e1f8e0
reserve size for record data the will attached after all keys attached. It can
e1f8e0
avoid keys consume whole size until p->size larger then p->max_size.
e1f8e0
e1f8e0
Resolves: #1081801
e1f8e0
---
e1f8e0
 avahi-core/dns.c         | 20 ++++++++++++++++++++
e1f8e0
 avahi-core/dns.h         |  4 +++-
e1f8e0
 avahi-core/probe-sched.c | 10 ++++++++--
e1f8e0
 3 files changed, 31 insertions(+), 3 deletions(-)
e1f8e0
e1f8e0
diff --git a/avahi-core/dns.c b/avahi-core/dns.c
e1f8e0
index 2fcd91f..523afdc 100644
e1f8e0
--- a/avahi-core/dns.c
e1f8e0
+++ b/avahi-core/dns.c
e1f8e0
@@ -55,6 +55,7 @@ AvahiDnsPacket* avahi_dns_packet_new(unsigned mtu) {
e1f8e0
 
e1f8e0
     p->size = p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE;
e1f8e0
     p->max_size = max_size;
e1f8e0
+    p->res_size = 0;
e1f8e0
     p->name_table = NULL;
e1f8e0
     p->data = NULL;
e1f8e0
 
e1f8e0
@@ -833,6 +834,25 @@ size_t avahi_dns_packet_space(AvahiDnsPacket *p) {
e1f8e0
     return p->max_size - p->size;
e1f8e0
 }
e1f8e0
 
e1f8e0
+size_t avahi_dns_packet_reserve_size(AvahiDnsPacket *p, size_t res_size) {
e1f8e0
+    assert(p);
e1f8e0
+
e1f8e0
+    assert(p->size + p->res_size <= p->max_size);
e1f8e0
+
e1f8e0
+    if ((p->size + p->res_size + res_size) <= p->max_size)
e1f8e0
+	p->res_size += res_size;
e1f8e0
+
e1f8e0
+    return p->res_size;
e1f8e0
+}
e1f8e0
+
e1f8e0
+size_t avahi_dns_packet_reserved_space(AvahiDnsPacket *p) {
e1f8e0
+    assert(p);
e1f8e0
+
e1f8e0
+    assert(p->size + p->res_size <= p->max_size);
e1f8e0
+
e1f8e0
+    return p->max_size - p->size - p->res_size;
e1f8e0
+}
e1f8e0
+
e1f8e0
 int avahi_rdata_parse(AvahiRecord *record, const void* rdata, size_t size) {
e1f8e0
     int ret;
e1f8e0
     AvahiDnsPacket p;
e1f8e0
diff --git a/avahi-core/dns.h b/avahi-core/dns.h
e1f8e0
index 52e8d88..13b1ac2 100644
e1f8e0
--- a/avahi-core/dns.h
e1f8e0
+++ b/avahi-core/dns.h
e1f8e0
@@ -30,7 +30,7 @@
e1f8e0
 #define AVAHI_DNS_PACKET_SIZE_MAX (AVAHI_DNS_PACKET_HEADER_SIZE + 256 + 2 + 2 + 4 + 2 + AVAHI_DNS_RDATA_MAX)
e1f8e0
 
e1f8e0
 typedef struct AvahiDnsPacket {
e1f8e0
-    size_t size, rindex, max_size;
e1f8e0
+    size_t size, rindex, max_size, res_size;
e1f8e0
     AvahiHashmap *name_table; /* for name compression */
e1f8e0
     uint8_t *data;
e1f8e0
 } AvahiDnsPacket;
e1f8e0
@@ -78,6 +78,8 @@ int avahi_dns_packet_skip(AvahiDnsPacket *p, size_t length);
e1f8e0
 
e1f8e0
 int avahi_dns_packet_is_empty(AvahiDnsPacket *p);
e1f8e0
 size_t avahi_dns_packet_space(AvahiDnsPacket *p);
e1f8e0
+size_t avahi_dns_packet_reserve_size(AvahiDnsPacket *p, size_t res_size);
e1f8e0
+size_t avahi_dns_packet_reserved_space(AvahiDnsPacket *p);
e1f8e0
 
e1f8e0
 #define AVAHI_DNS_FIELD_ID 0
e1f8e0
 #define AVAHI_DNS_FIELD_FLAGS 1
e1f8e0
diff --git a/avahi-core/probe-sched.c b/avahi-core/probe-sched.c
e1f8e0
index 1e63411..63cb817 100644
e1f8e0
--- a/avahi-core/probe-sched.c
e1f8e0
+++ b/avahi-core/probe-sched.c
e1f8e0
@@ -179,7 +179,7 @@ static int packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, Ava
e1f8e0
         avahi_record_get_estimate_size(pj->record);
e1f8e0
 
e1f8e0
     /* Too large */
e1f8e0
-    if (size > avahi_dns_packet_space(p))
e1f8e0
+    if (size > avahi_dns_packet_reserved_space(p))
e1f8e0
         return 0;
e1f8e0
 
e1f8e0
     /* Create the probe query */
e1f8e0
@@ -189,6 +189,9 @@ static int packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, Ava
e1f8e0
     b = !!avahi_dns_packet_append_key(p, k, 0);
e1f8e0
     assert(b);
e1f8e0
 
e1f8e0
+    /* reserve size for record data */
e1f8e0
+    avahi_dns_packet_reserve_size(p, avahi_record_get_estimate_size(pj->record));
e1f8e0
+
e1f8e0
     /* Mark this job for addition to the packet */
e1f8e0
     pj->chosen = 1;
e1f8e0
 
e1f8e0
@@ -202,9 +205,12 @@ static int packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, Ava
e1f8e0
             continue;
e1f8e0
 
e1f8e0
         /* This job wouldn't fit in */
e1f8e0
-        if (avahi_record_get_estimate_size(pj->record) > avahi_dns_packet_space(p))
e1f8e0
+        if (avahi_record_get_estimate_size(pj->record) > avahi_dns_packet_reserved_space(p))
e1f8e0
             break;
e1f8e0
 
e1f8e0
+	/* reserve size for record data */
e1f8e0
+	avahi_dns_packet_reserve_size(p, avahi_record_get_estimate_size(pj->record));
e1f8e0
+
e1f8e0
         /* Mark this job for addition to the packet */
e1f8e0
         pj->chosen = 1;
e1f8e0
     }
e1f8e0
-- 
e1f8e0
2.3.4
e1f8e0