[syslog-ng] [PATCH (3.4)] confgen: Implement a built-in system() generator

Balazs Scheidler bazsi77 at gmail.com
Sat Aug 18 13:58:52 CEST 2012


Hi,

On Fri, 2012-07-06 at 14:57 +0200, Gergely Nagy wrote:
> The system SCL plugin relies on a script (generate-system-source.sh)
> to generate the block system() expands into. While this is flexible
> and easy to modifiy, it has the disadvantage of running an external
> script at startup, which is undesirable in many situations, including
> when using a strict AppArmor profile.
> 
> However, a generated system() is useful in a lot of situations,
> ranging from creating portable, system-agnostic configuration files to
> supporting sysvinit and systemd with the same config.
> 
> For these reasons, this patch implements a built-in system()
> generator, that does not rely on the generate-system-source.sh script
> at all, but does everything itself, from C.
> 
> It should be used similarly to the existing generator:
> 
>  @module confgen context(source) name(system) system(yes)
> 
> This will result in the very same system() expansion as the script's
> as of this patch. The downside is that if one of the generator gets
> extended, the other must be updated too, to keep them in sync.

Even though I understand the merits of not having to use a separate
script to generate the system() source, this is the wrong way to go. I
fear the maintenance burden of keeping the two in sync is too much
hassle.

I'm also somewhat puzzled why it is not used by default, then. If
someone is able to edit her scl/system/plugin.conf, she might as well
add the required source definitions there, without executing a script. I
imagine this was caused problems on SUSE, perhaps other distros, where
the definitions emitted by the system() macro is fixed.

Also, implementation wise, this shouldn't go to the confgen plugin,
confgen was supposed to call a script and include its output. If we
wanted to implement this in C, I'd do it as a separate system() plugin.

So I'm reluctant to include this in this form, but I might be
convinced. :)

