From: Michal Privoznik <mprivozn@redhat.com>
To: passt-dev@passt.top
Subject: [PATCH 2/2] conf, log: Introduce --log-fd option
Date: Tue, 6 Jun 2023 13:41:30 +0200 [thread overview]
Message-ID: <24c5ae1d4a44e6c3e32cc5e909dacd714b45e3b5.1686037337.git.mprivozn@redhat.com> (raw)
In-Reply-To: <cover.1686037337.git.mprivozn@redhat.com>
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.
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;
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) {
+ if (set_cloexec(logfd) < 0)
+ die("Could not set CLOEXEC flag on logfd", strerror(errno));
+ log_file = logfd;
+ } else {
+ 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));
+ }
log_size = size ? size : LOGFILE_SIZE_DEFAULT;
diff --git a/log.h b/log.h
index 3aab29d..d96359a 100644
--- a/log.h
+++ b/log.h
@@ -30,7 +30,7 @@ void trace_init(int enable);
} while (0)
void __openlog(const char *ident, int option, int facility);
-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);
void passt_vsyslog(int pri, const char *format, va_list ap);
void logfile_write(int pri, const char *format, va_list ap);
void __setlogmask(int mask);
diff --git a/passt.1 b/passt.1
index 1ad4276..ee5abbb 100644
--- a/passt.1
+++ b/passt.1
@@ -101,6 +101,11 @@ terminal, and to both system logger and standard error otherwise.
.BR \-l ", " \-\-log-file " " \fIPATH\fR
Log to file \fIPATH\fR, not to standard error, and not to the system logger.
+.TP
+.BR \-l ", " \-\-log-fd " " \fIFD\fR
+Log to pre-opened file descriptor \fIFD\fR, not to standard error, and not to
+the system logger.
+
.TP
.BR \-\-log-size " " \fISIZE\fR
Limit log file size to \fISIZE\fR bytes. When the log file is full, make room
--
@@ -101,6 +101,11 @@ terminal, and to both system logger and standard error otherwise.
.BR \-l ", " \-\-log-file " " \fIPATH\fR
Log to file \fIPATH\fR, not to standard error, and not to the system logger.
+.TP
+.BR \-l ", " \-\-log-fd " " \fIFD\fR
+Log to pre-opened file descriptor \fIFD\fR, not to standard error, and not to
+the system logger.
+
.TP
.BR \-\-log-size " " \fISIZE\fR
Limit log file size to \fISIZE\fR bytes. When the log file is full, make room
--
2.39.3
next prev parent reply other threads:[~2023-06-06 11:41 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 ` Michal Privoznik [this message]
2023-06-06 20:59 ` [PATCH 2/2] conf, log: Introduce --log-fd option Stefano Brivio
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=24c5ae1d4a44e6c3e32cc5e909dacd714b45e3b5.1686037337.git.mprivozn@redhat.com \
--to=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).