diff --git a/RELNOTES b/RELNOTES index a2e42b6b..b6c4683e 100644 --- a/RELNOTES +++ b/RELNOTES @@ -41,6 +41,22 @@ the README file. - An option definition referencing leak was fixed, which resulted in early termination of dhclient upon the renewal event. +- Some default hash table sizes were tweaked, some upwards, some downwards. + 3.1.0a1's tables resulted in a reduction in default server memory use. + The new selected values provide more of a zero sum (increasing the size + of tables likely to be populated, decreasing the size of tables unlikely). + +- Lease structures appear in three spearate hashes: by IP address, by UID, + and by hardware address. One type of table was used for all three, and + improvements to IP address hashing were applied to all three (so UID and + hardware addresses were treated like 4-byte integers). There are now two + types of tables, and the uid/hw hashes use functions more appropriate + to their needs. + +- The max-lease-misbalance percentage no longer causes scheduled rebalance + runs to be skipped: it still governs the schedule, but every scheduled + run will attempt balance. + Changes since 3.0 (New Features) - A workaround for certain STSN servers that send a mangled domain-name diff --git a/common/tables.c b/common/tables.c index 980ba30a..b4b47ba6 100644 --- a/common/tables.c +++ b/common/tables.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: tables.c,v 1.59 2006/09/18 17:35:44 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: tables.c,v 1.60 2006/10/27 22:54:12 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -677,6 +677,12 @@ void initialize_common_option_spaces() dhcp_options [i].name, 0, &dhcp_options [i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("DHCP name hash: %s", + option_name_hash_report(dhcp_universe.name_hash)); + log_info("DHCP code hash: %s", + option_code_hash_report(dhcp_universe.code_hash)); +#endif /* Set up the Novell option universe (for option 63)... */ nwip_universe.name = "nwip"; @@ -715,6 +721,12 @@ void initialize_common_option_spaces() nwip_options[i].name, 0, &nwip_options[i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("NWIP name hash: %s", + option_name_hash_report(nwip_universe.name_hash)); + log_info("NWIP code hash: %s", + option_code_hash_report(nwip_universe.code_hash)); +#endif /* Set up the FQDN option universe... */ fqdn_universe.name = "fqdn"; @@ -753,6 +765,12 @@ void initialize_common_option_spaces() fqdn_options[i].name, 0, &fqdn_options[i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("FQDN name hash: %s", + option_name_hash_report(fqdn_universe.name_hash)); + log_info("FQDN code hash: %s", + option_code_hash_report(fqdn_universe.code_hash)); +#endif /* Set up the Vendor Identified Vendor Class options (for option * 125)... @@ -794,6 +812,12 @@ void initialize_common_option_spaces() vendor_class_options[i].name, 0, &vendor_class_options[i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("VIVCO name hash: %s", + option_name_hash_report(vendor_class_universe.name_hash)); + log_info("VIVCO code hash: %s", + option_code_hash_report(vendor_class_universe.code_hash)); +#endif /* Set up the Vendor Identified Vendor Sub-options (option 126)... */ vendor_universe.name = "vendor"; @@ -833,6 +857,12 @@ void initialize_common_option_spaces() vendor_options[i].name, 0, &vendor_options[i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("VIVSO name hash: %s", + option_name_hash_report(vendor_universe.name_hash)); + log_info("VIVSO code hash: %s", + option_code_hash_report(vendor_universe.code_hash)); +#endif /* Set up the ISC Vendor-option universe (for option 125.2495)... */ isc_universe.name = "isc"; @@ -863,14 +893,20 @@ void initialize_common_option_spaces() !option_code_new_hash(&isc_universe.code_hash, VIV_ISC_HASH_SIZE, MDL)) log_fatal("Can't allocate ISC Vendor options hash table."); - for (i = 0 ; vendor_options[i].name ; i++) { - option_code_hash_add(vendor_universe.code_hash, - &vendor_options[i].code, 0, - &vendor_options[i], MDL); - option_name_hash_add(vendor_universe.name_hash, - vendor_options[i].name, 0, - &vendor_options[i], MDL); + for (i = 0 ; isc_options[i].name ; i++) { + option_code_hash_add(isc_universe.code_hash, + &isc_options[i].code, 0, + &isc_options[i], MDL); + option_name_hash_add(isc_universe.name_hash, + isc_options[i].name, 0, + &isc_options[i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("ISC name hash: %s", + option_name_hash_report(isc_universe.name_hash)); + log_info("ISC code hash: %s", + option_code_hash_report(isc_universe.code_hash)); +#endif /* Set up the hash of universes. */ universe_new_hash(&universe_hash, UNIVERSE_HASH_SIZE, MDL); diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 0c674c97..9c5cd71b 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -67,7 +67,8 @@ typedef struct hash_table universe_hash_t; typedef struct hash_table option_name_hash_t; typedef struct hash_table option_code_hash_t; typedef struct hash_table dns_zone_hash_t; -typedef struct hash_table lease_hash_t; +typedef struct hash_table lease_ip_hash_t; +typedef struct hash_table lease_id_hash_t; typedef struct hash_table host_hash_t; typedef struct hash_table class_hash_t; @@ -87,13 +88,23 @@ typedef struct hash_table class_hash_t; # define BYTE_CODE_HASH_SIZE 254 /* Default would be rediculous. */ #endif +/* Although it is highly improbable that a 16-bit option space might + * actually use 2^16 actual defined options, it is the worst case + * scenario we must prepare for. Having 4 options per bucket in this + * case is pretty reasonable. + */ #if !defined (WORD_NAME_HASH_SIZE) -# define WORD_NAME_HASH_SIZE 0 /* Default. */ +# define WORD_NAME_HASH_SIZE 20479 #endif #if !defined (WORD_CODE_HASH_SIZE) -# define WORD_CODE_HASH_SIZE 0 /* Default. */ +# define WORD_CODE_HASH_SIZE 16384 #endif +/* Not only is it improbable that the 32-bit spaces might actually use 2^32 + * defined options, it is infeasable. It would be best for this kind of + * space to be dynamically sized. Instead we size it at the word hash's + * level. + */ #if !defined (QUAD_NAME_HASH_SIZE) # define QUAD_NAME_HASH_SIZE WORD_NAME_HASH_SIZE #endif @@ -111,15 +122,18 @@ typedef struct hash_table class_hash_t; #endif #if !defined (NWIP_HASH_SIZE) -# define NWIP_HASH_SIZE 11 /* A really small table. */ +# define NWIP_HASH_SIZE 17 /* A really small table. */ #endif #if !defined (FQDN_HASH_SIZE) -# define FQDN_HASH_SIZE 7 /* A rediculously small table. */ +# define FQDN_HASH_SIZE 13 /* A rediculously small table. */ #endif +/* I really doubt a given installation is going to have more than a few + * hundred vendors involved. + */ #if !defined (VIVCO_HASH_SIZE) -# define VIVCO_HASH_SIZE QUAD_CODE_HASH_SIZE +# define VIVCO_HASH_SIZE 127 #endif #if !defined (VIVSO_HASH_SIZE) @@ -131,35 +145,52 @@ typedef struct hash_table class_hash_t; #endif #if !defined (UNIVERSE_HASH_SIZE) -# define UNIVERSE_HASH_SIZE 11 /* A really small table. */ +# define UNIVERSE_HASH_SIZE 13 /* A really small table. */ #endif #if !defined (GROUP_HASH_SIZE) # define GROUP_HASH_SIZE 0 /* Default. */ #endif +/* At least one person has indicated they use ~20k host records. + */ #if !defined (HOST_HASH_SIZE) -# define HOST_HASH_SIZE 0 /* Default. */ +# define HOST_HASH_SIZE 22501 #endif +/* We have user reports of use of ISC DHCP numbering leases in the 200k's. + * + * We also have reports of folks using 10.0/8 as a dynamic range. The + * following is something of a compromise between the two. At the ~2-3 + * hundred thousand leases, there's ~2-3 leases to search in each bucket. + */ #if !defined (LEASE_HASH_SIZE) -# define LEASE_HASH_SIZE 0 /* Default. */ +# define LEASE_HASH_SIZE 100003 #endif +/* It is not known what the worst case subclass hash size is. We estimate + * high, I think. + */ #if !defined (SCLASS_HASH_SIZE) -# define SCLASS_HASH_SIZE 1009 /* A less than gigantic sized table. */ +# define SCLASS_HASH_SIZE 12007 #endif #if !defined (AGENT_HASH_SIZE) # define AGENT_HASH_SIZE 11 /* A really small table. */ #endif +/* The server hash size is used for both names and codes. There aren't + * many (roughly 50 at the moment), so we use a smaller table. If we + * use a 1:1 table size, then we get name collisions due to poor name + * hashing. So we use double the space we need, which drastically + * reduces collisions. + */ #if !defined (SERVER_HASH_SIZE) -# define SERVER_HASH_SIZE (sizeof(server_options) / sizeof(struct option)) +# define SERVER_HASH_SIZE (2*(sizeof(server_options) / sizeof(struct option))) #endif - +/* How many options are likely to appear in a single packet? */ #if !defined (OPTION_HASH_SIZE) # define OPTION_HASH_SIZE 17 # define OPTION_HASH_PTWO 32 /* Next power of two above option hash. */ @@ -1071,7 +1102,10 @@ HASH_FUNCTIONS_DECL (option_name, const char *, struct option, HASH_FUNCTIONS_DECL (option_code, const unsigned *, struct option, option_code_hash_t) HASH_FUNCTIONS_DECL (dns_zone, const char *, struct dns_zone, dns_zone_hash_t) -HASH_FUNCTIONS_DECL (lease, const unsigned char *, struct lease, lease_hash_t) +HASH_FUNCTIONS_DECL(lease_ip, const unsigned char *, struct lease, + lease_ip_hash_t) +HASH_FUNCTIONS_DECL(lease_id, const unsigned char *, struct lease, + lease_id_hash_t) HASH_FUNCTIONS_DECL (host, const unsigned char *, struct host_decl, host_hash_t) HASH_FUNCTIONS_DECL (class, const char *, struct class, class_hash_t) @@ -2536,9 +2570,9 @@ extern struct shared_network *shared_networks; extern host_hash_t *host_hw_addr_hash; extern host_hash_t *host_uid_hash; extern host_hash_t *host_name_hash; -extern lease_hash_t *lease_uid_hash; -extern lease_hash_t *lease_ip_addr_hash; -extern lease_hash_t *lease_hw_addr_hash; +extern lease_id_hash_t *lease_uid_hash; +extern lease_ip_hash_t *lease_ip_addr_hash; +extern lease_id_hash_t *lease_hw_addr_hash; extern omapi_object_type_t *dhcp_type_host; diff --git a/includes/omapip/hash.h b/includes/omapip/hash.h index 2a588496..98f96a06 100644 --- a/includes/omapip/hash.h +++ b/includes/omapip/hash.h @@ -86,6 +86,7 @@ void name##_hash_delete (hashtype *, bufarg, unsigned, \ const char *, int); \ int name##_hash_lookup (type **, hashtype *, bufarg, unsigned, \ const char *, int); \ +unsigned char * name##_hash_report(hashtype *); \ int name##_hash_foreach (hashtype *, hash_foreach_func); \ int name##_new_hash (hashtype **, unsigned, const char *, int); \ void name##_free_hash_table (hashtype **, const char *, int); @@ -115,6 +116,11 @@ int name##_hash_lookup (type **ptr, hashtype *table, \ buf, len, file, line); \ } \ \ +unsigned char * name##_hash_report(hashtype *table) \ +{ \ + return hash_report((struct hash_table *)table); \ +} \ + \ int name##_hash_foreach (hashtype *table, hash_foreach_func func) \ { \ return hash_foreach ((struct hash_table *)table, \ @@ -144,8 +150,10 @@ int new_hash(struct hash_table **, const char *, int); unsigned do_string_hash(const void *, unsigned, unsigned); unsigned do_case_hash(const void *, unsigned, unsigned); +unsigned do_id_hash(const void *, unsigned, unsigned); unsigned do_number_hash(const void *, unsigned, unsigned); unsigned do_ip4_hash(const void *, unsigned, unsigned); +unsigned char *hash_report(struct hash_table *); void add_hash (struct hash_table *, const void *, unsigned, hashed_object_t *, const char *, int); diff --git a/omapip/hash.c b/omapip/hash.c index 29a67eb6..ace7ef22 100644 --- a/omapip/hash.c +++ b/omapip/hash.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: hash.c,v 1.11 2006/07/25 09:59:39 shane Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: hash.c,v 1.12 2006/10/27 22:54:12 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include @@ -282,6 +282,41 @@ do_string_hash(const void *name, unsigned len, unsigned size) return accum % size; } +/* Client identifiers are generally 32-bits of ordinary + * non-randomness followed by 24-bits of unordinary randomness. + * So, end-align in 24-bit chunks, and xor any preceding data + * just to mix it up a little. + */ +unsigned +do_id_hash(const void *name, unsigned len, unsigned size) +{ + register unsigned accum = 0; + register const unsigned char *s = (const unsigned char *)name; + const unsigned char *end = s + len; + + if (len == 0) + return 0; + + /* The switch indexes our starting position into the do/while loop, + * taking up the remainder after hashing in all the other bytes in + * threes. + */ + switch (len % 3) { + do { + case 0: + accum ^= *s++ << 16; + case 2: + accum ^= *s++ << 8; + case 1: + accum ^= *s++; + } while (s < end); + + break; + } + + return accum % size; +} + unsigned do_number_hash(const void *key, unsigned len, unsigned size) { @@ -302,6 +337,55 @@ do_ip4_hash(const void *key, unsigned len, unsigned size) return number % size; } +unsigned char * +hash_report(struct hash_table *table) +{ + static unsigned char retbuf[sizeof("Contents/Size (%): " + "2147483647/2147483647 " + "(2147483647%). " + "Min/max: 2147483647/2147483647")]; + unsigned curlen, pct, contents=0, minlen=UINT_MAX, maxlen=0; + unsigned i; + struct hash_bucket *bp; + + if (table->hash_count == 0) + return "Invalid hash table."; + + for (i = 0 ; i < table->hash_count ; i++) { + curlen = 0; + + bp = table->buckets[i]; + while (bp != NULL) { + curlen++; + bp = bp->next; + } + + if (curlen < minlen) + minlen = curlen; + if (curlen > maxlen) + maxlen = curlen; + + contents += curlen; + } + + if (contents >= (UINT_MAX / 100)) + pct = contents / ((table->hash_count / 100) + 1); + else + pct = (contents * 100) / table->hash_count; + + if (contents > 2147483647 || + table->hash_count > 2147483647 || + pct > 2147483647 || + minlen > 2147483647 || + maxlen > 2147483647) + return "Report out of range for display."; + + sprintf(retbuf, "Contents/Size (%%): %u/%u (%u%%). Min/max: %u/%u", + contents, table->hash_count, pct, minlen, maxlen); + + return retbuf; +} + void add_hash (table, key, len, pointer, file, line) struct hash_table *table; unsigned len; diff --git a/server/db.c b/server/db.c index 004e840b..2ea9c866 100644 --- a/server/db.c +++ b/server/db.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: db.c,v 1.74 2006/07/19 16:44:47 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: db.c,v 1.75 2006/10/27 22:54:12 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -652,11 +652,11 @@ write_named_billing_class(const void *key, unsigned len, void *object) (due to clone_group() call). */ if (class->group != 0 && class->group->authoritative != 0) write_statements(db_file, class->group->statements, 8); - + if (fprintf(db_file, "}\n\n") <= 0) return ISC_R_IOERROR; } - + if (class->hash != NULL) { /* yep. recursive. god help us. */ /* XXX - cannot check error status of this... * foo_hash_foreach returns a count of operations completed. @@ -786,6 +786,16 @@ void db_startup (testp) GET_TIME (&write_time); new_lease_file (); } + +#if defined(REPORT_HASH_PERFORMANCE) + log_info("Host HW hash: %s", host_hash_report(host_hw_addr_hash)); + log_info("Host UID hash: %s", host_hash_report(host_uid_hash)); + log_info("Lease IP hash: %s", + lease_ip_hash_report(lease_ip_addr_hash)); + log_info("Lease UID hash: %s", lease_id_hash_report(lease_uid_hash)); + log_info("Lease HW hash: %s", + lease_id_hash_report(lease_hw_addr_hash)); +#endif } int new_lease_file () diff --git a/server/failover.c b/server/failover.c index ab8904c8..a7e18c02 100644 --- a/server/failover.c +++ b/server/failover.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: failover.c,v 1.67 2006/10/09 17:47:43 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: failover.c,v 1.68 2006/10/27 22:54:12 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -2320,21 +2320,6 @@ static int dhcp_failover_pool_dobalance(dhcp_failover_state_t *state) reqsent = 1; } - /* Do not go through the process unless at least we have - * more than thresh% more leases than the peer. - */ - if (lts <= thresh) { - log_info("pool %lx %s: lts <= max-lease-misbalance " - "(%d), pool rebalance event skipped.", - (unsigned long)p, - (p->shared_network ? - p->shared_network->name : ""), thresh); - - /* Recalculate next rebalance event timer. */ - dhcp_failover_pool_check(p); - continue; - } - /* In the first pass, try to allocate leases to the * peer which it would normally be responsible for (if * the lease has a hardware address or client-identifier, diff --git a/server/mdb.c b/server/mdb.c index 6dc3b947..c6b457fe 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: mdb.c,v 1.85 2006/09/27 18:27:27 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: mdb.c,v 1.86 2006/10/27 22:54:13 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -45,9 +45,9 @@ struct shared_network *shared_networks; host_hash_t *host_hw_addr_hash; host_hash_t *host_uid_hash; host_hash_t *host_name_hash; -lease_hash_t *lease_uid_hash; -lease_hash_t *lease_ip_addr_hash; -lease_hash_t *lease_hw_addr_hash; +lease_id_hash_t *lease_uid_hash; +lease_ip_hash_t *lease_ip_addr_hash; +lease_id_hash_t *lease_hw_addr_hash; int numclasseswritten; @@ -549,15 +549,17 @@ void new_address_range (cfile, low, high, subnet, pool, lpchain) /* Initialize the hash table if it hasn't been done yet. */ if (!lease_uid_hash) { - if (!lease_new_hash(&lease_uid_hash, LEASE_HASH_SIZE, MDL)) + if (!lease_id_new_hash(&lease_uid_hash, LEASE_HASH_SIZE, MDL)) log_fatal ("Can't allocate lease/uid hash"); } if (!lease_ip_addr_hash) { - if (!lease_new_hash(&lease_ip_addr_hash, LEASE_HASH_SIZE, MDL)) + if (!lease_ip_new_hash(&lease_ip_addr_hash, LEASE_HASH_SIZE, + MDL)) log_fatal ("Can't allocate lease/ip hash"); } if (!lease_hw_addr_hash) { - if (!lease_new_hash(&lease_hw_addr_hash, LEASE_HASH_SIZE, MDL)) + if (!lease_id_new_hash(&lease_hw_addr_hash, LEASE_HASH_SIZE, + MDL)) log_fatal ("Can't allocate lease/hw hash"); } @@ -638,9 +640,9 @@ void new_address_range (cfile, low, high, subnet, pool, lpchain) pool_reference (< -> pool, pool, MDL); lease_dereference (<, MDL); } else - lease_hash_add (lease_ip_addr_hash, - lp -> ip_addr.iabuf, - lp -> ip_addr.len, lp, MDL); + lease_ip_hash_add(lease_ip_addr_hash, + lp->ip_addr.iabuf, lp->ip_addr.len, + lp, MDL); /* Put the lease on the chain for the caller. */ if (lpchain) { if (*lpchain) { @@ -836,9 +838,9 @@ void enter_lease (lease) if (comp -> subnet) subnet_reference (&lease -> subnet, comp -> subnet, MDL); - lease_hash_delete (lease_ip_addr_hash, - lease -> ip_addr.iabuf, - lease -> ip_addr.len, MDL); + lease_ip_hash_delete(lease_ip_addr_hash, + lease->ip_addr.iabuf, lease->ip_addr.len, + MDL); lease_dereference (&comp, MDL); } @@ -855,9 +857,8 @@ void enter_lease (lease) log_error ("lease %s: no subnet.", piaddr (lease -> ip_addr)); return; } - lease_hash_add (lease_ip_addr_hash, - lease -> ip_addr.iabuf, - lease -> ip_addr.len, lease, MDL); + lease_ip_hash_add(lease_ip_addr_hash, lease->ip_addr.iabuf, + lease->ip_addr.len, lease, MDL); } /* Replace the data in an existing lease with the data in a new lease; @@ -1668,8 +1669,8 @@ void pool_timer (vpool) int find_lease_by_ip_addr (struct lease **lp, struct iaddr addr, const char *file, int line) { - return lease_hash_lookup (lp, lease_ip_addr_hash, - addr.iabuf, addr.len, file, line); + return lease_ip_hash_lookup(lp, lease_ip_addr_hash, addr.iabuf, + addr.len, file, line); } int find_lease_by_uid (struct lease **lp, const unsigned char *uid, @@ -1677,7 +1678,7 @@ int find_lease_by_uid (struct lease **lp, const unsigned char *uid, { if (len == 0) return 0; - return lease_hash_lookup (lp, lease_uid_hash, uid, len, file, line); + return lease_id_hash_lookup (lp, lease_uid_hash, uid, len, file, line); } int find_lease_by_hw_addr (struct lease **lp, @@ -1686,8 +1687,8 @@ int find_lease_by_hw_addr (struct lease **lp, { if (hwlen == 0) return 0; - return lease_hash_lookup (lp, lease_hw_addr_hash, - hwaddr, hwlen, file, line); + return lease_id_hash_lookup(lp, lease_hw_addr_hash, hwaddr, hwlen, + file, line); } /* Add the specified lease to the uid hash. */ @@ -1701,8 +1702,8 @@ void uid_hash_add (lease) /* If it's not in the hash, just add it. */ if (!find_lease_by_uid (&head, lease -> uid, lease -> uid_len, MDL)) - lease_hash_add (lease_uid_hash, lease -> uid, - lease -> uid_len, lease, MDL); + lease_id_hash_add(lease_uid_hash, lease->uid, lease->uid_len, + lease, MDL); else { /* Otherwise, attach it to the end of the list. */ while (head -> n_uid) { @@ -1735,13 +1736,12 @@ void uid_hash_delete (lease) remove the hash table entry and add a new one with the next lease on the list (if there is one). */ if (head == lease) { - lease_hash_delete (lease_uid_hash, - lease -> uid, lease -> uid_len, MDL); + lease_id_hash_delete(lease_uid_hash, lease->uid, + lease->uid_len, MDL); if (lease -> n_uid) { - lease_hash_add (lease_uid_hash, - lease -> n_uid -> uid, - lease -> n_uid -> uid_len, - lease -> n_uid, MDL); + lease_id_hash_add(lease_uid_hash, lease->n_uid->uid, + lease->n_uid->uid_len, lease->n_uid, + MDL); lease_dereference (&lease -> n_uid, MDL); } } else { @@ -1775,10 +1775,9 @@ void hw_hash_add (lease) /* If it's not in the hash, just add it. */ if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf, lease -> hardware_addr.hlen, MDL)) - lease_hash_add (lease_hw_addr_hash, - lease -> hardware_addr.hbuf, - lease -> hardware_addr.hlen, - lease, MDL); + lease_id_hash_add(lease_hw_addr_hash, + lease->hardware_addr.hbuf, + lease->hardware_addr.hlen, lease, MDL); else { /* Otherwise, attach it to the end of the list. */ while (head -> n_hw) { @@ -1813,15 +1812,15 @@ void hw_hash_delete (lease) remove the hash table entry and add a new one with the next lease on the list (if there is one). */ if (head == lease) { - lease_hash_delete (lease_hw_addr_hash, - lease -> hardware_addr.hbuf, - lease -> hardware_addr.hlen, MDL); - if (lease -> n_hw) { - lease_hash_add (lease_hw_addr_hash, - lease -> n_hw -> hardware_addr.hbuf, - lease -> n_hw -> hardware_addr.hlen, - lease -> n_hw, MDL); - lease_dereference (&lease -> n_hw, MDL); + lease_id_hash_delete(lease_hw_addr_hash, + lease->hardware_addr.hbuf, + lease->hardware_addr.hlen, MDL); + if (lease->n_hw) { + lease_id_hash_add(lease_hw_addr_hash, + lease->n_hw->hardware_addr.hbuf, + lease->n_hw->hardware_addr.hlen, + lease->n_hw, MDL); + lease_dereference(&lease->n_hw, MDL); } } else { /* Otherwise, look for the lease in the list of leases @@ -2118,9 +2117,8 @@ lease_instantiate(const void *key, unsigned len, void *object) XXX orphan, which we *should* keep around until it expires, XXX but which right now we just forget. */ if (!lease -> pool) { - lease_hash_delete (lease_ip_addr_hash, - lease -> ip_addr.iabuf, - lease -> ip_addr.len, MDL); + lease_ip_hash_delete(lease_ip_addr_hash, lease->ip_addr.iabuf, + lease->ip_addr.len, MDL); return ISC_R_SUCCESS; } @@ -2179,7 +2177,7 @@ void expire_all_pools () /* First, go over the hash list and actually put all the leases on the appropriate lists. */ - lease_hash_foreach (lease_ip_addr_hash, lease_instantiate); + lease_ip_hash_foreach(lease_ip_addr_hash, lease_instantiate); /* Loop through each pool in each shared network and call the * expiry routine on the pool. It is no longer safe to follow @@ -2273,8 +2271,10 @@ void dump_subnets () } } -HASH_FUNCTIONS (lease, const unsigned char *, struct lease, lease_hash_t, - lease_reference, lease_dereference, do_ip4_hash) +HASH_FUNCTIONS(lease_ip, const unsigned char *, struct lease, lease_ip_hash_t, + lease_reference, lease_dereference, do_ip4_hash) +HASH_FUNCTIONS(lease_id, const unsigned char *, struct lease, lease_id_hash_t, + lease_reference, lease_dereference, do_id_hash) HASH_FUNCTIONS (host, const unsigned char *, struct host_decl, host_hash_t, host_reference, host_dereference, do_string_hash) HASH_FUNCTIONS (class, const char *, struct class, class_hash_t, diff --git a/server/omapi.c b/server/omapi.c index 3cd66284..4caf8e34 100644 --- a/server/omapi.c +++ b/server/omapi.c @@ -41,7 +41,7 @@ #ifndef lint static char copyright[] = -"$Id: omapi.c,v 1.58 2006/06/01 20:23:17 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: omapi.c,v 1.59 2006/10/27 22:54:13 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -755,9 +755,9 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, status = omapi_get_value_str (ref, id, "ip-address", &tv); if (status == ISC_R_SUCCESS) { lease = (struct lease *)0; - lease_hash_lookup (&lease, lease_ip_addr_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len, MDL); + lease_ip_hash_lookup(&lease, lease_ip_addr_hash, + tv->value->u.buffer.value, + tv->value->u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); @@ -784,9 +784,9 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv); if (status == ISC_R_SUCCESS) { lease = (struct lease *)0; - lease_hash_lookup (&lease, lease_uid_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len, MDL); + lease_id_hash_lookup(&lease, lease_uid_hash, + tv->value->u.buffer.value, + tv->value->u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (*lp && *lp != (omapi_object_t *)lease) { @@ -858,7 +858,8 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, } lease = (struct lease *)0; - lease_hash_lookup (&lease, lease_hw_addr_hash, haddr, len, MDL); + lease_id_hash_lookup(&lease, lease_hw_addr_hash, haddr, len, + MDL); dfree (haddr, MDL); if (*lp && *lp != (omapi_object_t *)lease) { @@ -1480,9 +1481,9 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, /* first find the lease for this ip address */ l = (struct lease *)0; - lease_hash_lookup (&l, lease_ip_addr_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len, MDL); + lease_ip_hash_lookup(&l, lease_ip_addr_hash, + tv->value->u.buffer.value, + tv->value->u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (!l && !*lp) diff --git a/server/stables.c b/server/stables.c index 849f16b9..214241cb 100644 --- a/server/stables.c +++ b/server/stables.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: stables.c,v 1.33 2006/07/31 23:17:24 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"; +"$Id: stables.c,v 1.34 2006/10/27 22:54:13 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -357,6 +357,12 @@ void initialize_server_option_spaces() agent_options[i].name, 0, &agent_options[i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("Relay Agent name hash: %s", + option_name_hash_report(agent_universe.name_hash)); + log_info("Relay Agent code hash: %s", + option_code_hash_report(agent_universe.code_hash)); +#endif code = DHO_DHCP_AGENT_OPTIONS; option_code_hash_lookup(&agent_universe.enc_opt, dhcp_universe.code_hash, &code, 0, MDL); @@ -389,6 +395,12 @@ void initialize_server_option_spaces() server_options[i].name, 0, &server_options[i], MDL); } +#if defined(REPORT_HASH_PERFORMANCE) + log_info("Server-Config Option name hash: %s", + option_name_hash_report(server_universe.name_hash)); + log_info("Server-Config Option code hash: %s", + option_code_hash_report(server_universe.code_hash)); +#endif /* Add the server and agent option spaces to the option space hash. */ universe_hash_add (universe_hash,