Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Knot DNS
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
22
Issues
22
List
Boards
Labels
Service Desk
Milestones
Merge Requests
18
Merge Requests
18
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Knot projects
Knot DNS
Commits
5fc62cd4
Commit
5fc62cd4
authored
Aug 25, 2017
by
Daniel Salzman
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'journal_serials' into 'master'
Journal serials See merge request
!801
parents
7c93631d
97579e3a
Pipeline
#14531
passed with stages
in 10 minutes and 58 seconds
Changes
12
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
201 additions
and
91 deletions
+201
-91
src/knot/events/handlers/refresh.c
src/knot/events/handlers/refresh.c
+1
-1
src/knot/journal/journal.c
src/knot/journal/journal.c
+72
-30
src/knot/journal/journal.h
src/knot/journal/journal.h
+4
-6
src/knot/nameserver/ixfr.c
src/knot/nameserver/ixfr.c
+2
-3
src/knot/nameserver/notify.c
src/knot/nameserver/notify.c
+1
-1
src/knot/updates/ddns.c
src/knot/updates/ddns.c
+1
-1
src/knot/updates/zone-update.c
src/knot/updates/zone-update.c
+1
-1
src/knot/zone/serial.c
src/knot/zone/serial.c
+18
-13
src/knot/zone/serial.h
src/knot/zone/serial.h
+40
-7
src/knot/zone/zone-diff.c
src/knot/zone/zone-diff.c
+2
-2
src/utils/kjournalprint/main.c
src/utils/kjournalprint/main.c
+39
-6
tests/test_zone_serial.c
tests/test_zone_serial.c
+20
-20
No files found.
src/knot/events/handlers/refresh.c
View file @
5fc62cd4
...
...
@@ -127,7 +127,7 @@ struct refresh_data {
static
bool
serial_is_current
(
uint32_t
local_serial
,
uint32_t
remote_serial
)
{
return
serial_compare
(
local_serial
,
remote_serial
)
>=
0
;
return
(
serial_compare
(
local_serial
,
remote_serial
)
&
SERIAL_MASK_GEQ
)
;
}
static
time_t
bootstrap_next
(
const
zone_timers_t
*
timers
)
...
...
src/knot/journal/journal.c
View file @
5fc62cd4
...
...
@@ -19,7 +19,6 @@
#include <stdarg.h>
#include "knot/journal/journal.h"
#include "knot/zone/serial.h"
#include "knot/common/log.h"
#include "contrib/files.h"
#include "contrib/endian.h"
...
...
@@ -534,7 +533,7 @@ static int md_flushed(txn_t *txn)
{
return
(
!
md_flag
(
txn
,
SERIAL_TO_VALID
)
||
(
md_flag
(
txn
,
LAST_FLUSHED_VALID
)
&&
serial_
compare
(
txn
->
shadow_md
.
last_flushed
,
txn
->
shadow_md
.
last_serial
)
==
0
));
serial_
equal
(
txn
->
shadow_md
.
last_flushed
,
txn
->
shadow_md
.
last_serial
)
));
}
static
void
make_header
(
knot_db_val_t
*
to
,
uint32_t
serial_to
,
int
chunk_count
)
...
...
@@ -851,7 +850,7 @@ static int load_merged_changeset(journal_t *j, txn_t *_txn, changeset_t **mch,
uint32_t
ms
=
txn
->
shadow_md
.
merged_serial
,
fl
=
txn
->
shadow_md
.
flags
;
if
((
fl
&
MERGED_SERIAL_VALID
)
&&
(
only_if_serial
==
NULL
||
serial_
compare
(
ms
,
*
only_if_serial
)
==
0
))
{
(
only_if_serial
==
NULL
||
serial_
equal
(
ms
,
*
only_if_serial
)
))
{
load_one
(
j
,
txn
,
ms
,
mch
);
}
unreuse_txn
(
txn
,
_txn
);
...
...
@@ -961,17 +960,17 @@ static int del_upto_itercb(iteration_ctx_t *ctx)
// If it's not merged changeset, point first_serial to next one
if
(
ctx
->
chunk_index
==
ctx
->
chunk_count
-
1
)
{
if
(
!
md_flag
(
ctx
->
txn
,
MERGED_SERIAL_VALID
)
||
serial_compare
(
ctx
->
txn
->
shadow_md
.
merged_serial
,
ctx
->
serial
)
!=
0
)
{
!
serial_equal
(
ctx
->
txn
->
shadow_md
.
merged_serial
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
first_serial
=
ctx
->
serial_to
;
ctx
->
txn
->
shadow_md
.
changeset_count
--
;
}
if
(
serial_
compare
(
ctx
->
txn
->
shadow_md
.
last_flushed
,
ctx
->
serial
)
==
0
)
{
if
(
serial_
equal
(
ctx
->
txn
->
shadow_md
.
last_flushed
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
flags
&=
~
LAST_FLUSHED_VALID
;
}
if
(
serial_
compare
(
ctx
->
txn
->
shadow_md
.
last_serial
,
ctx
->
serial
)
==
0
)
{
if
(
serial_
equal
(
ctx
->
txn
->
shadow_md
.
last_serial
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
flags
&=
~
SERIAL_TO_VALID
;
}
if
(
serial_
compare
(
ctx
->
txn
->
shadow_md
.
merged_serial
,
ctx
->
serial
)
==
0
)
{
if
(
serial_
equal
(
ctx
->
txn
->
shadow_md
.
merged_serial
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
flags
&=
~
MERGED_SERIAL_VALID
;
}
}
...
...
@@ -1034,11 +1033,11 @@ static int del_tofree_itercb(iteration_ctx_t *ctx)
if
(
ctx
->
chunk_index
==
ctx
->
chunk_count
-
1
)
{
ctx
->
txn
->
shadow_md
.
first_serial
=
ctx
->
serial_to
;
ctx
->
txn
->
shadow_md
.
changeset_count
--
;
if
(
serial_
compare
(
ctx
->
txn
->
shadow_md
.
last_flushed
,
ctx
->
serial
)
==
0
)
{
if
(
serial_
equal
(
ctx
->
txn
->
shadow_md
.
last_flushed
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
flags
&=
~
LAST_FLUSHED_VALID
;
ds
->
to_be_freed
=
0
;
// prevents deleting unflushed changesets
}
if
(
serial_
compare
(
ctx
->
txn
->
shadow_md
.
last_serial
,
ctx
->
serial
)
==
0
)
{
if
(
serial_
equal
(
ctx
->
txn
->
shadow_md
.
last_serial
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
flags
&=
~
SERIAL_TO_VALID
;
}
if
(
ds
->
freed_approx
>=
ds
->
to_be_freed
)
{
...
...
@@ -1090,11 +1089,11 @@ static int del_count_itercb(iteration_ctx_t *ctx)
if
(
ctx
->
chunk_index
==
ctx
->
chunk_count
-
1
)
{
ctx
->
txn
->
shadow_md
.
first_serial
=
ctx
->
serial_to
;
ctx
->
txn
->
shadow_md
.
changeset_count
--
;
if
(
serial_
compare
(
ctx
->
txn
->
shadow_md
.
last_flushed
,
ctx
->
serial
)
==
0
)
{
if
(
serial_
equal
(
ctx
->
txn
->
shadow_md
.
last_flushed
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
flags
&=
~
LAST_FLUSHED_VALID
;
ds
->
to_be_freed
=
ds
->
freed_approx
;
// prevents deleting unflushed changesets
}
if
(
serial_
compare
(
ctx
->
txn
->
shadow_md
.
last_serial
,
ctx
->
serial
)
==
0
)
{
if
(
serial_
equal
(
ctx
->
txn
->
shadow_md
.
last_serial
,
ctx
->
serial
)
)
{
ctx
->
txn
->
shadow_md
.
flags
&=
~
SERIAL_TO_VALID
;
}
ds
->
freed_approx
++
;
...
...
@@ -1203,7 +1202,7 @@ static int merge_unflushed_changesets(journal_t *j, txn_t *_txn, changeset_t **m
}
from
=
knot_soa_serial
(
&
(
*
mch
)
->
soa_to
->
rrs
);
if
(
serial_compare
(
from
,
txn
->
shadow_md
.
last_serial_to
)
!=
0
)
{
if
(
!
serial_equal
(
from
,
txn
->
shadow_md
.
last_serial_to
)
)
{
txn
->
ret
=
iterate
(
j
,
txn
,
merge_itercb
,
JOURNAL_ITERATION_CHANGESETS
,
mch
,
from
,
txn
->
shadow_md
.
last_serial
,
normal_iterkeycb
);
}
...
...
@@ -1353,7 +1352,7 @@ static int store_changesets(journal_t *j, list_t *changesets)
bool
is_first_bootstrap
=
(
chs_head
->
soa_from
==
NULL
);
uint32_t
serial
=
is_first_bootstrap
?
0
:
knot_soa_serial
(
&
chs_head
->
soa_from
->
rrs
);
if
(
md_flag
(
txn
,
SERIAL_TO_VALID
)
&&
(
is_first_bootstrap
||
serial_compare
(
txn
->
shadow_md
.
last_serial_to
,
serial
)
!=
0
)
&&
!
serial_equal
(
txn
->
shadow_md
.
last_serial_to
,
serial
)
)
&&
!
inserting_bootstrap
/* if inserting bootstrap, drop_journal() was called, so no discontinuity */
)
{
log_zone_warning
(
j
->
zone
,
"journal, discontinuity in changes history (%u -> %u), dropping older changesets"
,
txn
->
shadow_md
.
last_serial_to
,
serial
);
...
...
@@ -1388,9 +1387,9 @@ static int store_changesets(journal_t *j, list_t *changesets)
}
}
else
{
try_flush
delete_upto
(
j
,
txn
,
txn
->
shadow_md
.
first_serial
,
serial_to
);
txn_restart
(
txn
);
}
delete_upto
(
j
,
txn
,
txn
->
shadow_md
.
first_serial
,
serial_to
);
txn_restart
(
txn
);
}
}
...
...
@@ -1796,12 +1795,31 @@ scrape_end:
return
txn
->
ret
;
}
void
journal_metadata_info
(
journal_t
*
j
,
bool
*
is_empty
,
uint32_t
*
serial_from
,
uint32_t
*
serial_to
)
void
journal_metadata_info
(
journal_t
*
j
,
bool
*
has_bootstrap
,
kserial_t
*
merged_serial
,
kserial_t
*
first_serial
,
kserial_t
*
last_flushed
,
kserial_t
*
serial_to
,
uint64_t
*
occupied
)
{
// NOTE: there is NEVER the situation that only merged changeset would be present and no common changeset in db.
if
(
j
==
NULL
||
j
->
db
==
NULL
)
{
*
is_empty
=
true
;
if
(
has_bootstrap
!=
NULL
)
{
*
has_bootstrap
=
false
;
}
if
(
merged_serial
!=
NULL
)
{
merged_serial
->
valid
=
false
;
}
if
(
first_serial
!=
NULL
)
{
first_serial
->
valid
=
false
;
}
if
(
last_flushed
!=
NULL
)
{
last_flushed
->
valid
=
false
;
}
if
(
serial_to
!=
NULL
)
{
serial_to
->
valid
=
false
;
}
if
(
occupied
!=
NULL
)
{
*
occupied
=
0
;
}
return
;
}
...
...
@@ -1809,13 +1827,37 @@ void journal_metadata_info(journal_t *j, bool *is_empty, uint32_t *serial_from,
txn_begin
(
txn
,
false
);
txn_check_open
(
txn
);
*
is_empty
=
!
md_flag
(
txn
,
SERIAL_TO_VALID
);
*
serial_from
=
txn
->
shadow_md
.
first_serial
;
*
serial_to
=
txn
->
shadow_md
.
last_serial_to
;
if
(
md_flag
(
txn
,
MERGED_SERIAL_VALID
))
{
*
serial_from
=
txn
->
shadow_md
.
merged_serial
;
if
(
has_bootstrap
!=
NULL
)
{
*
has_bootstrap
=
has_bootstrap_changeset
(
j
,
txn
);
}
if
(
merged_serial
!=
NULL
)
{
merged_serial
->
valid
=
md_flag
(
txn
,
MERGED_SERIAL_VALID
);
merged_serial
->
serial
=
txn
->
shadow_md
.
merged_serial
;
}
if
(
first_serial
!=
NULL
)
{
first_serial
->
valid
=
!
md_flag
(
txn
,
FIRST_SERIAL_INVALID
);
first_serial
->
serial
=
txn
->
shadow_md
.
first_serial
;
}
if
(
last_flushed
!=
NULL
)
{
last_flushed
->
valid
=
md_flag
(
txn
,
LAST_FLUSHED_VALID
);
last_flushed
->
serial
=
txn
->
shadow_md
.
last_flushed
;
}
if
(
serial_to
!=
NULL
)
{
serial_to
->
valid
=
md_flag
(
txn
,
SERIAL_TO_VALID
);
serial_to
->
serial
=
txn
->
shadow_md
.
last_serial_to
;
}
if
(
occupied
!=
NULL
)
{
md_get
(
txn
,
j
->
zone
,
MDKEY_PERZONE_OCCUPIED
,
occupied
);
knot_dname_t
*
last_inserter
=
NULL
;
md_get_common_last_inserter_zone
(
txn
,
&
last_inserter
);
if
(
last_inserter
!=
NULL
&&
knot_dname_is_equal
(
last_inserter
,
j
->
zone
))
{
size_t
lz_occupied
;
md_get_common_last_occupied
(
txn
,
&
lz_occupied
);
*
occupied
+=
lz_occupied
;
}
free
(
last_inserter
);
}
txn_abort
(
txn
);
}
...
...
@@ -1993,7 +2035,7 @@ int journal_check(journal_t *j, journal_check_level_t warn_level)
}
sfrom
=
knot_soa_serial
(
&
ch
->
soa_from
->
rrs
),
sto
=
knot_soa_serial
(
&
ch
->
soa_to
->
rrs
);
if
(
serial_compare
(
txn
->
shadow_md
.
first_serial
,
sfrom
)
!=
0
)
{
if
(
!
serial_equal
(
txn
->
shadow_md
.
first_serial
,
sfrom
)
)
{
jch_warn
(
"first changeset's serial 'from' %u is not ok"
,
sfrom
);
}
...
...
@@ -2012,7 +2054,7 @@ int journal_check(journal_t *j, journal_check_level_t warn_level)
changeset_free
(
ch
);
}
if
(
serial_
compare
(
txn
->
shadow_md
.
last_serial_to
,
sto
)
==
0
)
{
if
(
serial_
equal
(
txn
->
shadow_md
.
last_serial_to
,
sto
)
)
{
jch_info
(
"there is just one changeset in the journal"
);
goto
check_merged
;
}
...
...
@@ -2022,7 +2064,7 @@ int journal_check(journal_t *j, journal_check_level_t warn_level)
}
else
{
sfrom
=
knot_soa_serial
(
&
ch
->
soa_from
->
rrs
);
if
(
serial_compare
(
sfrom
,
sto
)
!=
0
)
{
if
(
!
serial_equal
(
sfrom
,
sto
)
)
{
jch_warn
(
"second changeset's serial 'from' %u is not ok"
,
sfrom
);
}
changeset_free
(
ch
);
...
...
@@ -2046,12 +2088,12 @@ int journal_check(journal_t *j, journal_check_level_t warn_level)
}
ch
=
HEAD
(
l
);
if
(
serial_compare
(
sfrom
,
knot_soa_serial
(
&
ch
->
soa_from
->
rrs
))
!=
0
)
{
if
(
!
serial_equal
(
sfrom
,
knot_soa_serial
(
&
ch
->
soa_from
->
rrs
))
)
{
jch_warn
(
"first listed changeset's serial 'from' %u is not ok"
,
knot_soa_serial
(
&
ch
->
soa_from
->
rrs
));
}
ch
=
TAIL
(
l
);
if
(
serial_compare
(
sto
,
knot_soa_serial
(
&
ch
->
soa_to
->
rrs
))
!=
0
)
{
if
(
!
serial_equal
(
sto
,
knot_soa_serial
(
&
ch
->
soa_to
->
rrs
))
)
{
jch_warn
(
"last listed changeset's serial 'to' %u is not ok"
,
knot_soa_serial
(
&
ch
->
soa_to
->
rrs
));
}
...
...
@@ -2072,10 +2114,10 @@ check_merged:
sto
=
knot_soa_serial
(
&
ch
->
soa_to
->
rrs
);
jch_info
(
"merged changeset %u -> %u (size %zu)"
,
sfrom
,
sto
,
changeset_serialized_size
(
ch
));
if
(
serial_compare
(
sfrom
,
txn
->
shadow_md
.
merged_serial
)
!=
0
)
{
if
(
!
serial_equal
(
sfrom
,
txn
->
shadow_md
.
merged_serial
)
)
{
jch_warn
(
"merged changeset's serial 'from' is not ok"
);
}
if
(
serial_compare
(
sto
,
first_unflushed
)
!=
0
)
{
if
(
!
serial_equal
(
sto
,
first_unflushed
)
)
{
jch_warn
(
"merged changeset's serial 'to' is not ok"
);
}
changeset_free
(
ch
);
...
...
src/knot/journal/journal.h
View file @
5fc62cd4
...
...
@@ -22,6 +22,7 @@
#include "contrib/ucw/lists.h"
#include "knot/updates/changesets.h"
#include "knot/journal/serialization.h"
#include "knot/zone/serial.h"
/*! \brief Minimum journal size. */
#define JOURNAL_MIN_FSLIMIT (1 * 1024 * 1024)
...
...
@@ -209,13 +210,10 @@ int journal_flush(journal_t *journal);
int
journal_scrape
(
journal_t
*
j
);
/*! \brief Obtain public information from journal metadata
*
* \param[in] j Journal
* \param[out] is_empty True if j contains no changesets
* \param[out] serial_from [if !is_empty] starting serial of changesets history
* \param[out] serial_to [if !is_empty] ending serial of changesets history
*/
void
journal_metadata_info
(
journal_t
*
j
,
bool
*
is_empty
,
uint32_t
*
serial_from
,
uint32_t
*
serial_to
);
void
journal_metadata_info
(
journal_t
*
j
,
bool
*
is_empty
,
kserial_t
*
merged_serial
,
kserial_t
*
first_serial
,
kserial_t
*
last_flushed
,
kserial_t
*
serial_to
,
uint64_t
*
occupied
);
/*! \brief Check the journal consistency, errors to stderr.
*
...
...
src/knot/nameserver/ixfr.c
View file @
5fc62cd4
...
...
@@ -143,12 +143,11 @@ static int ixfr_load_chsets(list_t *chgsets, zone_t *zone,
/* Compare serials. */
uint32_t
serial_to
=
zone_contents_serial
(
zone
->
contents
);
uint32_t
serial_from
=
knot_soa_serial
(
&
their_soa
->
rrs
);
int
ret
=
serial_compare
(
serial_to
,
serial_from
);
if
(
ret
<=
0
)
{
/* We have older/same age zone. */
if
(
serial_compare
(
serial_to
,
serial_from
)
&
SERIAL_MASK_LEQ
)
{
/* We have older/same age zone. */
return
KNOT_EUPTODATE
;
}
ret
=
zone_changes_load
(
conf
(),
zone
,
chgsets
,
serial_from
);
int
ret
=
zone_changes_load
(
conf
(),
zone
,
chgsets
,
serial_from
);
if
(
ret
!=
KNOT_EOK
)
{
changesets_free
(
chgsets
);
}
...
...
src/knot/nameserver/notify.c
View file @
5fc62cd4
...
...
@@ -70,7 +70,7 @@ int notify_process_query(knot_pkt_t *pkt, knotd_qdata_t *qdata)
uint32_t
serial
=
knot_soa_serial
(
&
soa
->
rrs
);
uint32_t
zone_serial
=
zone_contents_serial
(
zone
->
contents
);
NOTIFY_LOG
(
LOG_INFO
,
qdata
,
"received, serial %u"
,
serial
);
if
(
serial_
compare
(
serial
,
zone_serial
)
==
0
)
{
if
(
serial_
equal
(
serial
,
zone_serial
)
)
{
// NOTIFY serial == zone serial => ignore, keep timers
return
KNOT_STATE_DONE
;
}
...
...
src/knot/updates/ddns.c
View file @
5fc62cd4
...
...
@@ -316,7 +316,7 @@ static bool skip_soa(const knot_rrset_t *rr, int64_t sn)
{
if
(
rr
->
type
==
KNOT_RRTYPE_SOA
&&
(
rr
->
rclass
==
KNOT_CLASS_NONE
||
rr
->
rclass
==
KNOT_CLASS_ANY
||
serial_compare
(
knot_soa_serial
(
&
rr
->
rrs
),
sn
)
<=
0
))
{
(
serial_compare
(
knot_soa_serial
(
&
rr
->
rrs
),
sn
)
!=
SERIAL_GREATER
)
))
{
return
true
;
}
...
...
src/knot/updates/zone-update.c
View file @
5fc62cd4
...
...
@@ -484,7 +484,7 @@ static int set_new_soa(zone_update_t *update, unsigned serial_policy)
uint32_t
old_serial
=
knot_soa_serial
(
&
soa_cpy
->
rrs
);
uint32_t
new_serial
=
serial_next
(
old_serial
,
serial_policy
);
if
(
serial_compare
(
old_serial
,
new_serial
)
>=
0
)
{
if
(
serial_compare
(
old_serial
,
new_serial
)
!=
SERIAL_LOWER
)
{
log_zone_warning
(
update
->
zone
->
name
,
"updated serial is lower "
"than current, serial %u -> %u"
,
old_serial
,
new_serial
);
...
...
src/knot/zone/serial.c
View file @
5fc62cd4
/* Copyright (C) 201
5
CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 201
7
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
...
...
@@ -20,22 +20,22 @@
#include "knot/conf/conf.h"
#include "knot/zone/serial.h"
static
int32_t
serial_difference
(
uint32_t
s1
,
uint32_t
s2
)
{
return
(((
int64_t
)
s1
-
s2
)
%
((
int64_t
)
1
<<
32
));
}
static
const
serial_cmp_result_t
diffbrief2result
[
4
]
=
{
[
0
]
=
SERIAL_EQUAL
,
[
1
]
=
SERIAL_GREATER
,
[
2
]
=
SERIAL_INCOMPARABLE
,
[
3
]
=
SERIAL_LOWER
,
};
in
t
serial_compare
(
uint32_t
s1
,
uint32_t
s2
)
serial_cmp_result_
t
serial_compare
(
uint32_t
s1
,
uint32_t
s2
)
{
int32_t
diff
=
serial_difference
(
s1
,
s2
);
return
(
s1
==
s2
)
/* s1 equal to s2 */
?
0
:
((
diff
>=
1
&&
diff
<
((
uint32_t
)
1
<<
31
))
?
1
/* s1 larger than s2 */
:
-
1
);
/* s1 less than s2 */
uint64_t
diff
=
((
uint64_t
)
s1
+
((
uint64_t
)
1
<<
32
)
-
s2
)
&
0xffffffff
;
int
diffbrief
=
(
diff
>>
31
<<
1
)
|
((
diff
&
0x7fffffff
)
?
1
:
0
);
assert
(
diffbrief
>
-
1
&&
diffbrief
<
4
);
return
diffbrief2result
[
diffbrief
];
}
in
t
serial_next
(
uint32_t
current
,
int
policy
)
uint32_
t
serial_next
(
uint32_t
current
,
int
policy
)
{
switch
(
policy
)
{
case
SERIAL_POLICY_INCREMENT
:
...
...
@@ -47,3 +47,8 @@ int serial_next(uint32_t current, int policy)
return
0
;
}
}
serial_cmp_result_t
kserial_cmp
(
kserial_t
a
,
kserial_t
b
)
{
return
((
a
.
valid
&&
b
.
valid
)
?
serial_compare
(
a
.
serial
,
b
.
serial
)
:
SERIAL_INCOMPARABLE
);
}
src/knot/zone/serial.h
View file @
5fc62cd4
/* Copyright (C) 201
5
CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 201
7
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
...
...
@@ -16,16 +16,32 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
/*!
* \brief
Compares two zone serials
.
* \brief
result of serial comparison. LOWER means that the first serial is lower that the second
.
*
* \retval < 0 if s1 is less than s2.
* \retval > 0 if s1 is larger than s2.
* \retval == 0 if s1 is equal to s2.
* Example: (serial_compare(a, b) & SERIAL_MASK_LEQ) means "a <= b".
*/
typedef
enum
{
SERIAL_INCOMPARABLE
=
0x0
,
SERIAL_LOWER
=
0x1
,
SERIAL_GREATER
=
0x2
,
SERIAL_EQUAL
=
0x3
,
SERIAL_MASK_LEQ
=
SERIAL_LOWER
,
SERIAL_MASK_GEQ
=
SERIAL_GREATER
,
}
serial_cmp_result_t
;
/*!
* \brief Compares two zone serials.
*/
int
serial_compare
(
uint32_t
s1
,
uint32_t
s2
);
serial_cmp_result_t
serial_compare
(
uint32_t
s1
,
uint32_t
s2
);
inline
static
bool
serial_equal
(
uint32_t
a
,
uint32_t
b
)
{
return
serial_compare
(
a
,
b
)
==
SERIAL_EQUAL
;
}
/*!
* \brief Get next serial for given serial update policy.
...
...
@@ -35,4 +51,21 @@ int serial_compare(uint32_t s1, uint32_t s2);
*
* \return New serial.
*/
int
serial_next
(
uint32_t
current
,
int
policy
);
uint32_t
serial_next
(
uint32_t
current
,
int
policy
);
typedef
struct
{
uint32_t
serial
;
bool
valid
;
}
kserial_t
;
/*!
* \brief Compares two kserials.
*
* If any of them is invalid, they are INCOMPARABLE.
*/
serial_cmp_result_t
kserial_cmp
(
kserial_t
a
,
kserial_t
b
);
inline
static
bool
kserial_equal
(
kserial_t
a
,
kserial_t
b
)
{
return
kserial_cmp
(
a
,
b
)
==
SERIAL_EQUAL
;
}
src/knot/zone/zone-diff.c
View file @
5fc62cd4
...
...
@@ -54,11 +54,11 @@ static int load_soas(const zone_contents_t *zone1, const zone_contents_t *zone2,
uint32_t
soa_serial1
=
knot_soa_serial
(
&
soa_rrset1
.
rrs
);
uint32_t
soa_serial2
=
knot_soa_serial
(
&
soa_rrset2
.
rrs
);
if
(
serial_compare
(
soa_serial1
,
soa_serial2
)
==
0
)
{
if
(
serial_compare
(
soa_serial1
,
soa_serial2
)
==
SERIAL_EQUAL
)
{
return
KNOT_ENODIFF
;
}
if
(
serial_compare
(
soa_serial1
,
soa_serial2
)
>
0
)
{
if
(
serial_compare
(
soa_serial1
,
soa_serial2
)
!=
SERIAL_LOWER
)
{
return
KNOT_ERANGE
;
}
...
...
src/utils/kjournalprint/main.c
View file @
5fc62cd4
...
...
@@ -188,17 +188,24 @@ int print_journal(char *path, knot_dname_t *name, uint32_t limit, bool color, bo
return
ret
;
}
bool
is_empty
;
uint32_t
serial_from
,
serial_to
;
journal_metadata_info
(
j
,
&
is_empty
,
&
serial_from
,
&
serial_to
);
bool
has_bootstrap
;
kserial_t
merged_serial
,
serial_from
,
last_flushed
,
serial_to
;
uint64_t
occupied
;
journal_metadata_info
(
j
,
&
has_bootstrap
,
&
merged_serial
,
&
serial_from
,
&
last_flushed
,
&
serial_to
,
&
occupied
);
bool
alternative_from
=
(
has_bootstrap
||
merged_serial
.
valid
);
bool
is_empty
=
(
!
alternative_from
&&
!
serial_from
.
valid
);
if
(
is_empty
)
{
ret
=
KNOT_ENOENT
;
goto
pj_finally
;
}
ret
=
journal_load_bootstrap
(
j
,
&
db
);
if
(
ret
==
KNOT_ENOENT
)
{
ret
=
journal_load_changesets
(
j
,
&
db
,
serial_from
);
if
(
has_bootstrap
)
{
ret
=
journal_load_bootstrap
(
j
,
&
db
);
}
else
if
(
merged_serial
.
valid
)
{
ret
=
journal_load_changesets
(
j
,
&
db
,
merged_serial
.
serial
);
}
else
{
ret
=
journal_load_changesets
(
j
,
&
db
,
serial_from
.
serial
);
}
if
(
ret
!=
KNOT_EOK
)
{
goto
pj_finally
;
...
...
@@ -221,6 +228,32 @@ int print_journal(char *path, knot_dname_t *name, uint32_t limit, bool color, bo
changesets_free
(
&
db
);
if
(
debugmode
)
{
if
((
alternative_from
&&
serial_from
.
valid
)
||
kserial_equal
(
serial_from
,
last_flushed
))
{
printf
(
"---- Additional history ----
\n
"
);
init_list
(
&
db
);
ret
=
journal_load_changesets
(
j
,
&
db
,
serial_from
.
serial
);
if
(
ret
!=
KNOT_EOK
)
{
goto
pj_finally
;
}
WALK_LIST
(
chs
,
db
)
{
print_changeset_debugmode
(
chs
);
if
(
last_flushed
.
valid
&&
serial_equal
(
knot_soa_serial
(
&
chs
->
soa_from
->
rrs
),
last_flushed
.
serial
))
{
break
;
}
}
changesets_free
(
&
db
);
}
else
{
printf
(
"---- No additional history ----
\n
"
);
}
}
if
(
debugmode
)
{
printf
(
"Occupied: %lu KiB
\n
"
,
occupied
/
1024
);
}
pj_finally:
journal_close
(
j
);
journal_free
(
&
j
);
...
...
tests/test_zone_serial.c
View file @
5fc62cd4
...
...
@@ -43,59 +43,59 @@ int main(int argc, char *argv[])
plan
(
20
);
/* Serial compare test. */
ok
(
serial_compare
(
S_LOWEST
,
S_BELOW_MIDDLE
)
<
0
,
ok
(
serial_compare
(
S_LOWEST
,
S_BELOW_MIDDLE
)
==
SERIAL_LOWER
,
"serial compare: lowest < below middle"
);
ok
(
serial_compare
(
S_BELOW_MIDDLE
,
S_LOWEST
)
>
0
,
ok
(
serial_compare
(
S_BELOW_MIDDLE
,
S_LOWEST
)
==
SERIAL_GREATER
,
"serial compare: below middle > lowest"
);
/* Corner-case: these serials' distance is exactly 2^31. */
ok
(
serial_compare
(
S_LOWEST
,
S_ABOVE_MIDDLE
)
<
0
,
ok
(
serial_compare
(
S_LOWEST
,
S_ABOVE_MIDDLE
)
==
SERIAL_INCOMPARABLE
,
"serial compare: lowest < above_middle"
);
ok
(
serial_compare
(
S_ABOVE_MIDDLE
,
S_LOWEST
)
<
0
,
ok
(
serial_compare
(
S_ABOVE_MIDDLE
,
S_LOWEST
)
==
SERIAL_INCOMPARABLE
,
"serial compare: above_middle < lowest"
);
ok
(
serial_compare
(
S_LOWEST
,
S_HIGHEST
)
>
0
,
ok
(
serial_compare
(
S_LOWEST
,
S_HIGHEST
)
==
SERIAL_GREATER
,
"serial compare: lowest > highest"
);
ok
(
serial_compare
(
S_HIGHEST
,
S_LOWEST
)
<
0
,
ok
(
serial_compare
(
S_HIGHEST
,
S_LOWEST
)
==
SERIAL_LOWER
,
"serial compare: highest < lowest"
);
ok
(
serial_compare
(
S_2LOWEST
,
S_ABOVE_MIDDLE
)
<
0
,
ok
(
serial_compare
(
S_2LOWEST
,
S_ABOVE_MIDDLE
)
==
SERIAL_LOWER
,
"serial compare: 2nd lowest < above middle"
);
ok
(
serial_compare
(
S_ABOVE_MIDDLE
,
S_2LOWEST
)
>
0
,
ok
(
serial_compare
(
S_ABOVE_MIDDLE
,
S_2LOWEST
)
==
SERIAL_GREATER
,
"serial compare: above middle > 2nd lowest"
);
/* Corner-case: these serials' distance is exactly 2^31. */
ok
(
serial_compare
(
S_BELOW_MIDDLE
,
S_HIGHEST
)
<
0
,
ok
(
serial_compare
(
S_BELOW_MIDDLE
,
S_HIGHEST
)
==
SERIAL_INCOMPARABLE
,
"serial compare: below middle < highest"
);
ok
(
serial_compare
(
S_HIGHEST
,
S_BELOW_MIDDLE
)
<
0
,
ok
(
serial_compare
(
S_HIGHEST
,
S_BELOW_MIDDLE
)
==
SERIAL_INCOMPARABLE
,
"serial compare: highest < below middle"
);
ok
(
serial_compare
(
S_BELOW_MIDDLE
,
S_2HIGHEST
)
<
0
,
ok
(
serial_compare
(
S_BELOW_MIDDLE
,
S_2HIGHEST
)
==
SERIAL_LOWER
,
"serial compare: below middle < 2nd highest"
);
ok
(
serial_compare
(
S_2HIGHEST
,
S_BELOW_MIDDLE
)
>
0
,
ok
(
serial_compare
(
S_2HIGHEST
,
S_BELOW_MIDDLE
)
==
SERIAL_GREATER
,
"serial compare: 2nd highest > below middle"
);
ok
(
serial_compare
(
S_ABOVE_MIDDLE
,
S_HIGHEST
)
<
0
,
ok
(
serial_compare
(
S_ABOVE_MIDDLE
,
S_HIGHEST
)
==
SERIAL_LOWER
,
"serial compare: above middle < highest"
);
ok
(
serial_compare
(
S_HIGHEST
,
S_ABOVE_MIDDLE
)
>
0
,
ok
(
serial_compare
(
S_HIGHEST
,
S_ABOVE_MIDDLE
)
==
SERIAL_GREATER
,
"serial compare: highest > above middle"
);
ok
(
serial_compare
(
S_LOWEST
,
S_LOWEST
)
==
0
,
ok
(
serial_compare
(
S_LOWEST
,
S_LOWEST
)
==
SERIAL_EQUAL
,
"serial compare: lowest == lowest"
);
ok
(
serial_compare
(
S_HIGHEST
,
S_HIGHEST
)
==
0
,
ok
(
serial_compare
(
S_HIGHEST
,
S_HIGHEST
)
==
SERIAL_EQUAL
,
"serial compare: highest == highest"
);
ok
(
serial_compare
(
S_LOWEST
-
1
,
S_HIGHEST
)
==
0
,
ok
(
serial_compare
(
S_LOWEST
-
1
,
S_HIGHEST
)
==
SERIAL_EQUAL
,
"serial compare: lowest - 1 == highest"
);
ok
(
serial_compare
(
S_LOWEST
,
S_HIGHEST
+
1
)
==
0
,
ok
(
serial_compare
(
S_LOWEST
,
S_HIGHEST
+
1
)
==
SERIAL_EQUAL
,
"serial compare: lowest== highest + 1"
);
/* Corner-case: these serials' distance is exactly 2^31. */
uint32_t
s1
=
random_serial
();
uint32_t
s2
=
s1
+
S_ABOVE_MIDDLE
;
// exactly the 'opposite' number
ok
(
serial_compare
(
s1
,
s2
)
<
0
,
ok
(
serial_compare
(
s1
,
s2
)
==
SERIAL_INCOMPARABLE
,
"serial compare: random opposites (s1 < s2)"
);
ok
(
serial_compare
(
s2
,
s1
)
<
0
,
ok
(
serial_compare
(
s2
,
s1
)
==
SERIAL_INCOMPARABLE
,
"serial compare: random opposites (s2 < s1)"
);
return
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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