Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Knot projects
Knot DNS
Commits
cd71653b
Commit
cd71653b
authored
Dec 05, 2022
by
Daniel Salzman
Browse files
Merge branch 'cat_impr' into 'master'
Reload changed catalog members only (reuse otherwise) See merge request
!1499
parents
b27b901d
3fbdc932
Pipeline
#107142
passed with stages
in 9 minutes and 31 seconds
Changes
11
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
cd71653b
...
...
@@ -712,7 +712,7 @@ LIBS="$save_LIBS"
# Checks for header files.
AC_HEADER_RESOLV
AC_CHECK_HEADERS_ONCE([pthread_np.h sys/uio.h bsd/string.h])
AC_CHECK_HEADERS_ONCE([pthread_np.h
stdatomic.h
sys/uio.h bsd/string.h])
# Checks for optional library functions.
AC_CHECK_FUNCS([accept4 clock_gettime fgetln getline initgroups malloc_trim \
...
...
distro/pkg/el-7/knot.spec
View file @
cd71653b
...
...
@@ -30,8 +30,7 @@ Patch2: 02-revert-AC_PROG_CC.patch
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool
BuildRequires: make
BuildRequires: gcc
BuildRequires: devtoolset-7
BuildRequires: pkgconfig(liburcu)
BuildRequires: pkgconfig(gnutls) >= 3.3
BuildRequires: pkgconfig(libedit)
...
...
@@ -156,6 +155,7 @@ CFLAGS="%{optflags} -DNDEBUG -Wno-unused"
autoreconf -if
export CC="/opt/rh/devtoolset-7/root/usr/bin/gcc"
%configure \
--sysconfdir=/etc \
--localstatedir=/var/lib \
...
...
src/knot/catalog/catalog_update.c
View file @
cd71653b
/* Copyright (C) 202
1
CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 202
2
CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -398,6 +398,7 @@ int catalog_zone_purge(server_t *server, conf_t *conf, const knot_dname_t *zone)
int
ret
=
catalog_update_del_all
(
&
server
->
catalog_upd
,
&
server
->
catalog
,
zone
,
&
members
);
if
(
ret
==
KNOT_EOK
&&
members
>
0
)
{
log_zone_info
(
zone
,
"catalog zone purged, %zd member zones deconfigured"
,
members
);
server
->
catalog_upd_signal
=
true
;
if
(
kill
(
getpid
(),
SIGUSR1
)
!=
0
)
{
ret
=
knot_map_errno
();
}
...
...
src/knot/ctl/commands.c
View file @
cd71653b
...
...
@@ -1839,7 +1839,7 @@ static int ctl_server(ctl_args_t *args, ctl_cmd_t cmd)
ret
=
KNOT_CTL_ESTOP
;
break
;
case
CTL_RELOAD
:
ret
=
server_reload
(
args
->
server
);
ret
=
server_reload
(
args
->
server
,
RELOAD_FULL
);
if
(
ret
!=
KNOT_EOK
)
{
send_error
(
args
,
knot_strerror
(
ret
));
}
...
...
@@ -2059,7 +2059,7 @@ static int ctl_conf_txn(ctl_args_t *args, ctl_cmd_t cmd)
break
;
}
ret
=
server_reload
(
args
->
server
);
ret
=
server_reload
(
args
->
server
,
RELOAD_COMMIT
);
break
;
default:
assert
(
0
);
...
...
src/knot/server/server.c
View file @
cd71653b
...
...
@@ -1047,7 +1047,7 @@ static void warn_server_reconfigure(conf_t *conf, server_t *server)
}
}
int
server_reload
(
server_t
*
server
)
int
server_reload
(
server_t
*
server
,
reload_t
mode
)
{
if
(
server
==
NULL
)
{
return
KNOT_EINVAL
;
...
...
@@ -1109,7 +1109,7 @@ int server_reload(server_t *server)
stats_reconfigure
(
conf
(),
server
);
}
if
(
full
||
(
flags
&
(
CONF_IO_FRLD_ZONES
|
CONF_IO_FRLD_ZONE
)))
{
server_update_zones
(
conf
(),
server
);
server_update_zones
(
conf
(),
server
,
mode
);
}
/* Free old config needed for module unload in zone reload. */
...
...
@@ -1303,7 +1303,7 @@ int server_reconfigure(conf_t *conf, server_t *server)
return
KNOT_EOK
;
}
void
server_update_zones
(
conf_t
*
conf
,
server_t
*
server
)
void
server_update_zones
(
conf_t
*
conf
,
server_t
*
server
,
reload_t
mode
)
{
if
(
conf
==
NULL
||
server
==
NULL
)
{
return
;
...
...
@@ -1319,7 +1319,7 @@ void server_update_zones(conf_t *conf, server_t *server)
worker_pool_wait
(
server
->
workers
);
/* Reload zone database and free old zones. */
zonedb_reload
(
conf
,
server
);
zonedb_reload
(
conf
,
server
,
mode
);
/* Trim extra heap. */
mem_trim
();
...
...
src/knot/server/server.h
View file @
cd71653b
...
...
@@ -16,6 +16,8 @@
#pragma once
#include
<stdatomic.h>
#include
"knot/conf/conf.h"
#include
"knot/catalog/catalog_update.h"
#include
"knot/common/evsched.h"
...
...
@@ -48,6 +50,17 @@ typedef enum {
ServerRunning
=
1
<<
0
,
/*!< Server is running. */
}
server_state_t
;
/*!
* \brief Server reload kinds.
*/
typedef
enum
{
RELOAD_NONE
=
0
,
RELOAD_FULL
=
1
<<
0
,
/*!< Reload the server and all zones. */
RELOAD_COMMIT
=
1
<<
1
,
/*!< Process changes from dynamic configuration. */
RELOAD_ZONES
=
1
<<
2
,
/*!< Reload all zones. */
RELOAD_CATALOG
=
1
<<
3
,
/*!< Process catalog zone changes. */
}
reload_t
;
/*!
* \brief Server interface structure.
*/
...
...
@@ -103,8 +116,9 @@ typedef struct server {
iface_t
*
ifaces
;
size_t
n_ifaces
;
/*! \brief Pending changes to catalog member zones. */
/*! \brief Pending changes to catalog member zones
, update indication
. */
catalog_update_t
catalog_upd
;
atomic_bool
catalog_upd_signal
;
/*! \brief Context of pending zones' backup. */
zone_backup_ctxs_t
backup_ctxs
;
...
...
@@ -152,10 +166,11 @@ void server_wait(server_t *server);
* \brief Reload server configuration.
*
* \param server Server instance.
* \param mode Reload mode.
*
* \return Error code, KNOT_EOK if success.
*/
int
server_reload
(
server_t
*
server
);
int
server_reload
(
server_t
*
server
,
reload_t
mode
);
/*!
* \brief Requests server to stop.
...
...
@@ -169,6 +184,9 @@ void server_stop(server_t *server);
*
* Routine for dynamic server reconfiguration.
*
* \param conf Configuration.
* \param server Server instance.
*
* \return Error code, KNOT_EOK if success.
*/
int
server_reconfigure
(
conf_t
*
conf
,
server_t
*
server
);
...
...
@@ -177,5 +195,9 @@ int server_reconfigure(conf_t *conf, server_t *server);
* \brief Reconfigure zone database.
*
* Routine for dynamic server zones reconfiguration.
*
* \param conf Configuration.
* \param server Server instance.
* \param mode Reload mode.
*/
void
server_update_zones
(
conf_t
*
conf
,
server_t
*
server
);
void
server_update_zones
(
conf_t
*
conf
,
server_t
*
server
,
reload_t
mode
);
src/knot/updates/zone-update.c
View file @
cd71653b
...
...
@@ -14,10 +14,15 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include
<signal.h>
#include
<unistd.h>
#include
<urcu.h>
#include
"knot/catalog/interpret.h"
#include
"knot/common/log.h"
#include
"knot/common/systemd.h"
#include
"knot/dnssec/zone-events.h"
#include
"knot/server/server.h"
#include
"knot/updates/zone-update.h"
#include
"knot/zone/adds_tree.h"
#include
"knot/zone/adjust.h"
...
...
@@ -28,10 +33,6 @@
#include
"contrib/trim.h"
#include
"contrib/ucw/lists.h"
#include
<signal.h>
#include
<unistd.h>
#include
<urcu.h>
// Call mem_trim() whenever accumulated size of updated zones reaches this size.
#define UPDATE_MEMTRIM_AT (10 * 1024 * 1024)
...
...
@@ -783,6 +784,7 @@ static int update_catalog(conf_t *conf, zone_update_t *update)
if
(
ret
==
KNOT_EOK
)
{
log_zone_info
(
update
->
zone
->
name
,
"catalog reloaded, %zd updates"
,
upd_count
);
update
->
zone
->
server
->
catalog_upd_signal
=
true
;
if
(
kill
(
getpid
(),
SIGUSR1
)
!=
0
)
{
ret
=
knot_map_errno
();
}
...
...
src/knot/zone/zonedb-load.c
View file @
cd71653b
...
...
@@ -32,9 +32,6 @@
#include
"knot/zone/zonefile.h"
#include
"libknot/libknot.h"
#define FULL(conf) (!((conf)->io.flags & CONF_IO_FACTIVE) || \
((conf)->io.flags & CONF_IO_FRLD_ZONES))
static
bool
zone_file_updated
(
conf_t
*
conf
,
const
zone_t
*
old_zone
,
const
knot_dname_t
*
zone_name
)
{
...
...
@@ -278,14 +275,12 @@ static bool check_open_catalog(catalog_t *cat)
}
static
zone_t
*
reuse_member_zone
(
zone_t
*
zone
,
server_t
*
server
,
conf_t
*
conf
,
list_t
*
expired_contents
)
reload_t
mode
,
list_t
*
expired_contents
)
{
if
(
!
zone_get_flag
(
zone
,
ZONE_IS_CAT_MEMBER
,
false
))
{
return
NULL
;
}
bool
full
=
FULL
(
conf
);
catalog_upd_val_t
*
upd
=
catalog_update_get
(
&
server
->
catalog_upd
,
zone
->
name
);
if
(
upd
!=
NULL
)
{
switch
(
upd
->
type
)
{
...
...
@@ -295,10 +290,12 @@ static zone_t *reuse_member_zone(zone_t *zone, server_t *server, conf_t *conf,
ptrlist_add
(
expired_contents
,
zone_expire
(
zone
),
NULL
);
knot_sem_post
(
&
zone
->
cow_lock
);
// FALLTHROUGH
case
CAT_UPD_INVALID
:
case
CAT_UPD_MINOR
:
case
CAT_UPD_PROP
:
zone
->
change_type
=
CONF_IO_TRELOAD
;
break
;
// reload the member zone
case
CAT_UPD_INVALID
:
case
CAT_UPD_MINOR
:
return
zone
;
// reuse the member zone
case
CAT_UPD_REM
:
return
NULL
;
// remove the member zone
case
CAT_UPD_ADD
:
// cannot add existing member
...
...
@@ -306,9 +303,7 @@ static zone_t *reuse_member_zone(zone_t *zone, server_t *server, conf_t *conf,
assert
(
0
);
return
NULL
;
}
}
if
(
!
full
&&
(
upd
==
NULL
||
upd
->
type
!=
CAT_UPD_UNIQ
))
{
}
else
if
(
mode
&
(
RELOAD_COMMIT
|
RELOAD_CATALOG
))
{
return
zone
;
// reuse the member zone
}
...
...
@@ -400,11 +395,13 @@ static zone_t *add_member_zone(catalog_upd_val_t *val, knot_zonedb_t *check,
*
* \param conf New server configuration.
* \param server Server instance.
* \param mode Reload mode.
* \param expired_contents Out: ptrlist of zone_contents_t to be deep freed after sync RCU.
*
* \return New zone database.
*/
static
knot_zonedb_t
*
create_zonedb
(
conf_t
*
conf
,
server_t
*
server
,
list_t
*
expired_contents
)
static
knot_zonedb_t
*
create_zonedb
(
conf_t
*
conf
,
server_t
*
server
,
reload_t
mode
,
list_t
*
expired_contents
)
{
assert
(
conf
);
assert
(
server
);
...
...
@@ -415,10 +412,8 @@ static knot_zonedb_t *create_zonedb(conf_t *conf, server_t *server, list_t *expi
return
NULL
;
}
bool
full
=
FULL
(
conf
);
/* Mark changed zones. */
if
(
!
full
)
{
/* Mark changed zones during dynamic configuration. */
if
(
mode
==
RELOAD_COMMIT
)
{
mark_changed_zones
(
db_old
,
conf
->
io
.
zones
);
}
...
...
@@ -429,7 +424,7 @@ static knot_zonedb_t *create_zonedb(conf_t *conf, server_t *server, list_t *expi
const
knot_dname_t
*
name
=
conf_dname
(
&
id
);
zone_t
*
old_zone
=
knot_zonedb_find
(
db_old
,
name
);
if
(
old_zone
!=
NULL
&&
!
full
)
{
if
(
old_zone
!=
NULL
&&
(
mode
&
(
RELOAD_COMMIT
|
RELOAD_CATALOG
))
)
{
/* Reuse unchanged zone. */
if
(
!
(
old_zone
->
change_type
&
CONF_IO_TRELOAD
))
{
knot_zonedb_insert
(
db_new
,
old_zone
);
...
...
@@ -449,13 +444,14 @@ static knot_zonedb_t *create_zonedb(conf_t *conf, server_t *server, list_t *expi
knot_zonedb_insert
(
db_new
,
zone
);
}
/*
Remove deleted
cataloged zones
from conf
before catalog removals are commited. */
/*
Purge de
cataloged zones before catalog removals are commited. */
catalog_it_t
*
cat_it
=
catalog_it_begin
(
&
server
->
catalog_upd
);
while
(
!
catalog_it_finished
(
cat_it
))
{
catalog_upd_val_t
*
upd
=
catalog_it_val
(
cat_it
);
if
(
upd
->
type
==
CAT_UPD_REM
)
{
zone_t
*
zone
=
knot_zonedb_find
(
db_old
,
upd
->
member
);
if
(
zone
!=
NULL
)
{
zone
->
change_type
=
CONF_IO_TUNSET
;
zone_purge
(
conf
,
zone
);
}
}
...
...
@@ -474,7 +470,8 @@ static knot_zonedb_t *create_zonedb(conf_t *conf, server_t *server, list_t *expi
knot_zonedb_iter_t
*
it
=
knot_zonedb_iter_begin
(
db_old
);
while
(
!
knot_zonedb_iter_finished
(
it
))
{
zone_t
*
newzone
=
reuse_member_zone
(
knot_zonedb_iter_val
(
it
),
server
,
conf
,
expired_contents
);
server
,
conf
,
mode
,
expired_contents
);
if
(
newzone
!=
NULL
)
{
knot_zonedb_insert
(
db_new
,
newzone
);
}
...
...
@@ -536,14 +533,12 @@ static knot_zonedb_t *create_zonedb(conf_t *conf, server_t *server, list_t *expi
* \param server Server context.
*/
static
void
remove_old_zonedb
(
conf_t
*
conf
,
knot_zonedb_t
*
db_old
,
server_t
*
server
)
server_t
*
server
,
reload_t
mode
)
{
catalog_commit_cleanup
(
&
server
->
catalog
);
knot_zonedb_t
*
db_new
=
server
->
zone_db
;
bool
full
=
FULL
(
conf
);
if
(
db_old
==
NULL
)
{
goto
catalog_only
;
}
...
...
@@ -551,7 +546,7 @@ static void remove_old_zonedb(conf_t *conf, knot_zonedb_t *db_old,
knot_zonedb_iter_t
*
it
=
knot_zonedb_iter_begin
(
db_old
);
while
(
!
knot_zonedb_iter_finished
(
it
))
{
zone_t
*
zone
=
knot_zonedb_iter_val
(
it
);
if
(
full
)
{
if
(
mode
&
(
RELOAD_FULL
|
RELOAD_ZONES
)
)
{
/* Check if reloaded (reused contents). */
zone_t
*
new_zone
=
knot_zonedb_find
(
db_new
,
zone
->
name
);
if
(
new_zone
!=
NULL
)
{
...
...
@@ -565,7 +560,6 @@ static void remove_old_zonedb(conf_t *conf, knot_zonedb_t *db_old,
zone_t
*
new_zone
=
knot_zonedb_find
(
db_new
,
zone
->
name
);
assert
(
new_zone
);
replan_events
(
conf
,
new_zone
,
zone
);
zone
->
contents
=
NULL
;
zone_free
(
&
zone
);
/* Check if removed (drop also contents). */
...
...
@@ -584,27 +578,37 @@ catalog_only:
* thread while all zone events are paused. */
catalog_update_clear
(
&
server
->
catalog_upd
);
if
(
full
)
{
if
(
mode
&
(
RELOAD_FULL
|
RELOAD_ZONES
)
)
{
knot_zonedb_deep_free
(
&
db_old
,
false
);
}
else
{
knot_zonedb_free
(
&
db_old
);
}
}
void
zonedb_reload
(
conf_t
*
conf
,
server_t
*
server
)
void
zonedb_reload
(
conf_t
*
conf
,
server_t
*
server
,
reload_t
mode
)
{
if
(
conf
==
NULL
||
server
==
NULL
)
{
return
;
}
if
(
mode
==
RELOAD_COMMIT
)
{
assert
(
conf
->
io
.
flags
&
CONF_IO_FACTIVE
);
if
(
conf
->
io
.
flags
&
CONF_IO_FRLD_ZONES
)
{
mode
=
RELOAD_ZONES
;
}
}
list_t
contents_tofree
;
init_list
(
&
contents_tofree
);
catalog_update_finalize
(
&
server
->
catalog_upd
,
&
server
->
catalog
,
conf
);
log_info
(
"catalog, updating, %zu changes"
,
trie_weight
(
server
->
catalog_upd
.
upd
));
size_t
cat_upd_size
=
trie_weight
(
server
->
catalog_upd
.
upd
);
if
(
cat_upd_size
>
0
)
{
log_info
(
"catalog, updating, %zu changes"
,
cat_upd_size
);
}
/* Insert all required zones to the new zone DB. */
knot_zonedb_t
*
db_new
=
create_zonedb
(
conf
,
server
,
&
contents_tofree
);
knot_zonedb_t
*
db_new
=
create_zonedb
(
conf
,
server
,
mode
,
&
contents_tofree
);
if
(
db_new
==
NULL
)
{
log_error
(
"failed to create new zone database"
);
return
;
...
...
@@ -622,7 +626,7 @@ void zonedb_reload(conf_t *conf, server_t *server)
ptrlist_free_custom
(
&
contents_tofree
,
NULL
,
(
ptrlist_free_cb
)
zone_contents_deep_free
);
/* Remove old zone DB. */
remove_old_zonedb
(
conf
,
db_old
,
server
);
remove_old_zonedb
(
conf
,
db_old
,
server
,
mode
);
}
int
zone_reload_modules
(
conf_t
*
conf
,
server_t
*
server
,
const
knot_dname_t
*
zone_name
)
...
...
src/knot/zone/zonedb-load.h
View file @
cd71653b
/* Copyright (C) 202
0
CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 202
2
CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -22,10 +22,11 @@
/*!
* \brief Update zone database according to configuration.
*
* \param[in] conf Configuration.
* \param[in] server Server instance.
* \param conf Configuration.
* \param server Server instance.
* \param mode Reload mode.
*/
void
zonedb_reload
(
conf_t
*
conf
,
server_t
*
server
);
void
zonedb_reload
(
conf_t
*
conf
,
server_t
*
server
,
reload_t
mode
);
/*!
* \brief Re-create zone_t struct in zoneDB so that the zone is reloaded incl modules.
...
...
src/utils/knotd/main.c
View file @
cd71653b
...
...
@@ -259,11 +259,13 @@ static void event_loop(server_t *server, const char *socket)
/* Interrupts. */
if
(
sig_req_reload
&&
!
sig_req_stop
)
{
sig_req_reload
=
false
;
server_reload
(
server
);
server_reload
(
server
,
RELOAD_FULL
);
}
if
(
sig_req_zones_reload
&&
!
sig_req_stop
)
{
sig_req_zones_reload
=
false
;
server_update_zones
(
conf
(),
server
);
reload_t
mode
=
server
->
catalog_upd_signal
?
RELOAD_CATALOG
:
RELOAD_ZONES
;
server
->
catalog_upd_signal
=
false
;
server_update_zones
(
conf
(),
server
,
mode
);
}
if
(
sig_req_stop
)
{
break
;
...
...
@@ -571,7 +573,7 @@ int main(int argc, char **argv)
/* Populate zone database. */
log_info
(
"loading %zu zones"
,
conf_id_count
(
conf
(),
C_ZONE
));
server_update_zones
(
conf
(),
&
server
);
server_update_zones
(
conf
(),
&
server
,
RELOAD_ZONES
);
/* Check number of loaded zones. */
if
(
knot_zonedb_size
(
server
.
zone_db
)
==
0
)
{
...
...
tests-extra/tests/catalog/multi/test.py
View file @
cd71653b
...
...
@@ -58,14 +58,14 @@ master.ctl("zone-reload %s" % zone[1].name)
t
.
sleep
(
5
)
check_exists
(
master
,
"member1.example."
,
True
,
"First"
)
check_exists
(
master
,
"member2.example."
,
Tru
e
,
"First"
)
check_exists
(
master
,
"member3.example."
,
Tru
e
,
"First"
)
check_exists
(
master
,
"member2.example."
,
Fals
e
,
"First"
)
check_exists
(
master
,
"member3.example."
,
Fals
e
,
"First"
)
master
.
ctl
(
"zone-reload %s"
%
zone
[
2
].
name
)
t
.
sleep
(
5
)
check_exists
(
master
,
"member1.example."
,
True
,
"Second"
)
check_exists
(
master
,
"member2.example."
,
True
,
"Second"
)
check_exists
(
master
,
"member3.example."
,
Tru
e
,
"Second"
)
check_exists
(
master
,
"member3.example."
,
Fals
e
,
"Second"
)
t
.
end
()
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment