|
|
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 |
|