From: Stefano Brivio <sbrivio@redhat.com>
To: Michal Privoznik <mprivozn@redhat.com>
Cc: passt-dev@passt.top
Subject: Re: [PATCH 2/2] conf, log: Introduce --log-fd option
Date: Tue, 6 Jun 2023 22:59:10 +0200 [thread overview]
Message-ID: <20230606225910.228dd2e0@elisabeth> (raw)
In-Reply-To: <24c5ae1d4a44e6c3e32cc5e909dacd714b45e3b5.1686037337.git.mprivozn@redhat.com>
On Tue, 6 Jun 2023 13:41:30 +0200
Michal Privoznik <mprivozn@redhat.com> wrote:
> So far, users/mgmt apps can use --log-file to specify log output.
> This has a downside though - they have to set up permissions so
> that passt/pasta can open the file. But we can do a bit better:
> allow mgmt apps pass an pre-opened FD and write all log messages
> into it.
>
> This then allows the log file to be readable by very few users
> (root:root even) or reside in a path which would be otherwise
> inaccessible.
Right... that's exactly the part that worries me (even though I
understand and appreciate the compatibility argument).
> Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
> ---
> conf.c | 29 +++++++++++++++++++++++++----
> log.c | 17 ++++++++++++-----
> log.h | 2 +-
> passt.1 | 5 +++++
> 4 files changed, 43 insertions(+), 10 deletions(-)
>
> diff --git a/conf.c b/conf.c
> index ffff235..59d0a8e 100644
> --- a/conf.c
> +++ b/conf.c
> @@ -744,6 +744,7 @@ static void usage(const char *name)
> info( " -e, --stderr Log to stderr too");
> info( " default: log to system logger only if started from a TTY");
> info( " -l, --log-file PATH Log (only) to given file");
> + info( " --log-fd FD Log (only) to given file descriptor");
> info( " --log-size BYTES Maximum size of log file");
> info( " default: 1 MiB");
> info( " --runas UID|UID:GID Run as given UID, GID, which can be");
> @@ -1181,6 +1182,7 @@ void conf(struct ctx *c, int argc, char **argv)
> {"config-net", no_argument, NULL, 17 },
> {"no-copy-routes", no_argument, NULL, 18 },
> {"no-copy-addrs", no_argument, NULL, 19 },
> + {"log-fd", required_argument, NULL, 20 },
> { 0 },
> };
> struct get_bound_ports_ns_arg ns_ports_arg = { .c = c };
> @@ -1192,7 +1194,7 @@ void conf(struct ctx *c, int argc, char **argv)
> struct in_addr *dns4 = c->ip4.dns;
> unsigned int ifi4 = 0, ifi6 = 0;
> const char *optstring;
> - int name, ret, b, i;
> + int name, ret, b, i, logfd = -1;
We use a reverse christmas tree convention for ordering local
variables (like Linux kernel network code does), rationale:
consistency, plus:
https://hisham.hm/2018/06/16/when-listing-repeated-things-make-pyramids/
> size_t logsize = 0;
> uid_t uid;
> gid_t gid;
> @@ -1358,6 +1360,22 @@ void conf(struct ctx *c, int argc, char **argv)
>
> warn("--no-copy-addrs will be dropped soon");
> c->no_copy_addrs = 1;
> + break;
> + case 20:
> + if (logfile)
> + die("Either --log-file or --log-fd");
> +
> + if (c->force_stderr)
> + die("Can't log to both stderr and file");
> +
> + if (logfd >= 0)
> + die("Multiple --log-fd options given");
> +
> + errno = 0;
> + logfd = strtol(optarg, NULL, 0);
> + if (logfd < 0 || errno)
> + die("Invalid --log-fd: %s", optarg);
> +
> break;
> case 'd':
> if (c->debug)
> @@ -1369,7 +1387,7 @@ void conf(struct ctx *c, int argc, char **argv)
> c->debug = 1;
> break;
> case 'e':
> - if (logfile)
> + if (logfile || logfd >= 0)
> die("Can't log to both file and stderr");
>
> if (c->force_stderr)
> @@ -1381,6 +1399,9 @@ void conf(struct ctx *c, int argc, char **argv)
> if (c->force_stderr)
> die("Can't log to both stderr and file");
>
> + if (logfd >= 0)
> + die("Either --log-file or --log-fd");
> +
> if (logfile)
> die("Multiple --log-file options given");
>
> @@ -1659,9 +1680,9 @@ void conf(struct ctx *c, int argc, char **argv)
>
> conf_ugid(runas, &uid, &gid);
>
> - if (logfile) {
> + if (logfile || logfd >= 0) {
> logfile_init(c->mode == MODE_PASST ? "passt" : "pasta",
> - logfile, logsize);
> + logfile, logfd, logsize);
> }
>
> nl_sock_init(c, false);
> diff --git a/log.c b/log.c
> index 3a3d101..28929a7 100644
> --- a/log.c
> +++ b/log.c
> @@ -174,9 +174,10 @@ void passt_vsyslog(int pri, const char *format, va_list ap)
> * logfile_init() - Open log file and write header with PID, version, path
> * @name: Identifier for header: passt or pasta
> * @path: Path to log file
> + * @logfd: Pre-opened log file descriptor (if >= 0)
> * @size: Maximum size of log file: log_cut_size is calculatd here
> */
> -void logfile_init(const char *name, const char *path, size_t size)
> +void logfile_init(const char *name, const char *path, int logfd, size_t size)
> {
> char nl = '\n', exe[PATH_MAX] = { 0 };
> int n;
> @@ -186,10 +187,16 @@ void logfile_init(const char *name, const char *path, size_t size)
> exit(EXIT_FAILURE);
> }
>
> - log_file = open(path, O_CREAT | O_TRUNC | O_APPEND | O_RDWR | O_CLOEXEC,
> - S_IRUSR | S_IWUSR);
> - if (log_file == -1)
> - die("Couldn't open log file %s: %s", path, strerror(errno));
> + if (logfd >= 0) {
We should probably ftruncate() the referenced file to zero bytes, here,
because otherwise we're not guaranteeing the rotation with fallocate()
later.
> + if (set_cloexec(logfd) < 0)
> + die("Could not set CLOEXEC flag on logfd", strerror(errno));
Using errno from set_cloexec() is a bit fragile, in case somebody ever
adds something else to that function.
By the way, this,
> + log_file = logfd;
> + } else {
> + log_file = open(path, O_CREAT | O_TRUNC | O_APPEND | O_RDWR | O_CLOEXEC,
> + S_IRUSR | S_IWUSR);
this,
> + if (log_file == -1)
> + die("Couldn't open log file %s: %s", path, strerror(errno));
and this now exceed 80 columns.
--
Stefano
next prev parent reply other threads:[~2023-06-06 20:59 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-06 11:41 [PATCH 0/2] Introduce --log-fd option Michal Privoznik
2023-06-06 11:41 ` [PATCH 1/2] util: Introduce set_cloexec() Michal Privoznik
2023-06-06 20:59 ` Stefano Brivio
2023-06-06 11:41 ` [PATCH 2/2] conf, log: Introduce --log-fd option Michal Privoznik
2023-06-06 20:59 ` Stefano Brivio [this message]
2023-06-06 20:58 ` [PATCH 0/2] " Stefano Brivio
2023-06-07 11:38 ` Michal Prívozník
2023-06-07 14:42 ` Stefano Brivio
2023-06-08 11:51 ` Michal Prívozník
2023-06-13 3:12 ` Stefano Brivio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230606225910.228dd2e0@elisabeth \
--to=sbrivio@redhat.com \
--cc=mprivozn@redhat.com \
--cc=passt-dev@passt.top \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).