BIND 10 master, updated. c4004066611a83ea5589af57bf07172da5a4aa94 Merge branch 'trac3006'
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Jun 30 15:11:51 UTC 2013
The branch, master has been updated
via c4004066611a83ea5589af57bf07172da5a4aa94 (commit)
via fcbb1a926c62a986d97566002bf318822161a5e4 (commit)
via f1c399008dea27eed1200e392afd08929c5f9f96 (commit)
via b99e16aa62aae9000905822f4a76bec8fff3591a (commit)
via 7a55d6839c96bc41cb440e30822e219911ed2ea1 (commit)
via df2c166741be35284c9a7711b28513fa0f5a128c (commit)
via 38ff6231fc72640e2d67de0583a6af1bb98a1e3d (commit)
via f3599de81907489d828748988c660d644257f0fe (commit)
via 51861a16ff9aa86bda48baaca5cac0c37eb10dfc (commit)
via 0507bba4a8dcbd4a3e7f0f6ad03eb5df6068201f (commit)
via 7e343de52c027ac35f231f906cfdd19500e8b7c1 (commit)
via 46544d453c97522254fcbef13fb57c67be622cb5 (commit)
via bdf66e1261cd868e356392e478b0361fcca349b8 (commit)
via d6b484dc1a2689bf7fc8f1cfe2454ddb025b2a01 (commit)
via 8cb8350f576413a4a5f0cf6fda366219ab316b89 (commit)
via 472b197fab494c18fa3ed25018176997da20c22a (commit)
via 8c4f48f99c0a25c37b15f7819aa5c01a3a1b6844 (commit)
via bd4a777c870eb78b1cdfc6df2c8e13ea93480c12 (commit)
via 5485e7248939b67d6dc94b18925cee753df14390 (commit)
via df956ae5a69124cdfd7704ef0582adfe254df802 (commit)
from aa0265f874883431407a6ed6a2f0d543fc4e8507 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c4004066611a83ea5589af57bf07172da5a4aa94
Merge: aa0265f fcbb1a9
Author: Mukund Sivaraman <muks at isc.org>
Date: Sun Jun 30 20:09:17 2013 +0530
Merge branch 'trac3006'
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 10 +
doc/Makefile.am | 2 +-
doc/design/Makefile.am | 1 +
doc/design/datasrc/.gitignore | 3 +
doc/design/datasrc/Makefile.am | 30 +++
doc/design/datasrc/auth-local.txt | 137 ++++++++++
doc/design/datasrc/auth-mapped.txt | 98 ++++++++
doc/design/datasrc/data-source-classes.txt | 364 +++++++++++++++++++++++++++
doc/design/datasrc/memmgr-mapped-init.txt | 132 ++++++++++
doc/design/datasrc/memmgr-mapped-reload.txt | 92 +++++++
doc/design/datasrc/overview.txt | 68 +++++
11 files changed, 936 insertions(+), 1 deletion(-)
create mode 100644 doc/design/Makefile.am
create mode 100644 doc/design/datasrc/.gitignore
create mode 100644 doc/design/datasrc/Makefile.am
create mode 100644 doc/design/datasrc/auth-local.txt
create mode 100644 doc/design/datasrc/auth-mapped.txt
create mode 100644 doc/design/datasrc/data-source-classes.txt
create mode 100644 doc/design/datasrc/memmgr-mapped-init.txt
create mode 100644 doc/design/datasrc/memmgr-mapped-reload.txt
create mode 100644 doc/design/datasrc/overview.txt
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 8c01aa6..c88dc53 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1132,6 +1132,14 @@ AC_ARG_ENABLE(logger-checks, [AC_HELP_STRING([--enable-logger-checks],
AM_CONDITIONAL(ENABLE_LOGGER_CHECKS, test x$enable_logger_checks != xno)
AM_COND_IF([ENABLE_LOGGER_CHECKS], [AC_DEFINE([ENABLE_LOGGER_CHECKS], [1], [Check logger messages?])])
+# Check for asciidoc
+AC_PATH_PROG(ASCIIDOC, asciidoc, no)
+AM_CONDITIONAL(HAVE_ASCIIDOC, test "x$ASCIIDOC" != "xno")
+
+# Check for plantuml
+AC_PATH_PROG(PLANTUML, plantuml, no)
+AM_CONDITIONAL(HAVE_PLANTUML, test "x$PLANTUML" != "xno")
+
# Check for valgrind
AC_PATH_PROG(VALGRIND, valgrind, no)
AM_CONDITIONAL(HAVE_VALGRIND, test "x$VALGRIND" != "xno")
@@ -1171,6 +1179,8 @@ AM_COND_IF([HAVE_OPTRESET], [AC_DEFINE([HAVE_OPTRESET], [1], [Check for optreset
AC_CONFIG_FILES([Makefile
doc/Makefile
doc/guide/Makefile
+ doc/design/Makefile
+ doc/design/datasrc/Makefile
compatcheck/Makefile
src/Makefile
src/bin/Makefile
diff --git a/doc/Makefile.am b/doc/Makefile.am
index e08de67..4af8188 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = guide
+SUBDIRS = guide design
EXTRA_DIST = version.ent.in differences.txt Doxyfile Doxyfile-xml
diff --git a/doc/design/Makefile.am b/doc/design/Makefile.am
new file mode 100644
index 0000000..e0c888e
--- /dev/null
+++ b/doc/design/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = datasrc
diff --git a/doc/design/datasrc/.gitignore b/doc/design/datasrc/.gitignore
new file mode 100644
index 0000000..065b83e
--- /dev/null
+++ b/doc/design/datasrc/.gitignore
@@ -0,0 +1,3 @@
+/*.html
+/*.png
+/*.xml
diff --git a/doc/design/datasrc/Makefile.am b/doc/design/datasrc/Makefile.am
new file mode 100644
index 0000000..d339cd7
--- /dev/null
+++ b/doc/design/datasrc/Makefile.am
@@ -0,0 +1,30 @@
+UML_FILES = \
+ overview.txt \
+ auth-local.txt \
+ auth-mapped.txt \
+ memmgr-mapped-init.txt \
+ memmgr-mapped-reload.txt
+
+TEXT_FILES = \
+ data-source-classes.txt
+
+devel: $(patsubst %.txt, %.png, $(UML_FILES)) $(patsubst %.txt, %.html, $(TEXT_FILES))
+
+.txt.html:
+if HAVE_ASCIIDOC
+ $(AM_V_GEN) $(ASCIIDOC) -n $<
+else
+ @echo "*** asciidoc is required to regenerate $(@) ***"; exit 1;
+endif
+
+.txt.png:
+if HAVE_PLANTUML
+ $(AM_V_GEN) $(PLANTUML) $<
+else
+ @echo "*** plantuml is required to regenerate $(@) ***"; exit 1;
+endif
+
+CLEANFILES = \
+ $(patsubst %.txt, %.png, $(UML_FILES)) \
+ $(patsubst %.txt, %.html, $(TEXT_FILES)) \
+ $(patsubst %.txt, %.xml, $(TEXT_FILES))
diff --git a/doc/design/datasrc/auth-local.txt b/doc/design/datasrc/auth-local.txt
new file mode 100644
index 0000000..79d7399
--- /dev/null
+++ b/doc/design/datasrc/auth-local.txt
@@ -0,0 +1,137 @@
+ at startuml
+
+participant auth as "b10-auth"
+[-> auth: new/initial config\n(datasrc cfg)
+activate auth
+
+participant list as "Configurable\nClientList"
+create list
+auth -> list: <<construct>>
+
+auth -> list: configure(cfg)
+activate list
+
+create CacheConfig
+list -> CacheConfig: <<construct>> (cfg)
+
+participant zt_segment as "ZoneTable\nSegment\n(Local)"
+create zt_segment
+list -> zt_segment: <<construct>>
+activate zt_segment
+
+create ZoneTable
+zt_segment -> ZoneTable: <<construct>>
+
+deactivate zt_segment
+
+list -> zt_segment: isWritable()
+activate zt_segment
+note over zt_segment: Local segments are\nalways writable
+zt_segment --> list: true
+deactivate zt_segment
+
+loop for each zone in CacheConfig
+list -> CacheConfig: getLoadAction()
+activate CacheConfig
+
+create LoadAction
+CacheConfig -> LoadAction: <<construct>>
+
+participant LoadAction.2
+
+CacheConfig --> list : LoadAction
+
+deactivate CacheConfig
+
+create ZoneWriter
+list -> ZoneWriter: <<construct>> (load_action)
+
+participant ZoneWriter.2
+
+list -> ZoneWriter: load()
+activate ZoneWriter
+ZoneWriter -> LoadAction: (funcall)
+activate LoadAction
+
+create ZoneData
+LoadAction -> ZoneData: <<construct>> via helpers
+
+participant ZoneData.2
+
+LoadAction --> ZoneWriter: ZoneData
+deactivate LoadAction
+deactivate ZoneWriter
+
+list -> ZoneWriter: install()
+activate ZoneWriter
+
+ZoneWriter -> ZoneTable: addZone(ZoneData)
+activate ZoneTable
+ZoneTable --> ZoneWriter: NULL (no old data)
+deactivate ZoneTable
+
+deactivate ZoneWriter
+
+end
+
+deactivate list
+deactivate auth
+
+...
+
+[-> auth: reload\n(zonename)
+activate auth
+
+auth -> list: getCachedZoneWriter\n(zone_name)
+activate list
+
+list -> CacheConfig: getLoadAction()
+activate CacheConfig
+
+create LoadAction.2
+CacheConfig -> LoadAction.2: <<construct>>
+
+CacheConfig --> list : LoadAction.2
+
+deactivate CacheConfig
+
+create ZoneWriter.2
+list -> ZoneWriter.2: <<construct>> (load_action)
+
+list --> auth: ZoneWriter.2
+
+deactivate list
+
+
+auth -> ZoneWriter.2: load()
+activate ZoneWriter.2
+ZoneWriter.2 -> LoadAction.2: (funcall)
+activate LoadAction.2
+
+create ZoneData.2
+LoadAction.2 -> ZoneData.2: <<construct>> via helpers
+
+LoadAction.2 --> ZoneWriter.2: ZoneData.2
+deactivate LoadAction.2
+deactivate ZoneWriter.2
+
+auth -> ZoneWriter.2: install()
+activate ZoneWriter.2
+
+ZoneWriter.2 -> ZoneTable: addZone(ZoneData.2)
+activate ZoneTable
+ZoneTable --> ZoneWriter.2: ZoneData (old data)
+deactivate ZoneTable
+
+deactivate ZoneWriter.2
+
+auth -> ZoneWriter.2: cleanup()
+activate ZoneWriter.2
+
+ZoneWriter.2 -> ZoneData: <<destroy>>
+destroy ZoneData
+deactivate ZoneWriter.2
+
+deactivate auth
+
+ at enduml
diff --git a/doc/design/datasrc/auth-mapped.txt b/doc/design/datasrc/auth-mapped.txt
new file mode 100644
index 0000000..d656220
--- /dev/null
+++ b/doc/design/datasrc/auth-mapped.txt
@@ -0,0 +1,98 @@
+ at startuml
+
+participant auth as "b10-auth"
+[-> auth: new/initial config\n(datasrc cfg)
+activate auth
+
+participant list as "Configurable\nClientList"
+create list
+auth -> list: <<construct>>
+
+auth -> list: configure(cfg)
+activate list
+
+create CacheConfig
+list -> CacheConfig: <<construct>> (cfg)
+
+participant zt_segment as "ZoneTable\nSegment\n(Mapped)"
+create zt_segment
+list -> zt_segment: <<construct>>
+
+list -> zt_segment: isWritable()
+activate zt_segment
+note over zt_segment: Segment not writable\nwhen not reset
+zt_segment --> list: false
+deactivate zt_segment
+
+deactivate list
+
+auth -> list: getStatus()
+activate list
+list --> auth: DataSourceStatus[]
+deactivate list
+
+[<- auth: subscribe to\nmemmgr group
+
+deactivate auth
+
+...
+
+[-> auth: command from\nmemmgr\n(datasrc_name,\nsegmentparam)
+activate auth
+
+auth -> list: resetMemorySegment\n(datasrc_name,\nREAD_ONLY,\nsegmentparam)
+activate list
+
+list -> zt_segment: reset\n(READ_ONLY,\nsegmentparam)
+activate zt_segment
+
+participant segment as "Memory\nSegment\n(Mapped)"
+create segment
+zt_segment -> segment: <<construct>>
+
+deactivate zt_segment
+deactivate list
+deactivate auth
+
+...
+
+[-> auth: command from\nmemmgr\n(datasrc_name,\nsegmentparam)
+activate auth
+
+auth -> list: resetMemorySegment\n(datasrc_name,\nREAD_ONLY,\nsegmentparam)
+activate list
+
+list -> zt_segment: reset\n(READ_ONLY,\nsegmentparam)
+activate zt_segment
+
+zt_segment -> segment: <<destroy>>
+destroy segment
+
+participant segment.2 as "Memory\nSegment\n(Mapped)\n2"
+create segment.2
+zt_segment -> segment.2: <<construct>>
+
+deactivate zt_segment
+deactivate list
+deactivate auth
+
+...
+
+[-> auth: reload\n(zonename)
+activate auth
+
+auth -> list: getCachedZoneWriter\n(zone_name)
+activate list
+
+list -> zt_segment: isWritable()
+activate zt_segment
+note over zt_segment: Segment not writable\nas it is READ_ONLY
+zt_segment --> list: false
+deactivate zt_segment
+
+list --> auth: CACHE_NOT_WRITABLE
+deactivate list
+
+deactivate auth
+
+ at enduml
diff --git a/doc/design/datasrc/data-source-classes.txt b/doc/design/datasrc/data-source-classes.txt
new file mode 100644
index 0000000..ac7e5a9
--- /dev/null
+++ b/doc/design/datasrc/data-source-classes.txt
@@ -0,0 +1,364 @@
+Data Source Library Classes
+===========================
+
+About this document
+-------------------
+
+This memo describes major classes used in the data source library,
+mainly focusing on handling in-memory cache with consideration of the
+shared memory support. It will give an overview of the entire design
+architecture and some specific details of how these classes are expected
+to be used.
+
+Before reading, the higher level inter-module protocol should be understood:
+http://bind10.isc.org/wiki/SharedMemoryIPC
+
+Overall relationships between classes
+-------------------------------------
+
+The following diagram shows major classes in the data source library
+related to in-memory caches and their relationship.
+
+image::overview.png[Class diagram showing overview of relationships]
+
+Major design decisions of this architecture are:
+
+* Keep each class as concise as possible, each focusing on one or
+ small set of responsibilities. Smaller classes are generally easier
+ to understand (at the cost of understanding how they work in the
+ "big picture" of course) and easier to test.
+
+* On a related point, minimize dependency to any single class. A
+ monolithic class on which many others are dependent is generally
+ difficult to maintain because you'll need to ensure a change to the
+ monolithic class doesn't break anything on any other classes.
+
+* Use polymorphism for any "fluid" behavior, and hide specific details
+ under abstract interfaces so implementation details won't be
+ directly referenced from any other part of the library.
+ Specifically, the underlying memory segment type (local, mapped, and
+ possibly others) and the source of in-memory data (master file or
+ other data source) are hidden via a kind of polymorphism.
+
+* Separate classes directly used by applications from classes that
+ implement details. Make the former classes as generic as possible,
+ agnostic about implementation specific details such as the memory
+ segment type (or, ideally and where possible, whether it's for
+ in-memory cache or the underlying data source).
+
+The following give a summarized description of these classes.
+
+* `ConfigurableClientList`: The front end to application classes. An
+ application that uses the data source library generally maintains
+ one or more `ConfigurableClientList` object (usually one per RR
+ class, or when we support views, probably one per view). This class
+ is a container of sets of data source related classes, providing
+ accessor to these classes and also acting as a factory of other
+ related class objects. Note: Due to internal implementation
+ reasons, there is a base class for `ConfigurableClientList` named
+ `ClientList` in the C++ version, and applications are expected to
+ use the latter. But conceptually `ConfigurableClientList` is an
+ independent value class; the inheritance is not for polymorphism.
+ Note also that the Python version doesn't have the base class.
+
+* `DataSourceInfo`: this is a straightforward tuple of set of class
+ objects corresponding to a single data source, including
+ `DataSourceClient`, `CacheConfig`, and `ZoneTableSegment`.
+ `ConfigurableClientList` maintains a list of `DataSourceInfo`, one
+ for each data source specified in its configuration.
+
+* `DataSourceClient`: The front end class to applications for a single
+ data source. Applications will get a specific `DataSourceClient`
+ object by `ConfigurableClientList::find()`.
+ `DataSourceClient` itself is a set of factories for various
+ operations on the data source such as lookup or update.
+
+* `CacheConfig`: library internal representation of in-memory cache
+ configuration for a data source. It knows which zones are to be
+ cached and where the zone data (RRs) should come from, either from a
+ master file or other data source. With this knowledge it will
+ create an appropriate `LoadAction` object. Note that `CacheConfig`
+ isn't aware of the underlying memory segment type for the in-memory
+ data. It's intentionally separated from this class (see the
+ conciseness and minimal-dependency design decisions above).
+
+* `ZoneTableSegment`: when in-memory cache is enabled, it provides
+ memory-segment-type independent interface to the in-memory data.
+ This is an abstract base class (see polymorphism in the design
+ decisions) and inherited by segment-type specific subclasses:
+ `ZoneTableSegmentLocal` and `ZoneTableSegmentMapped` (and possibly
+ others). Any subclass of `ZoneTableSegment` is expected to maintain
+ the specific type of `MemorySegment` object.
+
+* `ZoneWriter`: a frontend utility class for applications to update
+ in-memory zone data (currently it can only load a whole zone and
+ replace any existing zone content with a new one, but this should be
+ extended so it can handle partial updates).
+ Applications will get a specific `ZoneWriter`
+ object by `ConfigurableClientList::getCachedZoneWriter()`.
+ `ZoneWriter` is constructed with `ZoneableSegment` and `LoadAction`.
+ Since these are abstract classes, `ZoneWriter` doesn't have to be
+ aware of "fluid" details. It's only responsible for "somehow" preparing
+ `ZoneData` for a new version of a specified zone using `LoadAction`,
+ and installing it in the `ZoneTable` (which can be accessed via
+ `ZoneTableSegment`).
+
+* `DataSourceStatus`: created by `ConfigurableClientList::getStatus()`,
+ a straightforward tuple that represents some status information of a
+ specific data source managed in the `ConfigurableClientList`.
+ `getStatus()` generates `DataSourceStatus` for all data sources
+ managed in it, and returns them as a vector.
+
+* `ZoneTableAccessor`, `ZoneTableIterator`: frontend classes to get
+ access to the conceptual "zone table" (a set of zones) stored in a
+ specific data source. In particular, `ZoneTableIterator` allows
+ applications to iterate over all zones (by name) stored in the
+ specific data source.
+ Applications will get a specific `ZoneTableAccessor`
+ object by `ConfigurableClientList::getZoneTableAccessor()`,
+ and get an iterator object by calling `getIterator` on the accessor.
+ These are abstract classes and provide unified interfaces
+ independent from whether it's for in-memory cached zones or "real"
+ underlying data source. But the initial implementation only
+ provides the in-memory cache version of subclass (see the next
+ item).
+
+* `ZoneTableAccessorCache`, `ZoneTableIteratorCache`: implementation
+ classes of `ZoneTableAccessor` and `ZoneTableIterator` for in-memory
+ cache. They refer to `CacheConfig` to get a list of zones to be
+ cached.
+
+* `ZoneTableHeader`, `ZoneTable`: top-level interface to actual
+ in-memory data. These were separated based on a prior version of
+ the design (http://bind10.isc.org/wiki/ScalableZoneLoadDesign) where
+ `ZoneTableHeader` may contain multiple `ZoneTable`s. It's
+ one-to-one relationship in the latest version (of implementation),
+ so we could probably unify them as a cleanup.
+
+* `ZoneData`: representing the in-memory content of a single zone.
+ `ZoneTable` contains (zero, one or) multiple `ZoneData` objects.
+
+* `RdataSet`: representing the in-memory content of (data of) a single
+ RRset.
+ `ZoneData` contains `RdataSet`s corresponding to the RRsets stored
+ in the zone.
+
+* `LoadAction`: a "polymorphic" functor that implements loading zone
+ data into memory. It hides from its user (i.e., `ZoneWriter`)
+ details about the source of the data: master file or other data
+ source (and perhaps some others). The "polymorphism" is actually
+ realized as different implementations of the functor interface, not
+ class inheritance (but conceptually the effect and goal is the
+ same). Note: there's a proposal to replace `LoadAction` with
+ a revised `ZoneDataLoader`, although the overall concept doesn't
+ change. See Trac ticket #2912.
+
+* `ZoneDataLoader` and `ZoneDataUpdater`: helper classes for the
+ `LoadAction` functor(s). These work independently from the source
+ of data, taking a sequence of RRsets objects, converting them
+ into the in-memory data structures (`RdataSet`), and installing them
+ into a newly created `ZoneData` object.
+
+Sequence for auth module using local memory segment
+---------------------------------------------------
+
+In the remaining sections, we explain how the classes shown in the
+previous section work together through their methods for commonly
+intended operations.
+
+The following sequence diagram shows the case for the authoritative
+DNS server module to maintain "local" in-memory data. Note that
+"auth" is a conceptual "class" (not actually implemented as a C++
+class) to represent the server application behavior. For the purpose
+of this document that should be sufficient. The same note applies to
+all examples below.
+
+image::auth-local.png[Sequence diagram for auth server using local memory segment]
+
+1. On startup, the auth module creates a `ConfigurableClientList`
+ for each RR class specified in the configuration for "data_sources"
+ module. It then calls `ConfigurableClientList::configure()`
+ for the given configuration of that RR class.
+
+2. For each data source, `ConfigurableClientList` creates a
+ `CacheConfig` object with the corresponding cache related
+ configuration.
+
+3. If in-memory cache is enabled for the data source,
+ `ZoneTableSegment` is also created. In this scenario the cache
+ type is specified as "local" in the configuration, so a functor
+ creates `ZoneTableSegmentLocal` as the actual instance.
+ In this case its `ZoneTable` is immediately created, too.
+
+4. `ConfigurableClientList` checks if the created `ZoneTableSegment` is
+ writable. It is always so for "local" type of segments. So
+ `ConfigurableClientList` immediately loads zones to be cached into
+ memory. For each such zone, it first gets the appropriate
+ `LoadAction` through `CacheConfig`, then creates `ZoneWriter` with
+ the `LoadAction`, and loads the data using the writer.
+
+5. If the auth module receives a "reload" command for a cached zone
+ from other module (xfrin, an end user, etc), it calls
+ `ConfigurableClientList::getCachedZoneWriter` to load and install
+ the new version of the zone. The same loading sequence takes place
+ except that the user of the writer is the auth module.
+ Also, the old version of the zone data is destroyed at the end of
+ the process.
+
+Sequence for auth module using mapped memory segment
+----------------------------------------------------
+
+This is an example for the authoritative server module that uses
+mapped type memory segment for in-memory data.
+
+image::auth-mapped.png[Sequence diagram for auth server using mapped memory segment]
+
+1. The sequence is the same to the point of creating `CacheConfig`.
+
+2. But in this case a `ZoneTableSegmentMapped` object is created based
+ on the configuration of the cache type. This type of
+ `ZoneTableSegment` is initially empty and isn't even associated
+ with a `MemorySegment` (and therefore considered non-writable).
+
+3. `ConfigurableClientList` checks if the zone table segment is
+ writable to know whether to load zones into memory by itself,
+ but as `ZoneTableSegment::isWritable()` returns false, it skips
+ the loading.
+
+4. The auth module gets the status of each data source, and notices
+ there's a `WAITING` state of segment. So it subscribes to the
+ "Memmgr" group on a command session and waits for an update
+ from the memory manager (memmgr) module. (See also the note at the
+ end of the section)
+
+5. When the auth module receives an update command from memmgr, it
+ calls `ConfigurableClientList::resetMemorySegment()` with the command
+ argument and the segment mode of `READ_ONLY`.
+ Note that the auth module handles the command argument as mostly
+ opaque data; it's not expected to deal with details of segment
+ type-specific behavior.
+
+6. `ConfigurableClientList::resetMemorySegment()` subsequently calls
+ `reset()` method on the corresponding `ZoneTableSegment` with the
+ given parameters.
+ In the case of `ZoneTableSegmentMapped`, it creates a new
+ `MemorySegment` object for the mapped type, which internally maps
+ the specific file into memory.
+ memmgr is expected to have prepared all necessary data in the file,
+ so all the data are immediately ready for use (i.e., there
+ shouldn't be any explicit load operation).
+
+7. When a change is made in the mapped data, memmgr will send another
+ update command with parameters for new mapping. The auth module
+ calls `ConfigurableClientList::resetMemorySegment()`, and the
+ underlying memory segment is swapped with a new one. The old
+ memory segment object is destroyed. Note that
+ this "destroy" just means unmapping the memory region; the data
+ stored in the file are intact.
+
+8. If the auth module happens to receive a reload command from other
+ module, it could call
+ `ConfigurableClientList::getCachedZoneWriter()`
+ to reload the data by itself, just like in the previous section.
+ In this case, however, the writability check of
+ `getCachedZoneWriter()` fails (the segment was created as
+ `READ_ONLY` and is non-writable), so loading won't happen.
+
+NOTE: While less likely in practice, it's possible that the same auth
+module uses both "local" and "mapped" (and even others) type of
+segments for different data sources. In such cases the sequence is
+either the one in this or previous section depending on the specified
+segment type in the configuration. The auth module itself isn't aware
+of per segment-type details, but changes the behavior depending on the
+segment state of each data source at step 4 above: if it's `WAITING`,
+it means the auth module needs help from memmgr (that's all the auth
+module should know; it shouldn't be bothered with further details such
+as mapped file names); if it's something else, the auth module doesn't
+have to do anything further.
+
+Sequence for memmgr module initialization using mapped memory segment
+---------------------------------------------------------------------
+
+This sequence shows the common initialization sequence for the
+memory manager (memmgr) module using a mapped type memory segment.
+This is a mixture of the sequences shown in Sections 2 and 3.
+
+image::memmgr-mapped-init.png[]
+
+1. Initial sequence is the same until the application module (memmgr)
+ calls `ConfigurableClientList::getStatus()` as that for the
+ previous section.
+
+2. The memmgr module identifies the data sources whose in-memory cache
+ type is "mapped". (Unlike other application modules, the memmgr
+ should know what such types means due to its exact responsibility).
+ For each such data source, it calls
+ `ConfigurableClientList::resetMemorySegment` with the READ_WRITE
+ mode and other mapped-type specific parameters. memmgr should be
+ able to generate the parameters from its own configuration and
+ other data source specific information (such as the RR class and
+ data source name).
+
+3. The `ConfigurableClientList` class calls
+ `ZoneTableSegment::reset()` on the corresponding zone table
+ segment with the given parameters. In this case, since the mode is
+ READ_WRITE, a new `ZoneTable` will be created (assuming this is a
+ very first time initialization; if there's already a zone table
+ in the segment, it will be used).
+
+4. The memmgr module then calls
+ `ConfigurableClientList::getZoneTableAccessor()`, and calls the
+ `getItertor()` method on it to get a list of zones for which
+ zone data are to be loaded into the memory segment.
+
+5. The memmgr module loads the zone data for each such zone. This
+ sequence is the same as shown in Section 2.
+
+6. On loading all zone data, the memmgr module sends an update command
+ to all interested modules (such as auth) in the segment, and waits
+ for acknowledgment from all of them.
+
+7. Then it calls `ConfigurableClientList::resetMemorySegment()` for
+ this data source with almost the same parameter as step 2 above,
+ but with a different mapped file name. This will make a swap of
+ the underlying memory segment with a new mapping. The old
+ `MemorySegment` object will be destroyed, but as explained in the
+ previous section, it simply means unmapping the file.
+
+8. The memmgr loads the zone data into the newly mapped memory region
+ by repeating the sequence shown in step 5.
+
+9. The memmgr repeats all this sequence for data sources that use
+ "mapped" segment for in-memory cache. Note: it could handle
+ multiple data sources in parallel, e.g., while waiting for
+ acknowledgment from other modules.
+
+Sequence for memmgr module to reload a zone using mapped memory segment
+-----------------------------------------------------------------------
+
+This example is a continuation of the previous section, describing how
+the memory manager reloads a zone in mapped memory segment.
+
+image::memmgr-mapped-reload.png[]
+
+1. When the memmgr module receives a reload command from other module,
+ it calls `ConfigurableClientList::getCachedZoneWriter()` for the
+ specified zone name. This method checks the writability of
+ the segment, and since it's writable (as memmgr created it in the
+ READ_WRITE mode), `getCachedZoneWriter()` succeeds and returns
+ a `ZoneWriter`.
+
+2. The memmgr module uses the writer to load the new version of zone
+ data. There is nothing specific to mapped-type segment here.
+
+3. The memmgr module then sends an update command to other modules
+ that would share this version, and waits for acknowledgment from
+ all of them.
+
+4. On getting acknowledgments, the memmgr module calls
+ `ConfigurableClientList::resetMemorySegment()` with the parameter
+ specifying the other mapped file. This will swap the underlying
+ `MemorySegment` with a newly created one, mapping the other file.
+
+5. The memmgr updates this segment, too, so the two files will contain
+ the same version of data.
diff --git a/doc/design/datasrc/memmgr-mapped-init.txt b/doc/design/datasrc/memmgr-mapped-init.txt
new file mode 100644
index 0000000..52ca783
--- /dev/null
+++ b/doc/design/datasrc/memmgr-mapped-init.txt
@@ -0,0 +1,132 @@
+ at startuml
+
+participant memmgr as "memmgr"
+[-> memmgr: new/initial config\n(datasrc cfg)
+activate memmgr
+
+participant list as "Configurable\nClientList"
+create list
+memmgr -> list: <<construct>>
+
+memmgr -> list: configure(cfg)
+activate list
+
+create CacheConfig
+list -> CacheConfig: <<construct>> (cfg)
+
+participant zt_segment as "ZoneTable\nSegment\n(Mapped)"
+create zt_segment
+list -> zt_segment: <<construct>>
+
+list -> zt_segment: isWritable()
+activate zt_segment
+note over zt_segment: Segment not writable\nwhen not reset
+zt_segment --> list: false
+deactivate zt_segment
+
+deactivate list
+
+memmgr -> list: getStatus()
+activate list
+list --> memmgr: DataSourceStatus[]
+deactivate list
+
+loop for each datasrc with mapped segment
+
+memmgr -> list: resetMemorySegment\n(datasrc_name,\nREAD_WRITE,\nsegmentparam)
+activate list
+
+list -> zt_segment: reset\n(READ_WRITE,\nsegmentparam)
+activate zt_segment
+
+participant segment as "Memory\nSegment\n(Mapped)"
+create segment
+zt_segment -> segment: <<construct>>
+
+participant segment.2 as "Memory\nSegment\n(Mapped)\n2"
+
+create ZoneTable
+zt_segment -> ZoneTable: <<construct>>
+
+deactivate zt_segment
+deactivate list
+
+memmgr -> list: getZoneTableAccessor\n(datasrc_name,\ncache=true)
+activate list
+list -> memmgr: ZoneTableAccessor
+deactivate list
+
+
+loop for each zone given by ZoneTableIterator
+
+memmgr -> list: getCachedZoneWriter\n(zone_name)
+activate list
+
+list -> CacheConfig: getLoadAction()
+activate CacheConfig
+
+create LoadAction
+CacheConfig -> LoadAction: <<construct>>
+
+CacheConfig --> list : LoadAction
+
+deactivate CacheConfig
+
+create ZoneWriter
+list -> ZoneWriter: <<construct>> (load_action)
+
+list --> memmgr: ZoneWriter
+
+deactivate list
+
+
+memmgr -> ZoneWriter: load()
+activate ZoneWriter
+ZoneWriter -> LoadAction: (funcall)
+activate LoadAction
+
+create ZoneData
+LoadAction -> ZoneData: <<construct>> via helpers
+
+LoadAction --> ZoneWriter: ZoneData
+deactivate LoadAction
+deactivate ZoneWriter
+
+memmgr -> ZoneWriter: install()
+activate ZoneWriter
+
+ZoneWriter -> ZoneTable: addZone(ZoneData)
+activate ZoneTable
+ZoneTable --> ZoneWriter: NULL (no old data)
+deactivate ZoneTable
+
+deactivate ZoneWriter
+
+end
+
+[<- memmgr: command to\nmodules\n(datasrc_name,\nsegmentparam)
+[--> memmgr: ack from all\nmodules
+
+memmgr -> list: resetMemorySegment\n(datasrc_name,\nREAD_WRITE,\nsegmentparam)
+activate list
+
+list -> zt_segment: reset\n(READ_WRITE,\nsegmentparam)
+activate zt_segment
+
+zt_segment -> segment: <<destroy>>
+destroy segment
+create segment.2
+zt_segment -> segment.2: <<construct>>
+
+deactivate zt_segment
+deactivate list
+
+note left of memmgr: load zone\nfor each zone\ngiven by\nZoneTableIterator
+
+end
+
+[<-- memmgr
+
+deactivate memmgr
+
+ at enduml
diff --git a/doc/design/datasrc/memmgr-mapped-reload.txt b/doc/design/datasrc/memmgr-mapped-reload.txt
new file mode 100644
index 0000000..83dbf46
--- /dev/null
+++ b/doc/design/datasrc/memmgr-mapped-reload.txt
@@ -0,0 +1,92 @@
+ at startuml
+
+participant memmgr as "memmgr"
+[-> memmgr: reload\n(zonename)
+activate memmgr
+
+participant list as "Configurable\nClientList"
+memmgr -> list: getCachedZoneWriter\n(zone_name)
+activate list
+
+participant CacheConfig
+
+participant zt_segment as "ZoneTable\nSegment\n(Mapped)"
+participant segment as "Memory\nSegment\n(Mapped)"
+participant segment.2 as "Memory\nSegment\n(Mapped)\n2"
+
+list -> zt_segment: isWritable()
+activate zt_segment
+zt_segment --> list: true
+deactivate zt_segment
+
+list -> CacheConfig: getLoadAction()
+activate CacheConfig
+
+participant ZoneTable
+participant ZoneWriter
+
+create LoadAction
+CacheConfig -> LoadAction: <<construct>>
+CacheConfig --> list: LoadAction
+deactivate CacheConfig
+
+create ZoneWriter
+list -> ZoneWriter: <<construct>> (LoadAction)
+list --> memmgr: ZoneWriter
+deactivate list
+
+memmgr -> ZoneWriter: load()
+activate ZoneWriter
+ZoneWriter -> LoadAction: (funcall)
+activate LoadAction
+
+participant ZoneData
+
+create ZoneData.2
+LoadAction -> ZoneData.2: <<construct>> via helpers
+
+LoadAction --> ZoneWriter: ZoneData.2
+deactivate LoadAction
+deactivate ZoneWriter
+
+memmgr -> ZoneWriter: install()
+activate ZoneWriter
+
+ZoneWriter -> ZoneTable: addZone(ZoneData.2)
+activate ZoneTable
+ZoneTable --> ZoneWriter: ZoneData (old data)
+deactivate ZoneTable
+
+deactivate ZoneWriter
+
+memmgr -> ZoneWriter: cleanup()
+activate ZoneWriter
+
+ZoneWriter -> ZoneData: <<destroy>>
+destroy ZoneData
+deactivate ZoneWriter
+
+[<- memmgr: command to\nmodules\n(datasrc_name,\nsegmentparam)
+[--> memmgr: ack from all\nmodules
+
+memmgr -> list: resetMemorySegment\n(datasrc_name,\nREAD_WRITE,\nsegmentparam)
+activate list
+
+list -> zt_segment: reset\n(READ_WRITE,\nsegmentparam)
+activate zt_segment
+
+zt_segment -> segment: <<destroy>>
+destroy segment
+create segment.2
+zt_segment -> segment.2: <<construct>>
+
+deactivate zt_segment
+deactivate list
+
+note left of memmgr: (repeat the\nsame sequence\nfor loading to the\nother segment)
+
+memmgr -> list: getCachedZoneWriter\n(zone_name)
+
+...
+
+ at enduml
diff --git a/doc/design/datasrc/overview.txt b/doc/design/datasrc/overview.txt
new file mode 100644
index 0000000..49aae9d
--- /dev/null
+++ b/doc/design/datasrc/overview.txt
@@ -0,0 +1,68 @@
+ at startuml
+
+hide members
+
+note "Automatic placement of classes\ndoesn't look good. This diagram\nhas to be improved." as n1
+
+Auth "1" *-d-> "*" ConfigurableClientList
+Auth -d-> DataSourceClient
+Auth -d-> ZoneWriter
+Auth -d-> ZoneTableAccessor
+Auth -d-> DataSourceStatus
+Auth -d-> ZoneTableIterator
+
+ConfigurableClientList "1" *-d-> "*" DataSourceInfo
+ConfigurableClientList ..> ZoneTableSegment : <<reset>>
+ConfigurableClientList ..d-> DataSourceStatus : <<create>>
+ConfigurableClientList ..> ZoneWriter : <<create>>
+ConfigurableClientList ..> ZoneTableAccessor : <<create>>
+
+DataSourceInfo "1" *-u-> "*" DataSourceClient
+DataSourceInfo "1" *-r-> "*" CacheConfig
+DataSourceInfo "1" *-d-> "*" ZoneTableSegment
+
+ZoneTableAccessor ..> ZoneTableIterator : <<create>>
+
+ZoneTableAccessorCache -> CacheConfig
+ZoneTableAccessorCache ..> ZoneTableIteratorCache : <<create>>
+ZoneTableAccessorCache -u-o ZoneTableAccessor
+
+ZoneTableIteratorCache -u-o ZoneTableIterator
+ZoneTableIteratorCache -u-> CacheConfig
+
+ZoneWriter -d-> ZoneTableSegment
+ZoneWriter ..> ZoneData : add/replace
+
+ZoneTableSegment "1" *-r-> "1" ZoneTableHeader
+ZoneTableSegment "1" *-d-> "1" MemorySegment
+
+CacheConfig ..> LoadAction
+
+LoadAction ..> ZoneData : create
+LoadAction *-> ZoneDataLoader
+
+ZoneDataLoader -> ZoneData
+ZoneDataLoader *-> ZoneDataUpdater
+ZoneDataLoader -> MemorySegment
+
+ZoneDataUpdater -> ZoneData
+ZoneDataUpdater ..> RdataSet : create
+ZoneDataUpdater ..> RdataSet : add
+
+ZoneTableHeader "1" *-d-> "1" ZoneTable
+ZoneTable "1" *-d-> "1" ZoneData
+ZoneData "1" *-d-> "1" RdataSet
+
+loadFromFile -d-o LoadAction
+IteratorLoader -d-o LoadAction
+
+MemorySegmentMapped -d-o MemorySegment
+MemorySegmentLocal -d-o MemorySegment
+
+ZoneTableSegmentMapped -d-o ZoneTableSegment
+ZoneTableSegmentLocal -d-o ZoneTableSegment
+
+ZoneTableSegmentMapped *-d-> MemorySegmentMapped
+ZoneTableSegmentLocal *-d-> MemorySegmentLocal
+
+ at enduml
More information about the bind10-changes
mailing list