[4/5] resolv: Enhance __resolv_conf_load to capture file change data
Commit Message
The data is captured after reading the file. This allows callers
to check the change data against an earlier measurement.
---
resolv/res_init.c | 14 +++++++++++---
resolv/resolv_conf.c | 2 +-
resolv/resolv_conf.h | 10 +++++++---
3 files changed, 19 insertions(+), 7 deletions(-)
Comments
On 21/01/2020 15:42, Florian Weimer wrote:
> The data is captured after reading the file. This allows callers
> to check the change data against an earlier measurement.
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> resolv/res_init.c | 14 +++++++++++---
> resolv/resolv_conf.c | 2 +-
> resolv/resolv_conf.h | 10 +++++++---
> 3 files changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/resolv/res_init.c b/resolv/res_init.c
> index 09345718cd..98d84f264d 100644
> --- a/resolv/res_init.c
> +++ b/resolv/res_init.c
> @@ -103,6 +103,7 @@
> #include <inet/net-internal.h>
> #include <errno.h>
> #include <resolv_conf.h>
> +#include <file_change_detection.h>
>
> static uint32_t net_mask (struct in_addr);
>
Ok.
> @@ -549,7 +550,8 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
> }
>
> struct resolv_conf *
> -__resolv_conf_load (struct __res_state *preinit)
> +__resolv_conf_load (struct __res_state *preinit,
> + struct file_change_detection *change)
> {
> /* Ensure that /etc/hosts.conf has been loaded (once). */
> _res_hconf_init ();
Ok.
> @@ -577,7 +579,13 @@ __resolv_conf_load (struct __res_state *preinit)
> resolv_conf_parser_init (&parser, preinit);
>
> struct resolv_conf *conf = NULL;
> - if (res_vinit_1 (fp, &parser))
> + bool ok = res_vinit_1 (fp, &parser);
> + if (ok && change != NULL)
> + /* Update the file change information if the configuration was
> + loaded successfully. */
> + ok = file_change_detection_for_fp (change, fp);
> +
> + if (ok)
> {
> parser.template.nameserver_list
> = nameserver_list_begin (&parser.nameserver_list);
Ok.
> @@ -615,7 +623,7 @@ __res_vinit (res_state statp, int preinit)
> if (preinit && has_preinit_values (statp))
> /* For the preinit case, we cannot use the cached configuration
> because some settings could be different. */
> - conf = __resolv_conf_load (statp);
> + conf = __resolv_conf_load (statp, NULL);
> else
> conf = __resolv_conf_get_current ();
> if (conf == NULL)
Ok.
> diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
> index d954ba9a5a..bdd2ebb909 100644
> --- a/resolv/resolv_conf.c
> +++ b/resolv/resolv_conf.c
> @@ -136,7 +136,7 @@ __resolv_conf_get_current (void)
> {
> /* Parse configuration while holding the lock. This avoids
> duplicate work. */
> - conf = __resolv_conf_load (NULL);
> + conf = __resolv_conf_load (NULL, NULL);
> if (conf != NULL)
> {
> if (global_copy->conf_current != NULL)
Ok.
> diff --git a/resolv/resolv_conf.h b/resolv/resolv_conf.h
> index 01cbff9111..101e14bfe5 100644
> --- a/resolv/resolv_conf.h
> +++ b/resolv/resolv_conf.h
> @@ -63,12 +63,16 @@ struct resolv_conf
> and the struct resolv_context facility. */
>
> struct __res_state;
> +struct file_change_detection;
>
> /* Read /etc/resolv.conf and return a configuration object, or NULL if
> /etc/resolv.conf cannot be read due to memory allocation errors.
> - If PREINIT is not NULL, some configuration values are taken from the
> - struct __res_state object. */
> -struct resolv_conf *__resolv_conf_load (struct __res_state *preinit)
> + If PREINIT is not NULL, some configuration values are taken from
> + the struct __res_state object. If CHANGE is not null, file change
> + detection data is written to *CHANGE, based on the state of the
> + file after reading it. */
> +struct resolv_conf *__resolv_conf_load (struct __res_state *preinit,
> + struct file_change_detection *change)
> attribute_hidden __attribute__ ((warn_unused_result));
>
> /* Return a configuration object for the current /etc/resolv.conf
>
Ok.
@@ -103,6 +103,7 @@
#include <inet/net-internal.h>
#include <errno.h>
#include <resolv_conf.h>
+#include <file_change_detection.h>
static uint32_t net_mask (struct in_addr);
@@ -549,7 +550,8 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
}
struct resolv_conf *
-__resolv_conf_load (struct __res_state *preinit)
+__resolv_conf_load (struct __res_state *preinit,
+ struct file_change_detection *change)
{
/* Ensure that /etc/hosts.conf has been loaded (once). */
_res_hconf_init ();
@@ -577,7 +579,13 @@ __resolv_conf_load (struct __res_state *preinit)
resolv_conf_parser_init (&parser, preinit);
struct resolv_conf *conf = NULL;
- if (res_vinit_1 (fp, &parser))
+ bool ok = res_vinit_1 (fp, &parser);
+ if (ok && change != NULL)
+ /* Update the file change information if the configuration was
+ loaded successfully. */
+ ok = file_change_detection_for_fp (change, fp);
+
+ if (ok)
{
parser.template.nameserver_list
= nameserver_list_begin (&parser.nameserver_list);
@@ -615,7 +623,7 @@ __res_vinit (res_state statp, int preinit)
if (preinit && has_preinit_values (statp))
/* For the preinit case, we cannot use the cached configuration
because some settings could be different. */
- conf = __resolv_conf_load (statp);
+ conf = __resolv_conf_load (statp, NULL);
else
conf = __resolv_conf_get_current ();
if (conf == NULL)
@@ -136,7 +136,7 @@ __resolv_conf_get_current (void)
{
/* Parse configuration while holding the lock. This avoids
duplicate work. */
- conf = __resolv_conf_load (NULL);
+ conf = __resolv_conf_load (NULL, NULL);
if (conf != NULL)
{
if (global_copy->conf_current != NULL)
@@ -63,12 +63,16 @@ struct resolv_conf
and the struct resolv_context facility. */
struct __res_state;
+struct file_change_detection;
/* Read /etc/resolv.conf and return a configuration object, or NULL if
/etc/resolv.conf cannot be read due to memory allocation errors.
- If PREINIT is not NULL, some configuration values are taken from the
- struct __res_state object. */
-struct resolv_conf *__resolv_conf_load (struct __res_state *preinit)
+ If PREINIT is not NULL, some configuration values are taken from
+ the struct __res_state object. If CHANGE is not null, file change
+ detection data is written to *CHANGE, based on the state of the
+ file after reading it. */
+struct resolv_conf *__resolv_conf_load (struct __res_state *preinit,
+ struct file_change_detection *change)
attribute_hidden __attribute__ ((warn_unused_result));
/* Return a configuration object for the current /etc/resolv.conf