> 
> Signed-off-by: Gergely Nagy <algernon at balabit.hu>
> ---
>  modules/confgen/confgen-plugin.c |  174 +++++++++++++++++++++++++++++++++++++-
>  scl/system/plugin.conf           |    5 ++
>  2 files changed, 175 insertions(+), 4 deletions(-)
> 
> diff --git a/modules/confgen/confgen-plugin.c b/modules/confgen/confgen-plugin.c
> index ffd24b2..90428b9 100644
> --- a/modules/confgen/confgen-plugin.c
> +++ b/modules/confgen/confgen-plugin.c
> @@ -28,8 +28,13 @@
>  #include "messages.h"
>  #include "plugin.h"
>  
> +#include <sys/utsname.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <stdlib.h>
>  #include <string.h>
>  #include <errno.h>
> +#include <unistd.h>
>  
>  gboolean
>  confgen_generate(CfgLexer *lexer, gint type, const gchar *name, CfgArgs *args, gpointer user_data)
> @@ -87,10 +92,157 @@ confgen_generate(CfgLexer *lexer, gint type, const gchar *name, CfgArgs *args, g
>    return TRUE;
>  }
>  
> +static void
> +confgen_sysblock_add_unix_dgram(GString *sysblock, const gchar *path,
> +                                const gchar *perms)
> +{
> +  g_string_append_printf(sysblock, "unix-dgram(\"%s\"", path);
> +  if (perms)
> +    g_string_append_printf(sysblock, " perms(%s)", perms);
> +  g_string_append(sysblock, ");\n");
> +}
> +
> +static void
> +confgen_sysblock_add_file(GString *sysblock, const gchar *path,
> +                          gint follow_freq, const gchar *prg_override,
> +                          const gchar *flags)
> +{
> +  g_string_append_printf(sysblock, "file(\"%s\"", path);
> +  if (follow_freq >= 0)
> +    g_string_append_printf(sysblock, " follow-freq(%d)", follow_freq);
> +  if (prg_override)
> +    g_string_append_printf(sysblock, " program-override(\"%s\")", prg_override);
> +  if (flags)
> +    g_string_append_printf(sysblock, " flags(%s)", flags);
> +  g_string_append(sysblock, ");\n");
> +}
> +
> +static void
> +confgen_sysblock_add_module(GString *sysblock, const gchar *mod)
> +{
> +  g_string_append_printf(sysblock, "@module %s\n", mod);
> +}
> +
> +static void
> +confgen_sysblock_add_sun_streams(GString *sysblock, const gchar *path,
> +                                 const gchar *door)
> +{
> +  g_string_append_printf(sysblock, "sun-streams(\"%s\"", path);
> +  if (door)
> +    g_string_append_printf(sysblock, " door(\"%s\")", door);
> +  g_string_append(sysblock, ");\n");
> +}
> +
> +static void
> +confgen_sysblock_add_pipe(GString *sysblock, const gchar *path, gint pad_size)
> +{
> +  g_string_append_printf(sysblock, "pipe(\"%s\"", path);
> +  if (pad_size >= 0)
> +    g_string_append_printf(sysblock, " pad_size(%d)", pad_size);
> +  g_string_append(sysblock, ");\n");
> +}
> +
> +gboolean
> +confgen_generate_system(CfgLexer *lexer, gint type, const gchar *name,
> +                        CfgArgs *args, gpointer user_data)
> +{
> +  gchar buf[256];
> +  GString *sysblock;
> +  struct utsname u;
> +
> +  g_snprintf(buf, sizeof(buf), "%s confgen %s", cfg_lexer_lookup_context_name_by_type(type), name);
> +  if (!cfg_args_validate(args, NULL, buf))
> +    {
> +      msg_error("confgen: confgen invocations do not process arguments, but your argument list is not empty",
> +                evt_tag_str("context", cfg_lexer_lookup_context_name_by_type(type)),
> +                evt_tag_str("block", name),
> +                NULL);
> +      return FALSE;
> +    }
> +
> +  sysblock = g_string_sized_new(1024);
> +
> +  if (uname(&u) != 0)
> +    {
> +      msg_error("confgen: Cannot get information about the running kernel",
> +                evt_tag_errno("error", errno),
> +                NULL);
> +      return FALSE;
> +    }
> +
> +  if (strcmp(u.sysname, "Linux") == 0)
> +    {
> +      char *log = "/dev/log";
> +
> +      if (getenv("LISTEN_FDS") != NULL)
> +        {
> +          struct stat sbuf;
> +
> +          if (stat("/run/systemd/journal/syslog", &sbuf) == 0)
> +            {
> +              if (S_ISSOCK(sbuf.st_mode))
> +                log = "/run/systemd/journal/syslog";
> +            }
> +        }
> +
> +      confgen_sysblock_add_unix_dgram(sysblock, log, NULL);
> +      confgen_sysblock_add_file(sysblock, "/proc/kmsg", -1, "kernel", "kernel");
> +    }
> +  else if (strcmp(u.sysname, "SunOS") == 0)
> +    {
> +      confgen_sysblock_add_module(sysblock, "afstreams");
> +
> +      if (strcmp(u.release, "5.8") == 0)
> +        confgen_sysblock_add_sun_streams(sysblock, "/dev/log", NULL);
> +      else if (strcmp(u.release, "5.9") == 0)
> +        confgen_sysblock_add_sun_streams(sysblock, "/dev/log", "/etc/.syslog_door");
> +      else
> +        confgen_sysblock_add_sun_streams(sysblock, "/dev/log", "/var/run/syslog_door");
> +    }
> +  else if (strcmp(u.sysname, "FreeBSD") == 0)
> +    {
> +      confgen_sysblock_add_unix_dgram(sysblock, "/var/run/log", NULL);
> +      confgen_sysblock_add_unix_dgram(sysblock, "/var/run/logpriv", "0600");
> +      confgen_sysblock_add_file(sysblock, "/dev/klog", 0, "kernel", "no-parse");
> +    }
> +  else if (strcmp(u.sysname, "GNU/kFreeBSD") == 0)
> +    {
> +      confgen_sysblock_add_unix_dgram(sysblock, "/var/run/log", NULL);
> +      confgen_sysblock_add_file(sysblock, "/dev/klog", 0, "kernel", NULL);
> +    }
> +  else if (strcmp(u.sysname, "HP-UX") == 0)
> +    {
> +      confgen_sysblock_add_pipe(sysblock, "/dev/pipe", 2048);
> +    }
> +  else if (strcmp(u.sysname, "AIX") == 0 ||
> +           strcmp(u.sysname, "OSF1") == 0 ||
> +           strncmp(u.sysname, "CYGWIN", 6) == 0)
> +    {
> +      confgen_sysblock_add_unix_dgram(sysblock, "/dev/log", NULL);
> +    }
> +  else
> +    {
> +      msg_error("system(): Error detecting platform, unable to define the system() source. "
> +                "Please send your system information to the developers!",
> +                evt_tag_str("sysname", u.sysname),
> +                evt_tag_str("release", u.release),
> +                NULL);
> +      return FALSE;
> +    }
> +
> +  if (!cfg_lexer_include_buffer(lexer, buf, sysblock->str, sysblock->len))
> +    {
> +      g_string_free(sysblock, TRUE);
> +      return FALSE;
> +    }
> +
> +  return TRUE;
> +}
> +
>  gboolean
>  confgen_module_init(GlobalConfig *cfg, CfgArgs *args)
>  {
> -  const gchar *name, *context, *exec;
> +  const gchar *name, *context, *exec, *sys;
>  
>    name = cfg_args_get(args, "name");
>    if (!name)
> @@ -107,13 +259,27 @@ confgen_module_init(GlobalConfig *cfg, CfgArgs *args)
>        return FALSE;
>      }
>    exec = cfg_args_get(args, "exec");
> -  if (!exec)
> +  sys = cfg_args_get(args, "system");
> +
> +  if (!exec && !sys)
> +    {
> +      msg_error("confgen: exec or system argument expected",
> +                NULL);
> +      return FALSE;
> +    }
> +
> +  if (exec && sys)
>      {
> -      msg_error("confgen: exec argument expected",
> +      msg_error("confgen: exec and system arguments are mutually excluse",
>                  NULL);
>        return FALSE;
>      }
> -  cfg_lexer_register_block_generator(cfg->lexer, cfg_lexer_lookup_context_type_by_name(context), name, confgen_generate, g_strdup(exec), g_free);
> +
> +  if (exec)
> +    cfg_lexer_register_block_generator(cfg->lexer, cfg_lexer_lookup_context_type_by_name(context), name, confgen_generate, g_strdup(exec), g_free);
> +  if (sys)
> +    cfg_lexer_register_block_generator(cfg->lexer, cfg_lexer_lookup_context_type_by_name(context),
> +                                       name, confgen_generate_system, NULL, NULL);
>    return TRUE;
>  }
>  
> diff --git a/scl/system/plugin.conf b/scl/system/plugin.conf
> index 5ba652e..d150fee 100644
> --- a/scl/system/plugin.conf
> +++ b/scl/system/plugin.conf
> @@ -21,3 +21,8 @@
>  #############################################################################
>  
>  @module confgen context(source) name(system) exec("`scl-root`/system/generate-system-source.sh")
> +
> +# To use a built-in discovery system, that does not rely on a script,
> +# comment out the line above, and uncomment the next one:
> +
> +#@module confgen context(source) name(system) system(yes)




More information about the syslog-ng mailing list