mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-20 09:26:37 +00:00
Filesystem Heirarchy Standard (FHS) paths
If no instance directory specified, then use paths like /etc/serval/serval.conf /var/cache/serval /var/log/serval /var/run/serval etc. for files, instead of all in a single directory. Log all directory creation as INFO messages. Interpretation of log.file.directory_path has changed slightly. Updated servald configuration tech doc.
This commit is contained in:
parent
d228165814
commit
53c1b1c04c
@ -2,6 +2,8 @@ prefix=@prefix@
|
|||||||
exec_prefix=@exec_prefix@
|
exec_prefix=@exec_prefix@
|
||||||
bindir=@bindir@
|
bindir=@bindir@
|
||||||
sbindir=@sbindir@
|
sbindir=@sbindir@
|
||||||
|
sysconfdir=@sysconfdir@
|
||||||
|
localstatedir=@localstatedir@
|
||||||
|
|
||||||
NACL_BASE= nacl/src
|
NACL_BASE= nacl/src
|
||||||
include $(NACL_BASE)/nacl.mk
|
include $(NACL_BASE)/nacl.mk
|
||||||
@ -42,6 +44,7 @@ MDP_CLIENT_OBJS= $(MDP_CLIENT_SRCS:.c=.o)
|
|||||||
LDFLAGS=@LDFLAGS@ @LIBS@ @PORTAUDIO_LIBS@ @SRC_LIBS@ @SPANDSP_LIBS@ @CODEC2_LIBS@ @PTHREAD_LIBS@
|
LDFLAGS=@LDFLAGS@ @LIBS@ @PORTAUDIO_LIBS@ @SRC_LIBS@ @SPANDSP_LIBS@ @CODEC2_LIBS@ @PTHREAD_LIBS@
|
||||||
|
|
||||||
CFLAGS= -Isqlite-amalgamation-3070900 @CPPFLAGS@ @CFLAGS@ @PORTAUDIO_CFLAGS@ @SRC_CFLAGS@ @SPANDSP_CFLAGS@ @PTHREAD_CFLAGS@ $(VOIPTEST_CFLAGS) -Inacl/include
|
CFLAGS= -Isqlite-amalgamation-3070900 @CPPFLAGS@ @CFLAGS@ @PORTAUDIO_CFLAGS@ @SRC_CFLAGS@ @SPANDSP_CFLAGS@ @PTHREAD_CFLAGS@ $(VOIPTEST_CFLAGS) -Inacl/include
|
||||||
|
CFLAGS+=-DSYSCONFDIR="\"$(sysconfdir)\"" -DLOCALSTATEDIR="\"$(localstatedir)\""
|
||||||
CFLAGS+=-fPIC
|
CFLAGS+=-fPIC
|
||||||
CFLAGS+=-Wall -Wno-unused-value
|
CFLAGS+=-Wall -Wno-unused-value
|
||||||
# Solaris magic
|
# Solaris magic
|
||||||
|
@ -932,8 +932,13 @@ int app_server_start(const struct cli_parsed *parsed, struct cli_context *contex
|
|||||||
RETURN(WHY("Server process did not start"));
|
RETURN(WHY("Server process did not start"));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
const char *ipath = instance_path();
|
||||||
|
if (ipath) {
|
||||||
cli_field_name(context, "instancepath", ":");
|
cli_field_name(context, "instancepath", ":");
|
||||||
cli_put_string(context, serval_instancepath(), "\n");
|
cli_put_string(context, ipath, "\n");
|
||||||
|
}
|
||||||
|
cli_field_name(context, "pidfile", ":");
|
||||||
|
cli_put_string(context, server_pidfile_path(), "\n");
|
||||||
cli_field_name(context, "pid", ":");
|
cli_field_name(context, "pid", ":");
|
||||||
cli_put_long(context, pid, "\n");
|
cli_put_long(context, pid, "\n");
|
||||||
char buff[256];
|
char buff[256];
|
||||||
@ -968,9 +973,13 @@ int app_server_stop(const struct cli_parsed *parsed, struct cli_context *context
|
|||||||
DEBUG_cli_parsed(parsed);
|
DEBUG_cli_parsed(parsed);
|
||||||
int pid, tries, running;
|
int pid, tries, running;
|
||||||
time_ms_t timeout;
|
time_ms_t timeout;
|
||||||
const char *instancepath = serval_instancepath();
|
const char *ipath = instance_path();
|
||||||
|
if (ipath) {
|
||||||
cli_field_name(context, "instancepath", ":");
|
cli_field_name(context, "instancepath", ":");
|
||||||
cli_put_string(context, instancepath, "\n");
|
cli_put_string(context, ipath, "\n");
|
||||||
|
}
|
||||||
|
cli_field_name(context, "pidfile", ":");
|
||||||
|
cli_put_string(context, server_pidfile_path(), "\n");
|
||||||
pid = server_pid();
|
pid = server_pid();
|
||||||
/* Not running, nothing to stop */
|
/* Not running, nothing to stop */
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
@ -983,8 +992,8 @@ int app_server_stop(const struct cli_parsed *parsed, struct cli_context *context
|
|||||||
running = pid;
|
running = pid;
|
||||||
while (running == pid) {
|
while (running == pid) {
|
||||||
if (tries >= 5) {
|
if (tries >= 5) {
|
||||||
WHYF("Servald pid=%d for instance '%s' did not stop after %d SIGHUP signals",
|
WHYF("Servald pid=%d (pidfile=%s) did not stop after %d SIGHUP signals",
|
||||||
pid, instancepath, tries);
|
pid, server_pidfile_path(), tries);
|
||||||
return 253;
|
return 253;
|
||||||
}
|
}
|
||||||
++tries;
|
++tries;
|
||||||
@ -999,7 +1008,7 @@ int app_server_stop(const struct cli_parsed *parsed, struct cli_context *context
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
WHY_perror("kill");
|
WHY_perror("kill");
|
||||||
WHYF("Error sending SIGHUP to Servald pid=%d for instance '%s'", pid, instancepath);
|
WHYF("Error sending SIGHUP to Servald pid=%d (pidfile %s)", pid, server_pidfile_path());
|
||||||
return 252;
|
return 252;
|
||||||
}
|
}
|
||||||
/* Allow a few seconds for the process to die. */
|
/* Allow a few seconds for the process to die. */
|
||||||
@ -1019,8 +1028,13 @@ int app_server_status(const struct cli_parsed *parsed, struct cli_context *conte
|
|||||||
if (config.debug.verbose)
|
if (config.debug.verbose)
|
||||||
DEBUG_cli_parsed(parsed);
|
DEBUG_cli_parsed(parsed);
|
||||||
int pid = server_pid();
|
int pid = server_pid();
|
||||||
|
const char *ipath = instance_path();
|
||||||
|
if (ipath) {
|
||||||
cli_field_name(context, "instancepath", ":");
|
cli_field_name(context, "instancepath", ":");
|
||||||
cli_put_string(context, serval_instancepath(), "\n");
|
cli_put_string(context, ipath, "\n");
|
||||||
|
}
|
||||||
|
cli_field_name(context, "pidfile", ":");
|
||||||
|
cli_put_string(context, server_pidfile_path(), "\n");
|
||||||
cli_field_name(context, "status", ":");
|
cli_field_name(context, "status", ":");
|
||||||
cli_put_string(context, pid > 0 ? "running" : "stopped", "\n");
|
cli_put_string(context, pid > 0 ? "running" : "stopped", "\n");
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
@ -1426,6 +1440,52 @@ int app_config_get(const struct cli_parsed *parsed, struct cli_context *context)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int app_config_paths(const struct cli_parsed *parsed, struct cli_context *context)
|
||||||
|
{
|
||||||
|
if (config.debug.verbose)
|
||||||
|
DEBUG_cli_parsed(parsed);
|
||||||
|
if (cf_om_reload() == -1)
|
||||||
|
return -1;
|
||||||
|
char path[1024];
|
||||||
|
if (FORMF_SERVAL_ETC_PATH(path, NULL)) {
|
||||||
|
cli_field_name(context, "SERVAL_ETC_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
if (FORMF_SERVAL_RUN_PATH(path, NULL)) {
|
||||||
|
cli_field_name(context, "SERVAL_RUN_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
if (FORMF_SERVAL_CACHE_PATH(path, NULL)) {
|
||||||
|
cli_field_name(context, "SERVAL_CACHE_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
strbuf sb = strbuf_local(path, sizeof path);
|
||||||
|
strbuf_system_log_path(sb);
|
||||||
|
if (!strbuf_overrun(sb)) {
|
||||||
|
cli_field_name(context, "SYSTEM_LOG_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
strbuf_reset(sb);
|
||||||
|
strbuf_serval_log_path(sb);
|
||||||
|
if (!strbuf_overrun(sb)) {
|
||||||
|
cli_field_name(context, "SERVAL_LOG_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
if (FORMF_SERVAL_TMP_PATH(path, NULL)) {
|
||||||
|
cli_field_name(context, "SERVAL_TMP_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
if (FORMF_SERVALD_PROC_PATH(path, NULL)) {
|
||||||
|
cli_field_name(context, "SERVALD_PROC_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
if (FORMF_RHIZOME_STORE_PATH(path, NULL)) {
|
||||||
|
cli_field_name(context, "RHIZOME_STORE_PATH", ":");
|
||||||
|
cli_put_string(context, path, "\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int app_rhizome_hash_file(const struct cli_parsed *parsed, struct cli_context *context)
|
int app_rhizome_hash_file(const struct cli_parsed *parsed, struct cli_context *context)
|
||||||
{
|
{
|
||||||
if (config.debug.verbose)
|
if (config.debug.verbose)
|
||||||
@ -3019,6 +3079,8 @@ struct cli_schema command_line_options[]={
|
|||||||
"Del and set specified configuration variables."},
|
"Del and set specified configuration variables."},
|
||||||
{app_config_get,{"config","get","[<variable>]",NULL},CLIFLAG_PERMISSIVE_CONFIG,
|
{app_config_get,{"config","get","[<variable>]",NULL},CLIFLAG_PERMISSIVE_CONFIG,
|
||||||
"Get specified configuration variable."},
|
"Get specified configuration variable."},
|
||||||
|
{app_config_paths,{"config","paths",NULL},CLIFLAG_PERMISSIVE_CONFIG,
|
||||||
|
"Dump file and directory paths."},
|
||||||
{app_vomp_console,{"console",NULL}, 0,
|
{app_vomp_console,{"console",NULL}, 0,
|
||||||
"Test phone call life-cycle from the console"},
|
"Test phone call life-cycle from the console"},
|
||||||
{app_meshms_conversations,{"meshms","list","conversations" KEYRING_PIN_OPTIONS, "<sid>","[<offset>]","[<count>]",NULL},0,
|
{app_meshms_conversations,{"meshms","list","conversations" KEYRING_PIN_OPTIONS, "<sid>","[<offset>]","[<count>]",NULL},0,
|
||||||
|
4
conf.c
4
conf.c
@ -44,7 +44,7 @@ static struct file_meta config_meta = FILE_META_UNKNOWN;
|
|||||||
static const char *conffile_path()
|
static const char *conffile_path()
|
||||||
{
|
{
|
||||||
static char path[1024] = "";
|
static char path[1024] = "";
|
||||||
if (!path[0] && !FORM_SERVAL_INSTANCE_PATH(path, CONFFILE_NAME))
|
if (!path[0] && !FORMF_SERVAL_ETC_PATH(path, CONFFILE_NAME))
|
||||||
abort();
|
abort();
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ int cf_om_save()
|
|||||||
const char *path = conffile_path();
|
const char *path = conffile_path();
|
||||||
char tempfile[1024];
|
char tempfile[1024];
|
||||||
FILE *outf = NULL;
|
FILE *outf = NULL;
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(tempfile, "serval.conf.temp"))
|
if (!FORMF_SERVAL_ETC_PATH(tempfile, CONFFILE_NAME ".temp"))
|
||||||
return -1;
|
return -1;
|
||||||
if ((outf = fopen(tempfile, "w")) == NULL)
|
if ((outf = fopen(tempfile, "w")) == NULL)
|
||||||
return WHYF_perror("fopen(%s, \"w\")", tempfile);
|
return WHYF_perror("fopen(%s, \"w\")", tempfile);
|
||||||
|
@ -292,7 +292,7 @@ LOG_FORMAT_OPTIONS
|
|||||||
END_STRUCT
|
END_STRUCT
|
||||||
|
|
||||||
STRUCT(log_format_file)
|
STRUCT(log_format_file)
|
||||||
STRING(256, directory_path, "log", str_nonempty,, "Path of directory for log files, either absolute or relative to instance directory")
|
STRING(256, directory_path, "", str,, "Path of directory for log files, either absolute or relative to instance log directory")
|
||||||
STRING(256, path, "", str_nonempty,, "Path of single log file, either absolute or relative to directory_path")
|
STRING(256, path, "", str_nonempty,, "Path of single log file, either absolute or relative to directory_path")
|
||||||
ATOM(unsigned short, rotate, 12, ushort,, "Number of log files to rotate, zero means no deletion")
|
ATOM(unsigned short, rotate, 12, ushort,, "Number of log files to rotate, zero means no deletion")
|
||||||
ATOM(uint32_t, duration, 3600, uint32_time_interval,, "Time duration of each log file, zero means one file per invocation")
|
ATOM(uint32_t, duration, 3600, uint32_time_interval,, "Time duration of each log file, zero means one file per invocation")
|
||||||
|
24
configure.in
24
configure.in
@ -14,6 +14,30 @@ dnl Specify default instance path
|
|||||||
AC_ARG_VAR([INSTANCE_PATH], [default instance path for servald])
|
AC_ARG_VAR([INSTANCE_PATH], [default instance path for servald])
|
||||||
AS_IF([test "x$INSTANCE_PATH" != x], [AC_DEFINE_UNQUOTED([INSTANCE_PATH], ["$INSTANCE_PATH"], [default instance path])])
|
AS_IF([test "x$INSTANCE_PATH" != x], [AC_DEFINE_UNQUOTED([INSTANCE_PATH], ["$INSTANCE_PATH"], [default instance path])])
|
||||||
|
|
||||||
|
dnl Specify default Serval config directory
|
||||||
|
AC_ARG_VAR([SERVAL_ETC_PATH], [default Serval config directory])
|
||||||
|
AS_IF([test "x$SERVAL_ETC_PATH" != x], [AC_DEFINE_UNQUOTED([SERVAL_ETC_PATH], ["$SERVAL_ETC_PATH"], [default config directory])])
|
||||||
|
|
||||||
|
dnl Specify default Serval run directory
|
||||||
|
AC_ARG_VAR([SERVAL_RUN_PATH], [default Serval run directory])
|
||||||
|
AS_IF([test "x$SERVAL_RUN_PATH" != x], [AC_DEFINE_UNQUOTED([SERVAL_RUN_PATH], ["$SERVAL_RUN_PATH"], [default run directory])])
|
||||||
|
|
||||||
|
dnl Specify default Serval log directory
|
||||||
|
AC_ARG_VAR([SERVAL_LOG_PATH], [default Serval log directory])
|
||||||
|
AS_IF([test "x$SERVAL_LOG_PATH" != x], [AC_DEFINE_UNQUOTED([SERVAL_LOG_PATH], ["$SERVAL_LOG_PATH"], [default log directory])])
|
||||||
|
|
||||||
|
dnl Specify default system log directory
|
||||||
|
AC_ARG_VAR([SYSTEM_LOG_PATH], [default system log directory])
|
||||||
|
AS_IF([test "x$SYSTEM_LOG_PATH" != x], [AC_DEFINE_UNQUOTED([SYSTEM_LOG_PATH], ["$SYSTEM_LOG_PATH"], [default system log directory])])
|
||||||
|
|
||||||
|
dnl Specify default Serval tmp directory
|
||||||
|
AC_ARG_VAR([SERVAL_TMP_PATH], [default Serval tmp directory])
|
||||||
|
AS_IF([test "x$SERVAL_TMP_PATH" != x], [AC_DEFINE_UNQUOTED([SERVAL_TMP_PATH], ["$SERVAL_TMP_PATH"], [default Serval tmp directory])])
|
||||||
|
|
||||||
|
dnl Specify default Rhizome store directory
|
||||||
|
AC_ARG_VAR([RHIZOME_STORE_PATH], [default Rhizome store directory])
|
||||||
|
AS_IF([test "x$RHIZOME_STORE_PATH" != x], [AC_DEFINE_UNQUOTED([RHIZOME_STORE_PATH], ["$RHIZOME_STORE_PATH"], [default Rhizome store directory])])
|
||||||
|
|
||||||
dnl VoIP test app
|
dnl VoIP test app
|
||||||
AC_ARG_ENABLE(voiptest,
|
AC_ARG_ENABLE(voiptest,
|
||||||
AS_HELP_STRING([--enable-voiptest], [Require VoIP test program (default: only build if dependencies are present)])
|
AS_HELP_STRING([--enable-voiptest], [Require VoIP test program (default: only build if dependencies are present)])
|
||||||
|
@ -38,23 +38,6 @@ An option **VALUE** is a string of [US-ASCII][] characters, excluding newline
|
|||||||
|
|
||||||
If a VALUE does not parse correctly, it is *invalid*.
|
If a VALUE does not parse correctly, it is *invalid*.
|
||||||
|
|
||||||
Instance directory
|
|
||||||
------------------
|
|
||||||
|
|
||||||
By default, **servald** stores its configuration, keyring, and other temporary
|
|
||||||
files in its *instance directory*. The instance directory is set at run time
|
|
||||||
by the `SERVALINSTANCE_PATH` environment variable. If this is not set, then
|
|
||||||
**servald** uses a built-in default path which depends on its build-time option
|
|
||||||
and target platform:
|
|
||||||
|
|
||||||
* as specified by the `./configure INSTANCE_PATH=<path>` option when **servald**
|
|
||||||
was built from source
|
|
||||||
* on Android `/data/data/org.servalproject/var/serval-node`
|
|
||||||
* on other platforms `/var/serval-node`
|
|
||||||
|
|
||||||
**servald** will create its instance directory (and all enclosing parent
|
|
||||||
directories) if it does not already exist.
|
|
||||||
|
|
||||||
Configuration persistence
|
Configuration persistence
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
@ -115,22 +98,152 @@ defective file. This means that **servald** may always be used to inspect and
|
|||||||
correct the configuration, and to stop a running daemon, despite a defective
|
correct the configuration, and to stop a running daemon, despite a defective
|
||||||
configuration file.
|
configuration file.
|
||||||
|
|
||||||
Daemon processes
|
Configuration reloading
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
A running daemon re-loads its configuration whenever the `serval.conf` file is
|
||||||
|
changed. It does this by periodically checking the file's size and
|
||||||
|
modification time, and if they have changed, parses the file and updates its
|
||||||
|
own internal copy of the configuration settings.
|
||||||
|
|
||||||
|
As described above, the **servald** `start` command will not start a daemon
|
||||||
|
process if the `serval.conf` file is defective. However, the file may become
|
||||||
|
defective *after* the daemon has started.
|
||||||
|
|
||||||
|
In this case, the daemon will not terminate, nor load the defective file, but
|
||||||
|
will log an error and continue execution with its internal configuration
|
||||||
|
unchanged. The daemon's internal configuration will no longer be consistent
|
||||||
|
with the contents of the file. If the daemon is stopped or killed, it cannot
|
||||||
|
be re-started while `serval.conf` remains defective.
|
||||||
|
|
||||||
|
Despite detecting a defective configuration file, the daemon continues to check
|
||||||
|
for changes to the file, and attempts to re-load whenever it changes. As soon
|
||||||
|
as the defective `serval.conf` is fixed, the running daemon will load it
|
||||||
|
successfully and continue execution with the new configuration. The internal
|
||||||
|
configuration and the file contents will once again be consistent.
|
||||||
|
|
||||||
|
Daemon instances
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
To run more than one **servald** daemon process on the same device, each daemon
|
It order to support more than one daemon running on the same host, each daemon
|
||||||
must have its own instance path (and hence its own `serval.conf`). Set the
|
can be configured to use its own *instance directory*, as follows:
|
||||||
`SERVALINSTANCE_PATH` environment variable to a different directory path before
|
|
||||||
starting each daemon.
|
|
||||||
|
|
||||||
As described above, a defective `serval.conf` will prevent the **servald**
|
* A daemon's instance directory can be set at run time by setting the
|
||||||
`start` command from starting a daemon process. Once the daemon is running, it
|
`SERVALINSTANCE_PATH` environment variable prior to starting the daemon.
|
||||||
periodically checks whether `serval.conf` has changed (by comparing size and
|
This overrides all default paths. Once a daemon is running, the only way
|
||||||
modification time) and attempts to re-load it if it detects a change. If the
|
to change its instance directory is to stop it and start another daemon
|
||||||
re-loaded file is defective, the daemon rejects it, logs an error, and
|
with a different value for the environment variable.
|
||||||
continues execution with its prior configuration unchanged. If the daemon is
|
|
||||||
stopped or killed, it cannot be re-started while `serval.conf` remains
|
* If the instance directory is not set at run time, then if **servald** was
|
||||||
defective.
|
built with the `./configure INSTANCE_PATH=DIR` option, then the **servald**
|
||||||
|
executable will use the instance directory in `DIR` by default. The FHS
|
||||||
|
paths will never be used.
|
||||||
|
|
||||||
|
* On an Android system, if none of the above are used, then **servald** will
|
||||||
|
use the instance directory `/data/data/org.servalproject/var/serval-node`
|
||||||
|
by default. The FHS paths will never be used.
|
||||||
|
|
||||||
|
* If none of the above apply, then there is no *instance directory*.
|
||||||
|
Instead, [FHS][] paths are used (see below). Only one daemon can run in
|
||||||
|
this situation on the same host, since the single, common PID file will
|
||||||
|
prevent more than one being started.
|
||||||
|
|
||||||
|
The main use for multiple instances on a single host is for testing, and this
|
||||||
|
is used extensively in the automated test suite. Deployments other than
|
||||||
|
Android are unlikely to use an instance path, so the FHS paths are most likely
|
||||||
|
to be used in practice.
|
||||||
|
|
||||||
|
FHS paths
|
||||||
|
---------
|
||||||
|
|
||||||
|
By default, **servald** locates its files such as configuration, logs, Rhizome
|
||||||
|
storage, etc. in accordance with the [Filesystem Heirarchy Standard][FHS] 2.3:
|
||||||
|
|
||||||
|
* the **servald** executable is installed in `/usr/local/bin/servald`
|
||||||
|
* the configuration is stored in `/etc/serval/serval.conf`
|
||||||
|
* the keyring is stored in `/etc/serval/serval.keyring`
|
||||||
|
* the PID file is `/var/run/serval/servald.pid`
|
||||||
|
* the daemon creates its process information files under
|
||||||
|
`/var/run/serval/proc/`
|
||||||
|
* the daemon creates and rotates log files files under
|
||||||
|
`/var/log/serval/`
|
||||||
|
* the daemon creates and updates a symbolic link to the latest log file in
|
||||||
|
`/var/log/servald.log`
|
||||||
|
* the Rhizome store is in `/var/cache/serval/` (unless overridden by
|
||||||
|
configuration):
|
||||||
|
* the SQLite database is `/var/cache/serval/rhizome.db`
|
||||||
|
* large payloads are stored under `/var/cache/serval/blob/`
|
||||||
|
* the SQLite temporary directory is `/tmp/serval/sqlite3tmp/`
|
||||||
|
* dummy interface files are created under `/tmp/serval/` (unless overridden
|
||||||
|
by configuration)
|
||||||
|
|
||||||
|
The **servald** `start` command will create all sub-directories within the
|
||||||
|
standard FHS paths as needed, and any failure will cause the daemon not to
|
||||||
|
start.
|
||||||
|
|
||||||
|
The following build-time configuration options are available to alter the paths
|
||||||
|
described above, which can help adapt **servald** to systems which use a
|
||||||
|
different software installation convention (eg, all packages are installed
|
||||||
|
under `/opt/packagename`) or which have a volatile `/var` directory (eg, on
|
||||||
|
OpenWRT, `/var` is a symlink to `/tmp`):
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure --prefix=DIR` option, then
|
||||||
|
the executable is installed in `DIR/bin` instead of `/usr/local/bin`
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure --sysconfdir=DIR` option,
|
||||||
|
then it will use `DIR` in place of `/etc`
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure --localstatedir=DIR` option,
|
||||||
|
then it will use `DIR` in place of `/var`
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure SERVAL_ETC_PATH=DIR` option,
|
||||||
|
then it will use `DIR` in place of `/etc/serval`
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure SERVAL_RUN_PATH=DIR` option,
|
||||||
|
then it will use `DIR` in place of `/var/run/serval`
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure SYSTEM_LOG_PATH=DIR` option,
|
||||||
|
then it will use `DIR` in place of `/var/log`
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure SERVAL_LOG_PATH=DIR` option,
|
||||||
|
then it will use `DIR` in place of `/var/log/serval`
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure RHIZOME_STORE_PATH=DIR`
|
||||||
|
option, then it will use `DIR` in place of `/var/cache/serval` for the
|
||||||
|
Rhizome store
|
||||||
|
|
||||||
|
* If **servald** is built with the `./configure SERVAL_TMP_PATH=DIR` option,
|
||||||
|
then it will use `DIR` in place of `/tmp/serval`
|
||||||
|
|
||||||
|
The **servald** `config paths` command will display all the paths in use, based
|
||||||
|
on the built-in defaults as overridden by configuration settings and run-time
|
||||||
|
environment variables available to the command. This command will work even if
|
||||||
|
configuration is defective, so is a useful diagnostic tool.
|
||||||
|
|
||||||
|
Instance directory paths
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
If **servald** is started with an *instance directory*, then all configuration,
|
||||||
|
state, and temporary files are stored in or beneath that directory, denoted
|
||||||
|
`IDIR`:
|
||||||
|
|
||||||
|
* the configuration is stored in `IDIR/serval.conf`
|
||||||
|
* the keyring is stored in `IDIR/serval.keyring`
|
||||||
|
* the PID file is `IDIR/servald.pid`
|
||||||
|
* the daemon creates its process information files under `IDIR/proc/`
|
||||||
|
* the daemon creates and rotates log files files under `IDIR/log/`
|
||||||
|
* the daemon creates and updates a symbolic link to the latest log file in
|
||||||
|
`IDIR/servald.log`
|
||||||
|
* the Rhizome store is in `IDIR/` (unless overridden by configuration):
|
||||||
|
* the SQLite database is `IDIR/rhizome.db`
|
||||||
|
* large payloads are stored under `IDIR/blob/`
|
||||||
|
* the SQLite temporary directory is `IDIR/sqlite3tmp/`
|
||||||
|
* dummy interface files are created under `IDIR/` (unless overridden by
|
||||||
|
configuration)
|
||||||
|
|
||||||
|
The **servald** `start` command will create its instance directory (and all
|
||||||
|
enclosing parent directories) if it does not already exist. Failure will cause
|
||||||
|
the daemon not to start.
|
||||||
|
|
||||||
About the examples
|
About the examples
|
||||||
------------------
|
------------------
|
||||||
@ -300,8 +413,10 @@ All log destinations support the following configuration options:
|
|||||||
In addition, the *file* destination has these extra configuration options:
|
In addition, the *file* destination has these extra configuration options:
|
||||||
|
|
||||||
* `log.file.directory_path` If set, log files are created in this directory,
|
* `log.file.directory_path` If set, log files are created in this directory,
|
||||||
which is created if it does not exist. This defaults to the `log`
|
which is created if it does not exist. Relative paths are interpreted
|
||||||
directory within the instance directory.
|
relative to the `log` sub-directory of the instance directory. The default
|
||||||
|
setting (empty string) causes log files to be created within the `log`
|
||||||
|
sub-directory of the instance directory.
|
||||||
|
|
||||||
* `log.file.path` If set, all log messages are appended directly to the file
|
* `log.file.path` If set, all log messages are appended directly to the file
|
||||||
at the given path. If the path is not absolute, it is interpreted relative
|
at the given path. If the path is not absolute, it is interpreted relative
|
||||||
|
207
instance.c
207
instance.c
@ -24,46 +24,207 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "strbuf_helpers.h"
|
#include "strbuf_helpers.h"
|
||||||
|
|
||||||
static char *thisinstancepath = NULL;
|
/*
|
||||||
|
* A default INSTANCE_PATH can be set on the ./configure command line, eg:
|
||||||
|
*
|
||||||
|
* ./configure INSTANCE_PATH=/var/local/serval/node
|
||||||
|
*
|
||||||
|
* This will cause servald to never use FHS paths, and always use an instance
|
||||||
|
* path, even if the SERVALINSTANCE_PATH environment variable is not set.
|
||||||
|
*/
|
||||||
|
#ifdef INSTANCE_PATH
|
||||||
|
#define DEFAULT_INSTANCE_PATH INSTANCE_PATH
|
||||||
|
#else
|
||||||
|
|
||||||
const char *serval_instancepath()
|
/* On Android systems, always use an instance path (no FHS paths).
|
||||||
|
*/
|
||||||
|
#ifdef ANDROID
|
||||||
|
#define DEFAULT_INSTANCE_PATH "/data/data/org.servalproject/var/serval-node"
|
||||||
|
#define SERVAL_ETC_PATH ""
|
||||||
|
#define SERVAL_RUN_PATH ""
|
||||||
|
#define SYSTEM_LOG_PATH ""
|
||||||
|
#define SERVAL_LOG_PATH ""
|
||||||
|
#define SERVAL_CACHE_PATH ""
|
||||||
|
#define SERVAL_TMP_PATH ""
|
||||||
|
#define RHIZOME_STORE_PATH ""
|
||||||
|
#else
|
||||||
|
#define DEFAULT_INSTANCE_PATH NULL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The following paths are based on the Filesystem Hierarchy Standard (FHS) 2.3
|
||||||
|
* but can be altered using ./configure arguments, eg:
|
||||||
|
*
|
||||||
|
* ./configure SERVAL_LOG_PATH=/tmp/serval/log
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERVAL_ETC_PATH
|
||||||
|
#define SERVAL_ETC_PATH SYSCONFDIR "/serval"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SERVAL_RUN_PATH
|
||||||
|
#define SERVAL_RUN_PATH LOCALSTATEDIR "/run/serval"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SYSTEM_LOG_PATH
|
||||||
|
#define SYSTEM_LOG_PATH LOCALSTATEDIR "/log"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SERVAL_LOG_PATH
|
||||||
|
#define SERVAL_LOG_PATH SYSTEM_LOG_PATH "/serval"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SERVAL_CACHE_PATH
|
||||||
|
#define SERVAL_CACHE_PATH LOCALSTATEDIR "/cache/serval"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SERVAL_TMP_PATH
|
||||||
|
#define SERVAL_TMP_PATH "/tmp/serval"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RHIZOME_STORE_PATH
|
||||||
|
#define RHIZOME_STORE_PATH SERVAL_CACHE_PATH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int know_instancepath = 0;
|
||||||
|
static char *instancepath = NULL;
|
||||||
|
|
||||||
|
const char *instance_path()
|
||||||
{
|
{
|
||||||
if (thisinstancepath)
|
if (!know_instancepath) {
|
||||||
return thisinstancepath;
|
instancepath = getenv("SERVALINSTANCE_PATH");
|
||||||
const char *instancepath = getenv("SERVALINSTANCE_PATH");
|
if (instancepath == NULL)
|
||||||
if (!instancepath)
|
|
||||||
instancepath = DEFAULT_INSTANCE_PATH;
|
instancepath = DEFAULT_INSTANCE_PATH;
|
||||||
|
know_instancepath = 1;
|
||||||
|
}
|
||||||
return instancepath;
|
return instancepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
int formf_serval_instance_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, ...)
|
static int vformf_path(struct __sourceloc __whence, strbuf b, const char *syspath, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
va_list ap;
|
if (fmt)
|
||||||
va_start(ap, fmt);
|
|
||||||
int ret = vformf_serval_instance_path(__whence, buf, bufsiz, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vformf_serval_instance_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
strbuf b = strbuf_local(buf, bufsiz);
|
|
||||||
strbuf_va_vprintf(b, fmt, ap);
|
strbuf_va_vprintf(b, fmt, ap);
|
||||||
if (!strbuf_overrun(b) && strbuf_len(b) && buf[0] != '/') {
|
if (!strbuf_overrun(b) && (strbuf_len(b) == 0 || strbuf_str(b)[0] != '/')) {
|
||||||
strbuf_reset(b);
|
strbuf_reset(b);
|
||||||
strbuf_puts(b, serval_instancepath());
|
const char *ipath = instance_path();
|
||||||
|
#ifdef ANDROID
|
||||||
|
assert(ipath != NULL);
|
||||||
|
#endif
|
||||||
|
strbuf_puts(b, ipath ? ipath : syspath);
|
||||||
|
if (fmt) {
|
||||||
|
if (strbuf_substr(b, -1)[0] != '/')
|
||||||
strbuf_putc(b, '/');
|
strbuf_putc(b, '/');
|
||||||
strbuf_va_vprintf(b, fmt, ap);
|
strbuf_va_vprintf(b, fmt, ap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!strbuf_overrun(b))
|
if (!strbuf_overrun(b))
|
||||||
return 1;
|
return 1;
|
||||||
WHYF("instance path overflow (strlen %lu, sizeof buffer %lu): %s",
|
WHYF("instance path overflow (strlen %lu, sizeof buffer %lu): %s",
|
||||||
(unsigned long)strbuf_count(b),
|
(unsigned long)strbuf_count(b),
|
||||||
(unsigned long)bufsiz,
|
(unsigned long)strbuf_size(b),
|
||||||
alloca_str_toprint(buf));
|
alloca_str_toprint(strbuf_str(b)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_serval_instance_dir() {
|
int _formf_serval_etc_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, ...)
|
||||||
return emkdirs(serval_instancepath(), 0700);
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
int ret = vformf_path(__whence, strbuf_local(buf, bufsiz), SERVAL_ETC_PATH, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _formf_serval_run_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
int ret = _vformf_serval_run_path(__whence, buf, bufsiz, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _vformf_serval_run_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
return vformf_path(__whence, strbuf_local(buf, bufsiz), SERVAL_RUN_PATH, fmt, ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf strbuf_system_log_path(strbuf sb)
|
||||||
|
{
|
||||||
|
const char *ipath = instance_path();
|
||||||
|
strbuf_puts(sb, ipath ? ipath : SYSTEM_LOG_PATH);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf strbuf_serval_log_path(strbuf sb)
|
||||||
|
{
|
||||||
|
const char *ipath = instance_path();
|
||||||
|
if (ipath)
|
||||||
|
strbuf_path_join(sb, ipath, "log", NULL);
|
||||||
|
else
|
||||||
|
strbuf_puts(sb, SERVAL_LOG_PATH);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _formf_serval_cache_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
int ret = vformf_path(__whence, strbuf_local(buf, bufsiz), SERVAL_CACHE_PATH, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _formf_rhizome_store_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
int ret = vformf_path(__whence, strbuf_local(buf, bufsiz), RHIZOME_STORE_PATH, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _formf_serval_tmp_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
int ret = vformf_path(__whence, strbuf_local(buf, bufsiz), SERVAL_TMP_PATH, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _formf_servald_proc_path(struct __sourceloc __whence, char *buf, size_t bufsiz, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
int ret = vformf_path(__whence, strbuf_local(buf, bufsiz), SERVAL_RUN_PATH "/proc", fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_serval_instance_dir()
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
if (FORMF_SERVAL_ETC_PATH(path, NULL) && emkdirs_info(path, 0755) == -1)
|
||||||
|
ret = -1;
|
||||||
|
if (FORMF_SERVAL_RUN_PATH(path, NULL) && emkdirs_info(path, 0700) == -1)
|
||||||
|
ret = -1;
|
||||||
|
if (FORMF_SERVAL_CACHE_PATH(path, NULL) && emkdirs_info(path, 0700) == -1)
|
||||||
|
ret = -1;
|
||||||
|
strbuf sb = strbuf_local(path, sizeof path);
|
||||||
|
strbuf_system_log_path(sb);
|
||||||
|
if (!strbuf_overrun(sb) && emkdirs_info(path, 0700) == -1)
|
||||||
|
ret = -1;
|
||||||
|
strbuf_reset(sb);
|
||||||
|
strbuf_serval_log_path(sb);
|
||||||
|
if (!strbuf_overrun(sb) && emkdirs_info(path, 0700) == -1)
|
||||||
|
ret = -1;
|
||||||
|
if (FORMF_SERVAL_TMP_PATH(path, NULL) && emkdirs_info(path, 0700) == -1)
|
||||||
|
ret = -1;
|
||||||
|
if (FORMF_SERVALD_PROC_PATH(path, NULL) && emkdirs_info(path, 0755) == -1)
|
||||||
|
ret = -1;
|
||||||
|
if (FORMF_RHIZOME_STORE_PATH(path, NULL) && emkdirs_info(path, 0700) == -1)
|
||||||
|
ret = -1;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
60
instance.h
60
instance.h
@ -21,34 +21,40 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#define __SERVAL_DNA__INSTANCE_H
|
#define __SERVAL_DNA__INSTANCE_H
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
/*
|
const char *instance_path(); // returns NULL if not using an instance path
|
||||||
* A default INSTANCE_PATH can be set on the ./configure command line, eg:
|
|
||||||
*
|
|
||||||
* ./configure INSTANCE_PATH=/var/local/serval/node
|
|
||||||
*
|
|
||||||
* This will cause servald to never use FHS paths, and always use an instance
|
|
||||||
* path, even if the SERVALINSTANCE_PATH environment variable is not set.
|
|
||||||
*/
|
|
||||||
#ifdef INSTANCE_PATH
|
|
||||||
#define DEFAULT_INSTANCE_PATH INSTANCE_PATH
|
|
||||||
#else
|
|
||||||
#ifdef ANDROID
|
|
||||||
#define DEFAULT_INSTANCE_PATH "/data/data/org.servalproject/var/serval-node"
|
|
||||||
#else
|
|
||||||
#define DEFAULT_INSTANCE_PATH NULL
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Handy statement for forming a path to an instance file in a char buffer whose declaration
|
|
||||||
* is in scope (so that sizeof(buf) will work). Evaluates to true if the pathname fitted into
|
|
||||||
* the provided buffer, false (0) otherwise (after logging an error).
|
|
||||||
*/
|
|
||||||
#define FORM_SERVAL_INSTANCE_PATH(buf, path) (formf_serval_instance_path(__WHENCE__, buf, sizeof(buf), "%s", (path)))
|
|
||||||
|
|
||||||
const char *serval_instancepath();
|
|
||||||
int create_serval_instance_dir();
|
int create_serval_instance_dir();
|
||||||
int formf_serval_instance_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
|
|
||||||
int vformf_serval_instance_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, va_list);
|
int _formf_serval_etc_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
|
||||||
|
int _formf_serval_run_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
|
||||||
|
int _vformf_serval_run_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, va_list);
|
||||||
|
int _formf_serval_cache_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
|
||||||
|
int _formf_serval_tmp_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
|
||||||
|
int _formf_servald_proc_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
|
||||||
|
int _formf_rhizome_store_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
|
||||||
|
|
||||||
|
#define formf_serval_etc_path(buf,bufsz,fmt,...) _formf_serval_etc_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)
|
||||||
|
#define formf_serval_run_path(buf,bufsz,fmt,...) _formf_serval_run_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)
|
||||||
|
#define vformf_serval_run_path(buf,bufsz,fmt,ap) _vformf_serval_run_path(__WHENCE__, buf, bufsz, fmt, ap)
|
||||||
|
#define formf_serval_cache_path(buf,bufsz,fmt,...) _formf_serval_cache_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)
|
||||||
|
#define formf_serval_tmp_path(buf,bufsz,fmt,...) _formf_serval_tmp_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)
|
||||||
|
#define formf_servald_proc_path(buf,bufsz,fmt,...) _formf_servald_proc_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)
|
||||||
|
#define formf_rhizome_store_path(buf,bufsz,fmt,...) _formf_rhizome_store_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/* Handy macros for forming the absolute paths of various files, using a char[]
|
||||||
|
* buffer whose declaration is in scope (so that sizeof(buf) will work).
|
||||||
|
* Evaluates to true if the pathname fits into the provided buffer, false (0)
|
||||||
|
* otherwise (after logging an error).
|
||||||
|
*/
|
||||||
|
#define FORMF_SERVAL_ETC_PATH(buf,fmt,...) formf_serval_etc_path(buf, sizeof(buf), fmt, ##__VA_ARGS__)
|
||||||
|
#define FORMF_SERVAL_RUN_PATH(buf,fmt,...) formf_serval_run_path(buf, sizeof(buf), fmt, ##__VA_ARGS__)
|
||||||
|
#define FORMF_SERVAL_CACHE_PATH(buf,fmt,...) formf_serval_cache_path(buf, sizeof(buf), fmt, ##__VA_ARGS__)
|
||||||
|
#define FORMF_SERVAL_TMP_PATH(buf,fmt,...) formf_serval_tmp_path(buf, sizeof(buf), fmt, ##__VA_ARGS__)
|
||||||
|
#define FORMF_SERVALD_PROC_PATH(buf,fmt,...) formf_servald_proc_path(buf, sizeof(buf), fmt, ##__VA_ARGS__)
|
||||||
|
#define FORMF_RHIZOME_STORE_PATH(buf,fmt,...) formf_rhizome_store_path((buf), sizeof(buf), (fmt), ##__VA_ARGS__)
|
||||||
|
|
||||||
|
strbuf strbuf_system_log_path(strbuf sb);
|
||||||
|
strbuf strbuf_serval_log_path(strbuf sb);
|
||||||
|
|
||||||
#endif // __SERVAL_DNA__INSTANCE_H
|
#endif // __SERVAL_DNA__INSTANCE_H
|
||||||
|
@ -2020,7 +2020,7 @@ keyring_file *keyring_open_instance()
|
|||||||
if (!env)
|
if (!env)
|
||||||
env = "serval.keyring";
|
env = "serval.keyring";
|
||||||
char keyringFile[1024];
|
char keyringFile[1024];
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(keyringFile, env))
|
if (!FORMF_SERVAL_ETC_PATH(keyringFile, "%s", env))
|
||||||
RETURN(NULL);
|
RETURN(NULL);
|
||||||
// Work out if the keyring file is writeable.
|
// Work out if the keyring file is writeable.
|
||||||
int writeable = 0;
|
int writeable = 0;
|
||||||
|
60
log.c
60
log.c
@ -95,9 +95,12 @@ static FILE *_log_file = NULL;
|
|||||||
static void _open_log_file(_log_iterator *);
|
static void _open_log_file(_log_iterator *);
|
||||||
static void _rotate_log_file(_log_iterator *it);
|
static void _rotate_log_file(_log_iterator *it);
|
||||||
static void _flush_log_file();
|
static void _flush_log_file();
|
||||||
struct _log_state state_file;
|
static struct _log_state state_file;
|
||||||
struct config_log_format config_file;
|
static struct config_log_format config_file;
|
||||||
time_t _log_file_start_time;
|
static struct { size_t len; mode_t mode; } mkdir_trace[10];
|
||||||
|
static mode_t mkdir_trace_latest_mode;
|
||||||
|
static unsigned mkdir_count;
|
||||||
|
static time_t _log_file_start_time;
|
||||||
static char _log_file_buf[8192];
|
static char _log_file_buf[8192];
|
||||||
static struct strbuf _log_file_strbuf = STRUCT_STRBUF_EMPTY;
|
static struct strbuf _log_file_strbuf = STRUCT_STRBUF_EMPTY;
|
||||||
|
|
||||||
@ -424,11 +427,6 @@ static void _logs_printf_nl(int level, struct __sourceloc whence, const char *fm
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *log_file_directory_path()
|
|
||||||
{
|
|
||||||
return config.log.file.directory_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _compute_file_start_time(_log_iterator *it)
|
static void _compute_file_start_time(_log_iterator *it)
|
||||||
{
|
{
|
||||||
if (it->file_start_time == 0) {
|
if (it->file_start_time == 0) {
|
||||||
@ -440,6 +438,27 @@ static void _compute_file_start_time(_log_iterator *it)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void trace_mkdir(struct __sourceloc UNUSED(whence), const char *path, mode_t mode)
|
||||||
|
{
|
||||||
|
if (mkdir_count < NELS(mkdir_trace)) {
|
||||||
|
mkdir_trace[mkdir_count].len = strlen(path);
|
||||||
|
mkdir_trace[mkdir_count].mode = mode;
|
||||||
|
}
|
||||||
|
++mkdir_count;
|
||||||
|
mkdir_trace_latest_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_mkdir_trace(const char *dir)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < mkdir_count && i < NELS(mkdir_trace); ++i)
|
||||||
|
_logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Created %s (mode %04o)", alloca_toprint(-1, dir, mkdir_trace[i].len), mkdir_trace[i].mode);
|
||||||
|
if (mkdir_count > NELS(mkdir_trace) + 1)
|
||||||
|
_logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Created ...");
|
||||||
|
if (mkdir_count > NELS(mkdir_trace))
|
||||||
|
_logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Created %s (mode %04o)", alloca_str_toprint(dir), mkdir_trace_latest_mode);
|
||||||
|
}
|
||||||
|
|
||||||
static void _open_log_file(_log_iterator *it)
|
static void _open_log_file(_log_iterator *it)
|
||||||
{
|
{
|
||||||
assert(it->state == &state_file);
|
assert(it->state == &state_file);
|
||||||
@ -448,14 +467,15 @@ static void _open_log_file(_log_iterator *it)
|
|||||||
_log_file_path = getenv("SERVALD_LOG_FILE");
|
_log_file_path = getenv("SERVALD_LOG_FILE");
|
||||||
if (_log_file_path == NULL && !cf_limbo) {
|
if (_log_file_path == NULL && !cf_limbo) {
|
||||||
strbuf sbfile = strbuf_local(_log_file_path_buf, sizeof _log_file_path_buf);
|
strbuf sbfile = strbuf_local(_log_file_path_buf, sizeof _log_file_path_buf);
|
||||||
strbuf_path_join(sbfile, serval_instancepath(), log_file_directory_path(), NULL);
|
strbuf_serval_log_path(sbfile);
|
||||||
|
strbuf_path_join(sbfile, config.log.file.directory_path, "", NULL); // with trailing '/'
|
||||||
_compute_file_start_time(it);
|
_compute_file_start_time(it);
|
||||||
if (config.log.file.path[0]) {
|
if (config.log.file.path[0]) {
|
||||||
strbuf_path_join(sbfile, config.log.file.path, NULL);
|
strbuf_path_join(sbfile, config.log.file.path, NULL);
|
||||||
} else {
|
} else {
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
(void)localtime_r(&it->file_start_time, &tm);
|
(void)localtime_r(&it->file_start_time, &tm);
|
||||||
strbuf_append_strftime(sbfile, "/serval-%Y%m%d%H%M%S.log", &tm);
|
strbuf_append_strftime(sbfile, "serval-%Y%m%d%H%M%S.log", &tm);
|
||||||
}
|
}
|
||||||
if (strbuf_overrun(sbfile)) {
|
if (strbuf_overrun(sbfile)) {
|
||||||
_log_file = NO_FILE;
|
_log_file = NO_FILE;
|
||||||
@ -477,16 +497,27 @@ static void _open_log_file(_log_iterator *it)
|
|||||||
char _dir[dirsiz];
|
char _dir[dirsiz];
|
||||||
strcpy(_dir, _log_file_path);
|
strcpy(_dir, _log_file_path);
|
||||||
const char *dir = dirname(_dir); // modifies _dir[]
|
const char *dir = dirname(_dir); // modifies _dir[]
|
||||||
if (mkdirs(dir, 0700) != -1 && (_log_file = fopen(_log_file_path, "a"))) {
|
mkdir_count = 0;
|
||||||
|
if (mkdirs_log(dir, 0700, trace_mkdir) == -1) {
|
||||||
|
_log_file = NO_FILE;
|
||||||
|
log_mkdir_trace(dir);
|
||||||
|
_logs_printf_nl(LOG_LEVEL_WARN, __HERE__, "Cannot mkdir %s - %s [errno=%d]", alloca_str_toprint(dir), strerror(errno), errno);
|
||||||
|
} else if ((_log_file = fopen(_log_file_path, "a")) == NULL) {
|
||||||
|
_log_file = NO_FILE;
|
||||||
|
log_mkdir_trace(dir);
|
||||||
|
_logs_printf_nl(LOG_LEVEL_WARN, __HERE__, "Cannot create-append %s - %s [errno=%d]", _log_file_path, strerror(errno), errno);
|
||||||
|
} else {
|
||||||
setlinebuf(_log_file);
|
setlinebuf(_log_file);
|
||||||
memset(it->state, 0, sizeof *it->state);
|
memset(it->state, 0, sizeof *it->state);
|
||||||
// The first line in every log file must be the starting time stamp. (After that, it is up
|
// The first line in every log file must be the starting time stamp. (After that, it is up
|
||||||
// to _log_update() to insert other mandatory messages in any suitable order.)
|
// to _log_update() to insert other mandatory messages in any suitable order.)
|
||||||
_log_current_datetime(it, LOG_LEVEL_INFO);
|
_log_current_datetime(it, LOG_LEVEL_INFO);
|
||||||
|
log_mkdir_trace(dir);
|
||||||
_logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Logging to %s (fd %d)", _log_file_path, fileno(_log_file));
|
_logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Logging to %s (fd %d)", _log_file_path, fileno(_log_file));
|
||||||
// Update the log symlink to point to the latest log file.
|
// Update the log symlink to point to the latest log file.
|
||||||
strbuf sbsymlink = strbuf_alloca(400);
|
strbuf sbsymlink = strbuf_alloca(400);
|
||||||
strbuf_path_join(sbsymlink, serval_instancepath(), "serval.log", NULL);
|
strbuf_system_log_path(sbsymlink);
|
||||||
|
strbuf_path_join(sbsymlink, "serval.log", NULL);
|
||||||
if (strbuf_overrun(sbsymlink))
|
if (strbuf_overrun(sbsymlink))
|
||||||
_logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot form log symlink name - buffer overrun");
|
_logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot form log symlink name - buffer overrun");
|
||||||
else {
|
else {
|
||||||
@ -556,9 +587,6 @@ static void _open_log_file(_log_iterator *it)
|
|||||||
_logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Unlink %s", path);
|
_logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Unlink %s", path);
|
||||||
unlink(path);
|
unlink(path);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
_log_file = NO_FILE;
|
|
||||||
_logs_printf_nl(LOG_LEVEL_WARN, __HERE__, "Cannot create/append %s - %s [errno=%d]", _log_file_path, strerror(errno), errno);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -741,7 +769,7 @@ int log_backtrace(int level, struct __sourceloc whence)
|
|||||||
if (get_self_executable_path(execpath, sizeof execpath) == -1)
|
if (get_self_executable_path(execpath, sizeof execpath) == -1)
|
||||||
return WHY("cannot log backtrace: own executable path unknown");
|
return WHY("cannot log backtrace: own executable path unknown");
|
||||||
char tempfile[MAXPATHLEN];
|
char tempfile[MAXPATHLEN];
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(tempfile, "servalgdb.XXXXXX"))
|
if (!FORMF_SERVAL_TMP_PATH(tempfile, "servalgdb.XXXXXX"))
|
||||||
return -1;
|
return -1;
|
||||||
int tmpfd = mkstemp(tempfile);
|
int tmpfd = mkstemp(tempfile);
|
||||||
if (tmpfd == -1)
|
if (tmpfd == -1)
|
||||||
|
1
log.h
1
log.h
@ -92,7 +92,6 @@ extern const struct __sourceloc __whence; // see above
|
|||||||
|
|
||||||
extern int serverMode;
|
extern int serverMode;
|
||||||
|
|
||||||
const char *log_file_directory_path();
|
|
||||||
int create_log_file_directory();
|
int create_log_file_directory();
|
||||||
|
|
||||||
void close_log_file();
|
void close_log_file();
|
||||||
|
43
os.c
43
os.c
@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define __SERVAL_DNA__OS_INLINE
|
#define __SERVAL_DNA__OS_INLINE
|
||||||
|
#include "constants.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -31,39 +32,52 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int mkdirs(const char *path, mode_t mode)
|
void log_info_mkdir(struct __sourceloc __whence, const char *path, mode_t mode)
|
||||||
{
|
{
|
||||||
return mkdirsn(path, strlen(path), mode);
|
INFOF("mkdir %s (mode %04o)", alloca_str_toprint(path), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _emkdirs(struct __sourceloc __whence, const char *path, mode_t mode)
|
int _mkdirs(struct __sourceloc __whence, const char *path, mode_t mode, MKDIR_LOG_FUNC *logger)
|
||||||
{
|
{
|
||||||
if (mkdirs(path, mode) == -1)
|
return _mkdirsn(__whence, path, strlen(path), mode, logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _emkdirs(struct __sourceloc __whence, const char *path, mode_t mode, MKDIR_LOG_FUNC *logger)
|
||||||
|
{
|
||||||
|
if (_mkdirs(__whence, path, mode, logger) == -1)
|
||||||
return WHYF_perror("mkdirs(%s,%o)", alloca_str_toprint(path), mode);
|
return WHYF_perror("mkdirs(%s,%o)", alloca_str_toprint(path), mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _emkdirsn(struct __sourceloc __whence, const char *path, size_t len, mode_t mode)
|
int _emkdirsn(struct __sourceloc __whence, const char *path, size_t len, mode_t mode, MKDIR_LOG_FUNC *logger)
|
||||||
{
|
{
|
||||||
if (mkdirsn(path, len, mode) == -1)
|
if (_mkdirsn(__whence, path, len, mode, logger) == -1)
|
||||||
return WHYF_perror("mkdirsn(%s,%lu,%o)", alloca_toprint(-1, path, len), (unsigned long)len, mode);
|
return WHYF_perror("mkdirsn(%s,%lu,%o)", alloca_toprint(-1, path, len), (unsigned long)len, mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This variant must not log anything, because it is used by the logging subsystem itself!
|
/* This variant must not log anything itself, because it is called by the logging subsystem, and
|
||||||
|
* that would cause infinite recursion!
|
||||||
|
*
|
||||||
|
* The path need not be NUL terminated.
|
||||||
|
*
|
||||||
|
* The logger function pointer is usually NULL, for no logging, but may be any function the caller
|
||||||
|
* supplies (for example, log_info_mkdir).
|
||||||
*
|
*
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
*/
|
*/
|
||||||
int mkdirsn(const char *path, size_t len, mode_t mode)
|
int _mkdirsn(struct __sourceloc whence, const char *path, size_t len, mode_t mode, MKDIR_LOG_FUNC *logger)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
else {
|
else {
|
||||||
char *pathfrag = alloca(len + 1);
|
char *pathfrag = alloca(len + 1);
|
||||||
strncpy(pathfrag, path, len);
|
strncpy(pathfrag, path, len)[len] = '\0';
|
||||||
pathfrag[len] = '\0';
|
if (mkdir(pathfrag, mode) != -1) {
|
||||||
if (mkdir(pathfrag, mode) != -1)
|
if (logger)
|
||||||
|
logger(whence, pathfrag, mode);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
DIR *d = opendir(pathfrag);
|
DIR *d = opendir(pathfrag);
|
||||||
if (d) {
|
if (d) {
|
||||||
@ -78,13 +92,16 @@ int mkdirsn(const char *path, size_t len, mode_t mode)
|
|||||||
while (lastsep != path && *--lastsep == '/')
|
while (lastsep != path && *--lastsep == '/')
|
||||||
;
|
;
|
||||||
if (lastsep != path) {
|
if (lastsep != path) {
|
||||||
if (mkdirsn(path, lastsep - path + 1, mode) == -1)
|
if (_mkdirsn(whence, path, lastsep - path + 1, mode, logger) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (mkdir(pathfrag, mode) != -1)
|
if (mkdir(pathfrag, mode) != -1) {
|
||||||
|
if (logger)
|
||||||
|
logger(whence, pathfrag, mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
os.h
26
os.h
@ -103,13 +103,27 @@ __SERVAL_DNA__OS_INLINE off64_t lseek64(int fd, off64_t offset, int whence) {
|
|||||||
|
|
||||||
/* The "e" variants log the error before returning -1.
|
/* The "e" variants log the error before returning -1.
|
||||||
*/
|
*/
|
||||||
int mkdirs(const char *path, mode_t mode);
|
typedef void MKDIR_LOG_FUNC(struct __sourceloc, const char *, mode_t);
|
||||||
int mkdirsn(const char *path, size_t len, mode_t mode);
|
MKDIR_LOG_FUNC log_info_mkdir;
|
||||||
int _emkdirs(struct __sourceloc, const char *path, mode_t mode);
|
int _mkdirs(struct __sourceloc, const char *path, mode_t mode, MKDIR_LOG_FUNC *);
|
||||||
int _emkdirsn(struct __sourceloc, const char *path, size_t len, mode_t mode);
|
int _mkdirsn(struct __sourceloc, const char *path, size_t len, mode_t mode, MKDIR_LOG_FUNC *);
|
||||||
|
int _emkdirs(struct __sourceloc, const char *path, mode_t mode, MKDIR_LOG_FUNC *);
|
||||||
|
int _emkdirsn(struct __sourceloc, const char *path, size_t len, mode_t mode, MKDIR_LOG_FUNC *);
|
||||||
|
|
||||||
#define emkdirs(path, mode) _emkdirs(__WHENCE__, (path), (mode))
|
#define mkdirs_log(path, mode, func) _mkdirs(__WHENCE__, (path), (mode), (func))
|
||||||
#define emkdirsn(path, len, mode) _emkdirsn(__WHENCE__, (path), (len), (mode))
|
#define mkdirsn_log(path, len, mode, func) _mkdirsn(__WHENCE__, (path), (len), (mode), (func))
|
||||||
|
#define emkdirs_log(path, mode, func) _emkdirs(__WHENCE__, (path), (mode), (func))
|
||||||
|
#define emkdirsn_log(path, len, mode, func) _emkdirsn(__WHENCE__, (path), (len), (mode), (func))
|
||||||
|
|
||||||
|
#define mkdirs(path, mode) mkdirs_log((path), (mode), NULL)
|
||||||
|
#define mkdirsn(path, len, mode) mkdirsn_log((path), (len), (mode), NULL)
|
||||||
|
#define emkdirs(path, mode) emkdirs_log((path), (mode), NULL)
|
||||||
|
#define emkdirsn(path, len, mode) emkdirsn_log((path), (len), (mode), NULL)
|
||||||
|
|
||||||
|
#define mkdirs_info(path, mode) mkdirs_log((path), (mode), log_info_mkdir)
|
||||||
|
#define mkdirsn_info(path, len, mode) mkdirsn_log((path), (len), (mode), log_info_mkdir)
|
||||||
|
#define emkdirs_info(path, mode) emkdirs_log((path), (mode), log_info_mkdir)
|
||||||
|
#define emkdirsn_info(path, len, mode) emkdirsn_log((path), (len), (mode), log_info_mkdir)
|
||||||
|
|
||||||
void srandomdev();
|
void srandomdev();
|
||||||
int urandombytes(unsigned char *buf, size_t len);
|
int urandombytes(unsigned char *buf, size_t len);
|
||||||
|
@ -497,14 +497,9 @@ overlay_interface_init(const char *name, struct socket_address *addr,
|
|||||||
return WHY("overlay_interface_init_socket() failed");
|
return WHY("overlay_interface_init_socket() failed");
|
||||||
}else{
|
}else{
|
||||||
char read_file[1024];
|
char read_file[1024];
|
||||||
|
|
||||||
interface->local_echo = interface->point_to_point?0:1;
|
interface->local_echo = interface->point_to_point?0:1;
|
||||||
|
if (!FORMF_SERVAL_TMP_PATH(read_file, "%s/%s", config.server.interface_path, ifconfig->file))
|
||||||
strbuf d = strbuf_local(read_file, sizeof read_file);
|
return -1;
|
||||||
strbuf_path_join(d, serval_instancepath(), config.server.interface_path, ifconfig->file, NULL);
|
|
||||||
if (strbuf_overrun(d))
|
|
||||||
return WHYF("interface file name overrun: %s", alloca_str_toprint(strbuf_str(d)));
|
|
||||||
|
|
||||||
if ((interface->alarm.poll.fd = open(read_file, O_APPEND|O_RDWR)) == -1) {
|
if ((interface->alarm.poll.fd = open(read_file, O_APPEND|O_RDWR)) == -1) {
|
||||||
if (errno == ENOENT && ifconfig->socket_type == SOCK_FILE) {
|
if (errno == ENOENT && ifconfig->socket_type == SOCK_FILE) {
|
||||||
cleanup_ret = 1;
|
cleanup_ret = 1;
|
||||||
@ -1071,10 +1066,7 @@ void overlay_interface_discover(struct sched_ent *alarm)
|
|||||||
{
|
{
|
||||||
// use a local dgram socket
|
// use a local dgram socket
|
||||||
// no abstract sockets for now
|
// no abstract sockets for now
|
||||||
strbuf d = strbuf_local(addr.local.sun_path, sizeof addr.local.sun_path);
|
if (!FORMF_SERVAL_RUN_PATH(addr.local.sun_path, "%s/%s", config.server.interface_path, ifconfig->file)) {
|
||||||
strbuf_path_join(d, serval_instancepath(), config.server.interface_path, ifconfig->file, NULL);
|
|
||||||
if (strbuf_overrun(d)){
|
|
||||||
WHYF("interface file name overrun: %s", alloca_str_toprint(strbuf_str(d)));
|
|
||||||
// TODO set ifconfig->exclude to prevent spam??
|
// TODO set ifconfig->exclude to prevent spam??
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -97,16 +97,17 @@ static int mdp_send2(const struct socket_address *client, const struct mdp_heade
|
|||||||
/* Delete all UNIX socket files in instance directory. */
|
/* Delete all UNIX socket files in instance directory. */
|
||||||
void overlay_mdp_clean_socket_files()
|
void overlay_mdp_clean_socket_files()
|
||||||
{
|
{
|
||||||
const char *instance_path = serval_instancepath();
|
char path[PATH_MAX];
|
||||||
|
if (FORMF_SERVAL_RUN_PATH(path, NULL)) {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
if ((dir = opendir(instance_path)) == NULL) {
|
if ((dir = opendir(path)) == NULL) {
|
||||||
WARNF_perror("opendir(%s)", alloca_str_toprint(instance_path));
|
WARNF_perror("opendir(%s)", alloca_str_toprint(path));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ((dp = readdir(dir)) != NULL) {
|
while ((dp = readdir(dir)) != NULL) {
|
||||||
char path[PATH_MAX];
|
path[0] = '\0';
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(path, dp->d_name))
|
if (!FORMF_SERVAL_RUN_PATH(path, "%s", dp->d_name))
|
||||||
continue;
|
continue;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path, &st)) {
|
if (lstat(path, &st)) {
|
||||||
@ -118,6 +119,7 @@ void overlay_mdp_clean_socket_files()
|
|||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void overlay_mdp_fill_legacy(
|
static void overlay_mdp_fill_legacy(
|
||||||
const struct internal_mdp_header *header,
|
const struct internal_mdp_header *header,
|
||||||
|
10
rhizome.h
10
rhizome.h
@ -395,16 +395,6 @@ int rhizome_configure();
|
|||||||
int rhizome_enabled();
|
int rhizome_enabled();
|
||||||
int rhizome_fetch_delay_ms();
|
int rhizome_fetch_delay_ms();
|
||||||
|
|
||||||
int rhizome_set_datastore_path(const char *path);
|
|
||||||
|
|
||||||
const char *rhizome_datastore_path();
|
|
||||||
int form_rhizome_datastore_path(struct __sourceloc, char * buf, size_t bufsiz, const char *fmt, ...);
|
|
||||||
|
|
||||||
/* Handy statement for forming the path of a rhizome store file in a char buffer whose declaration
|
|
||||||
* is in scope (so that sizeof(buf) will work). Evaluates to true if the pathname fitted into
|
|
||||||
* the provided buffer, false (0) otherwise (after logging an error). */
|
|
||||||
#define FORM_RHIZOME_DATASTORE_PATH(buf,fmt,...) (form_rhizome_datastore_path(__WHENCE__, (buf), sizeof(buf), (fmt), ##__VA_ARGS__))
|
|
||||||
|
|
||||||
#define RHIZOME_BLOB_SUBDIR "blob"
|
#define RHIZOME_BLOB_SUBDIR "blob"
|
||||||
|
|
||||||
extern sqlite3 *rhizome_db;
|
extern sqlite3 *rhizome_db;
|
||||||
|
@ -30,51 +30,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "keyring.h"
|
#include "keyring.h"
|
||||||
|
|
||||||
static char rhizome_thisdatastore_path[256];
|
|
||||||
|
|
||||||
static int rhizome_delete_manifest_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp);
|
static int rhizome_delete_manifest_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp);
|
||||||
static int rhizome_delete_file_retry(sqlite_retry_state *retry, const rhizome_filehash_t *hashp);
|
static int rhizome_delete_file_retry(sqlite_retry_state *retry, const rhizome_filehash_t *hashp);
|
||||||
static int rhizome_delete_payload_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp);
|
static int rhizome_delete_payload_retry(sqlite_retry_state *retry, const rhizome_bid_t *bidp);
|
||||||
|
|
||||||
const char *rhizome_datastore_path()
|
static int create_rhizome_store_dir()
|
||||||
{
|
|
||||||
if (!rhizome_thisdatastore_path[0])
|
|
||||||
rhizome_set_datastore_path(NULL);
|
|
||||||
return rhizome_thisdatastore_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rhizome_set_datastore_path(const char *path)
|
|
||||||
{
|
|
||||||
strbuf b = strbuf_local(rhizome_thisdatastore_path, sizeof rhizome_thisdatastore_path);
|
|
||||||
strbuf_path_join(b, serval_instancepath(), config.rhizome.datastore_path, path, NULL);
|
|
||||||
INFOF("Rhizome datastore path = %s", alloca_str_toprint(rhizome_thisdatastore_path));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int form_rhizome_datastore_path(struct __sourceloc __whence, char * buf, size_t bufsiz, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
strbuf b = strbuf_local(buf, bufsiz);
|
|
||||||
strbuf_puts(b, rhizome_datastore_path());
|
|
||||||
if (fmt) {
|
|
||||||
va_start(ap, fmt);
|
|
||||||
if (*strbuf_substr(b, -1) != '/')
|
|
||||||
strbuf_putc(b, '/');
|
|
||||||
strbuf_vsprintf(b, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
if (strbuf_overrun(b)) {
|
|
||||||
WHY("Path buffer overrun");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int create_rhizome_datastore_dir()
|
|
||||||
{
|
{
|
||||||
|
char rdpath[1024];
|
||||||
|
if (!formf_rhizome_store_path(rdpath, sizeof rdpath, "%s", config.rhizome.datastore_path))
|
||||||
|
return -1;
|
||||||
|
INFOF("Rhizome datastore path = %s", alloca_str_toprint(rdpath));
|
||||||
if (config.debug.rhizome)
|
if (config.debug.rhizome)
|
||||||
DEBUGF("mkdirs(%s, 0700)", rhizome_datastore_path());
|
DEBUGF("mkdirs(%s, 0700)", alloca_str_toprint(rdpath));
|
||||||
return emkdirs(rhizome_datastore_path(), 0700);
|
return emkdirs_info(rdpath, 0700);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3 *rhizome_db = NULL;
|
sqlite3 *rhizome_db = NULL;
|
||||||
@ -239,23 +207,23 @@ int rhizome_opendb()
|
|||||||
|
|
||||||
IN();
|
IN();
|
||||||
|
|
||||||
if (create_rhizome_datastore_dir() == -1)
|
if (create_rhizome_store_dir() == -1)
|
||||||
RETURN(-1);
|
RETURN(-1);
|
||||||
char dbpath[1024];
|
char dbpath[1024];
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(dbpath, RHIZOME_BLOB_SUBDIR))
|
if (!FORMF_RHIZOME_STORE_PATH(dbpath, RHIZOME_BLOB_SUBDIR))
|
||||||
RETURN(-1);
|
RETURN(-1);
|
||||||
if (emkdirs(dbpath, 0700) == -1)
|
if (emkdirs_info(dbpath, 0700) == -1)
|
||||||
RETURN(-1);
|
RETURN(-1);
|
||||||
if (!sqlite3_temp_directory) {
|
if (!sqlite3_temp_directory) {
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(dbpath, "sqlite3tmp"))
|
if (!FORMF_RHIZOME_STORE_PATH(dbpath, "sqlite3tmp"))
|
||||||
RETURN(-1);
|
RETURN(-1);
|
||||||
if (emkdirs(dbpath, 0700) == -1)
|
if (emkdirs_info(dbpath, 0700) == -1)
|
||||||
RETURN(-1);
|
RETURN(-1);
|
||||||
sqlite3_temp_directory = sqlite3_mprintf("%s", dbpath);
|
sqlite3_temp_directory = sqlite3_mprintf("%s", dbpath);
|
||||||
}
|
}
|
||||||
sqlite3_config(SQLITE_CONFIG_LOG,sqlite_log,NULL);
|
sqlite3_config(SQLITE_CONFIG_LOG,sqlite_log,NULL);
|
||||||
|
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(dbpath, "rhizome.db"))
|
if (!FORMF_RHIZOME_STORE_PATH(dbpath, "rhizome.db"))
|
||||||
RETURN(-1);
|
RETURN(-1);
|
||||||
if (sqlite3_open(dbpath,&rhizome_db)){
|
if (sqlite3_open(dbpath,&rhizome_db)){
|
||||||
RETURN(WHYF("SQLite could not open database %s: %s", dbpath, sqlite3_errmsg(rhizome_db)));
|
RETURN(WHYF("SQLite could not open database %s: %s", dbpath, sqlite3_errmsg(rhizome_db)));
|
||||||
@ -1191,7 +1159,7 @@ static int rhizome_delete_external(const char *id)
|
|||||||
{
|
{
|
||||||
// attempt to remove any external blob
|
// attempt to remove any external blob
|
||||||
char blob_path[1024];
|
char blob_path[1024];
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(blob_path, "%s/%s", RHIZOME_BLOB_SUBDIR, id))
|
if (!FORMF_RHIZOME_STORE_PATH(blob_path, "%s/%s", RHIZOME_BLOB_SUBDIR, id))
|
||||||
return -1;
|
return -1;
|
||||||
if (unlink(blob_path) == -1) {
|
if (unlink(blob_path) == -1) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
|
@ -204,9 +204,7 @@ static int rhizome_direct_addfile_end(struct http_request *hr)
|
|||||||
char manifestTemplate[1024];
|
char manifestTemplate[1024];
|
||||||
manifestTemplate[0] = '\0';
|
manifestTemplate[0] = '\0';
|
||||||
if (config.rhizome.api.addfile.manifest_template_file[0]) {
|
if (config.rhizome.api.addfile.manifest_template_file[0]) {
|
||||||
strbuf b = strbuf_local(manifestTemplate, sizeof manifestTemplate);
|
if (!FORMF_SERVAL_ETC_PATH(manifestTemplate, "%s", config.rhizome.api.addfile.manifest_template_file)) {
|
||||||
strbuf_path_join(b, serval_instancepath(), config.rhizome.api.addfile.manifest_template_file, NULL);
|
|
||||||
if (strbuf_overrun(b)) {
|
|
||||||
rhizome_direct_clear_temporary_files(r);
|
rhizome_direct_clear_temporary_files(r);
|
||||||
http_request_simple_response(&r->http, 500, "Internal Error: Template path too long");
|
http_request_simple_response(&r->http, 500, "Internal Error: Template path too long");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -105,7 +105,7 @@ enum rhizome_payload_status rhizome_open_write(struct rhizome_write *write, cons
|
|||||||
}
|
}
|
||||||
char blob_path[1024];
|
char blob_path[1024];
|
||||||
if (file_length == RHIZOME_SIZE_UNSET || file_length > config.rhizome.max_blob_size) {
|
if (file_length == RHIZOME_SIZE_UNSET || file_length > config.rhizome.max_blob_size) {
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(blob_path, "%s/%"PRIu64, RHIZOME_BLOB_SUBDIR, write->temp_id))
|
if (!FORMF_RHIZOME_STORE_PATH(blob_path, "%s/%"PRIu64, RHIZOME_BLOB_SUBDIR, write->temp_id))
|
||||||
return RHIZOME_PAYLOAD_STATUS_ERROR;
|
return RHIZOME_PAYLOAD_STATUS_ERROR;
|
||||||
if (config.debug.rhizome_store)
|
if (config.debug.rhizome_store)
|
||||||
DEBUGF("Attempting to put blob for id='%"PRIu64"' in %s", write->temp_id, blob_path);
|
DEBUGF("Attempting to put blob for id='%"PRIu64"' in %s", write->temp_id, blob_path);
|
||||||
@ -473,7 +473,7 @@ enum rhizome_payload_status rhizome_finish_write(struct rhizome_write *write)
|
|||||||
SHA512_End(&write->sha512_context, NULL);
|
SHA512_End(&write->sha512_context, NULL);
|
||||||
|
|
||||||
char blob_path[1024];
|
char blob_path[1024];
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(blob_path, "%s/%"PRIu64, RHIZOME_BLOB_SUBDIR, write->temp_id)) {
|
if (!FORMF_RHIZOME_STORE_PATH(blob_path, "%s/%"PRIu64, RHIZOME_BLOB_SUBDIR, write->temp_id)) {
|
||||||
WHYF("Failed to generate external blob path");
|
WHYF("Failed to generate external blob path");
|
||||||
status = RHIZOME_PAYLOAD_STATUS_ERROR;
|
status = RHIZOME_PAYLOAD_STATUS_ERROR;
|
||||||
goto failure;
|
goto failure;
|
||||||
@ -549,7 +549,7 @@ enum rhizome_payload_status rhizome_finish_write(struct rhizome_write *write)
|
|||||||
|
|
||||||
if (external) {
|
if (external) {
|
||||||
char dest_path[1024];
|
char dest_path[1024];
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(dest_path, "%s/%s", RHIZOME_BLOB_SUBDIR, alloca_tohex_rhizome_filehash_t(write->id)))
|
if (!FORMF_RHIZOME_STORE_PATH(dest_path, "%s/%s", RHIZOME_BLOB_SUBDIR, alloca_tohex_rhizome_filehash_t(write->id)))
|
||||||
goto dbfailure;
|
goto dbfailure;
|
||||||
if (rename(blob_path, dest_path) == -1) {
|
if (rename(blob_path, dest_path) == -1) {
|
||||||
WHYF_perror("rename(%s, %s)", blob_path, dest_path);
|
WHYF_perror("rename(%s, %s)", blob_path, dest_path);
|
||||||
@ -776,7 +776,7 @@ enum rhizome_payload_status rhizome_open_read(struct rhizome_read *read, const r
|
|||||||
} else {
|
} else {
|
||||||
// No row in FILEBLOBS, look for an external blob file.
|
// No row in FILEBLOBS, look for an external blob file.
|
||||||
char blob_path[1024];
|
char blob_path[1024];
|
||||||
if (!FORM_RHIZOME_DATASTORE_PATH(blob_path, "%s/%s", RHIZOME_BLOB_SUBDIR, alloca_tohex_rhizome_filehash_t(read->id)))
|
if (!FORMF_RHIZOME_STORE_PATH(blob_path, "%s/%s", RHIZOME_BLOB_SUBDIR, alloca_tohex_rhizome_filehash_t(read->id)))
|
||||||
return RHIZOME_PAYLOAD_STATUS_ERROR;
|
return RHIZOME_PAYLOAD_STATUS_ERROR;
|
||||||
read->blob_fd = open(blob_path, O_RDONLY);
|
read->blob_fd = open(blob_path, O_RDONLY);
|
||||||
if (read->blob_fd == -1) {
|
if (read->blob_fd == -1) {
|
||||||
|
3
serval.h
3
serval.h
@ -206,7 +206,6 @@ extern char *gatewayspec;
|
|||||||
|
|
||||||
int rhizome_enabled();
|
int rhizome_enabled();
|
||||||
int rhizome_http_server_running();
|
int rhizome_http_server_running();
|
||||||
const char *rhizome_datastore_path();
|
|
||||||
|
|
||||||
#define MAX_PEERS 1024
|
#define MAX_PEERS 1024
|
||||||
extern int peer_count;
|
extern int peer_count;
|
||||||
@ -279,6 +278,8 @@ struct slip_decode_state{
|
|||||||
|
|
||||||
|
|
||||||
int server_pid();
|
int server_pid();
|
||||||
|
const char *_server_pidfile_path(struct __sourceloc);
|
||||||
|
#define server_pidfile_path() (_server_pidfile_path(__WHENCE__))
|
||||||
void server_save_argv(int argc, const char *const *argv);
|
void server_save_argv(int argc, const char *const *argv);
|
||||||
int server(const struct cli_parsed *parsed);
|
int server(const struct cli_parsed *parsed);
|
||||||
int server_write_pid();
|
int server_write_pid();
|
||||||
|
87
server.c
87
server.c
@ -31,9 +31,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "strbuf_helpers.h"
|
#include "strbuf_helpers.h"
|
||||||
#include "overlay_interface.h"
|
#include "overlay_interface.h"
|
||||||
|
|
||||||
|
#define PROC_SUBDIR "proc"
|
||||||
#define PIDFILE_NAME "servald.pid"
|
#define PIDFILE_NAME "servald.pid"
|
||||||
#define STOPFILE_NAME "servald.stop"
|
#define STOPFILE_NAME "servald.stop"
|
||||||
|
|
||||||
|
static char pidfile_path[256];
|
||||||
|
|
||||||
#define EXEC_NARGS 20
|
#define EXEC_NARGS 20
|
||||||
char *exec_args[EXEC_NARGS + 1];
|
char *exec_args[EXEC_NARGS + 1];
|
||||||
unsigned exec_argc = 0;
|
unsigned exec_argc = 0;
|
||||||
@ -49,31 +52,45 @@ void crash_handler(int signal);
|
|||||||
*/
|
*/
|
||||||
int server_pid()
|
int server_pid()
|
||||||
{
|
{
|
||||||
const char *instancepath = serval_instancepath();
|
char dirname[1024];
|
||||||
struct stat st;
|
if (!FORMF_SERVAL_RUN_PATH(dirname, NULL))
|
||||||
if (stat(instancepath, &st) == -1)
|
|
||||||
return WHYF_perror("stat(%s)", alloca_str_toprint(instancepath));
|
|
||||||
if ((st.st_mode & S_IFMT) != S_IFDIR)
|
|
||||||
return WHYF("Instance path '%s' is not a directory", instancepath);
|
|
||||||
char filename[1024];
|
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(filename, PIDFILE_NAME))
|
|
||||||
return -1;
|
return -1;
|
||||||
FILE *f = fopen(filename, "r");
|
struct stat st;
|
||||||
|
if (stat(dirname, &st) == -1)
|
||||||
|
return WHYF_perror("stat(%s)", alloca_str_toprint(dirname));
|
||||||
|
if ((st.st_mode & S_IFMT) != S_IFDIR)
|
||||||
|
return WHYF("Not a directory: %s", dirname);
|
||||||
|
const char *ppath = server_pidfile_path();
|
||||||
|
if (ppath == NULL)
|
||||||
|
return -1;
|
||||||
|
const char *p = strrchr(ppath, '/');
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
|
FILE *f = fopen(ppath, "r");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
return WHYF_perror("fopen(%s,\"r\")", alloca_str_toprint(filename));
|
return WHYF_perror("fopen(%s,\"r\")", alloca_str_toprint(ppath));
|
||||||
} else {
|
} else {
|
||||||
char buf[20];
|
char buf[20];
|
||||||
int pid = (fgets(buf, sizeof buf, f) != NULL) ? atoi(buf) : -1;
|
int pid = (fgets(buf, sizeof buf, f) != NULL) ? atoi(buf) : -1;
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (pid > 0 && kill(pid, 0) != -1)
|
if (pid > 0 && kill(pid, 0) != -1)
|
||||||
return pid;
|
return pid;
|
||||||
INFOF("Unlinking stale pidfile %s", filename);
|
INFOF("Unlinking stale pidfile %s", ppath);
|
||||||
unlink(filename);
|
unlink(ppath);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *_server_pidfile_path(struct __sourceloc __whence)
|
||||||
|
{
|
||||||
|
if (!pidfile_path[0]) {
|
||||||
|
if (!FORMF_SERVAL_RUN_PATH(pidfile_path, PIDFILE_NAME))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pidfile_path;
|
||||||
|
}
|
||||||
|
|
||||||
void server_save_argv(int argc, const char *const *argv)
|
void server_save_argv(int argc, const char *const *argv)
|
||||||
{
|
{
|
||||||
/* Save our argv[] to use for relaunching */
|
/* Save our argv[] to use for relaunching */
|
||||||
@ -123,26 +140,22 @@ int server(const struct cli_parsed *parsed)
|
|||||||
int server_write_pid()
|
int server_write_pid()
|
||||||
{
|
{
|
||||||
/* Record PID to advertise that the server is now running */
|
/* Record PID to advertise that the server is now running */
|
||||||
char filename[1024];
|
const char *ppath = server_pidfile_path();
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(filename, PIDFILE_NAME))
|
if (ppath == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
FILE *f=fopen(filename,"w");
|
FILE *f = fopen(ppath, "w");
|
||||||
if (!f) {
|
if (!f)
|
||||||
WHY_perror("fopen");
|
return WHYF_perror("fopen(%s,\"w\")", alloca_str_toprint(ppath));
|
||||||
return WHYF("Could not write to PID file %s", filename);
|
|
||||||
}
|
|
||||||
server_getpid = getpid();
|
server_getpid = getpid();
|
||||||
fprintf(f,"%d\n", server_getpid);
|
fprintf(f,"%d\n", server_getpid);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_proc_path(const char *path, char *buff, size_t buff_len)
|
static int get_proc_path(const char *path, char *buf, size_t bufsiz)
|
||||||
{
|
{
|
||||||
strbuf sbname = strbuf_local(buff, buff_len);
|
if (!formf_serval_run_path(buf, bufsiz, PROC_SUBDIR "/%s", path))
|
||||||
strbuf_path_join(sbname, serval_instancepath(), "proc", path, NULL);
|
return -1;
|
||||||
if (strbuf_overrun(sbname))
|
|
||||||
return WHY("Buffer overrun building proc filename");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +169,7 @@ int server_write_proc_state(const char *path, const char *fmt, ...)
|
|||||||
char dir_buf[dirsiz];
|
char dir_buf[dirsiz];
|
||||||
strcpy(dir_buf, path_buf);
|
strcpy(dir_buf, path_buf);
|
||||||
const char *dir = dirname(dir_buf); // modifies dir_buf[]
|
const char *dir = dirname(dir_buf); // modifies dir_buf[]
|
||||||
if (mkdirs(dir, 0700) == -1)
|
if (mkdirs_info(dir, 0700) == -1)
|
||||||
return WHY_perror("mkdirs()");
|
return WHY_perror("mkdirs()");
|
||||||
|
|
||||||
FILE *f = fopen(path_buf, "w");
|
FILE *f = fopen(path_buf, "w");
|
||||||
@ -249,7 +262,7 @@ void server_shutdown_check(struct sched_ent *alarm)
|
|||||||
int server_create_stopfile()
|
int server_create_stopfile()
|
||||||
{
|
{
|
||||||
char stopfile[1024];
|
char stopfile[1024];
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(stopfile, STOPFILE_NAME))
|
if (!FORMF_SERVAL_RUN_PATH(stopfile, STOPFILE_NAME))
|
||||||
return -1;
|
return -1;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
if ((f = fopen(stopfile, "w")) == NULL) {
|
if ((f = fopen(stopfile, "w")) == NULL) {
|
||||||
@ -263,7 +276,7 @@ int server_create_stopfile()
|
|||||||
int server_remove_stopfile()
|
int server_remove_stopfile()
|
||||||
{
|
{
|
||||||
char stopfile[1024];
|
char stopfile[1024];
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(stopfile, STOPFILE_NAME))
|
if (!FORMF_SERVAL_RUN_PATH(stopfile, STOPFILE_NAME))
|
||||||
return -1;
|
return -1;
|
||||||
if (unlink(stopfile) == -1) {
|
if (unlink(stopfile) == -1) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
@ -277,7 +290,7 @@ int server_remove_stopfile()
|
|||||||
int server_check_stopfile()
|
int server_check_stopfile()
|
||||||
{
|
{
|
||||||
char stopfile[1024];
|
char stopfile[1024];
|
||||||
if (!FORM_SERVAL_INSTANCE_PATH(stopfile, STOPFILE_NAME))
|
if (!FORMF_SERVAL_RUN_PATH(stopfile, STOPFILE_NAME))
|
||||||
return -1;
|
return -1;
|
||||||
int r = access(stopfile, F_OK);
|
int r = access(stopfile, F_OK);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
@ -292,9 +305,7 @@ int server_check_stopfile()
|
|||||||
static void clean_proc()
|
static void clean_proc()
|
||||||
{
|
{
|
||||||
char path_buf[400];
|
char path_buf[400];
|
||||||
strbuf sbname = strbuf_local(path_buf, sizeof path_buf);
|
if (FORMF_SERVAL_RUN_PATH(path_buf, PROC_SUBDIR)) {
|
||||||
strbuf_path_join(sbname, serval_instancepath(), "proc", NULL);
|
|
||||||
|
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
if ((dir = opendir(path_buf)) == NULL) {
|
if ((dir = opendir(path_buf)) == NULL) {
|
||||||
@ -302,19 +313,17 @@ static void clean_proc()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ((dp = readdir(dir)) != NULL) {
|
while ((dp = readdir(dir)) != NULL) {
|
||||||
strbuf_reset(sbname);
|
if (FORMF_SERVAL_RUN_PATH(path_buf, PROC_SUBDIR "/%s", dp->d_name)) {
|
||||||
strbuf_path_join(sbname, serval_instancepath(), "proc", dp->d_name, NULL);
|
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path_buf, &st)) {
|
if (lstat(path_buf, &st) == -1)
|
||||||
WARNF_perror("stat(%s)", path_buf);
|
WARNF_perror("stat(%s)", path_buf);
|
||||||
continue;
|
else if (S_ISREG(st.st_mode))
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISREG(st.st_mode))
|
|
||||||
unlink(path_buf);
|
unlink(path_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void serverCleanUp()
|
void serverCleanUp()
|
||||||
{
|
{
|
||||||
|
9
socket.c
9
socket.c
@ -27,9 +27,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "strbuf_helpers.h"
|
#include "strbuf_helpers.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
/* Form the name of an AF_UNIX (local) socket in the instance directory as an absolute path.
|
/* Form the name of an AF_UNIX (local) socket in the /var/run/serval (or instance) directory as an
|
||||||
* Under Linux, this will create a socket name in the abstract namespace. This permits us to use
|
* absolute path. Under Linux, this will create a socket name in the abstract namespace. This
|
||||||
* local sockets on Android despite its lack of a shared writeable directory on a UFS partition.
|
* permits us to use local sockets on Android despite its lack of a shared writeable directory on a
|
||||||
|
* UFS partition.
|
||||||
*
|
*
|
||||||
* The absolute file name is resolved to its real path using realpath(3), to ensure that name
|
* The absolute file name is resolved to its real path using realpath(3), to ensure that name
|
||||||
* comparisons of addresses returned by recvmsg(2) can reliably be used on systems where the
|
* comparisons of addresses returned by recvmsg(2) can reliably be used on systems where the
|
||||||
@ -47,7 +48,7 @@ int _make_local_sockaddr(struct __sourceloc __whence, struct socket_address *add
|
|||||||
addr->local.sun_family = AF_UNIX;
|
addr->local.sun_family = AF_UNIX;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
int r = vformf_serval_instance_path(__WHENCE__, addr->local.sun_path, sizeof addr->local.sun_path, fmt, ap);
|
int r = vformf_serval_run_path(addr->local.sun_path, sizeof addr->local.sun_path, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (!r)
|
if (!r)
|
||||||
return WHY("socket name overflow");
|
return WHY("socket name overflow");
|
||||||
|
@ -172,7 +172,7 @@ doc_LogFileDirectoryRelative="Relative log file directory path"
|
|||||||
test_LogFileDirectoryRelative() {
|
test_LogFileDirectoryRelative() {
|
||||||
executeOk_servald config \
|
executeOk_servald config \
|
||||||
set debug.verbose true \
|
set debug.verbose true \
|
||||||
set log.file.directory_path "blah"
|
set log.file.directory_path "../blah"
|
||||||
executeOk_servald echo one
|
executeOk_servald echo one
|
||||||
assert --message="exactly one log file" [ $(ls -d "$SERVALINSTANCE_PATH/blah/"*.log | wc -l) -eq 1 ]
|
assert --message="exactly one log file" [ $(ls -d "$SERVALINSTANCE_PATH/blah/"*.log | wc -l) -eq 1 ]
|
||||||
assertGrep "$SERVALINSTANCE_PATH/blah/"*.log '^DEBUG:.*echo:argv\[1\]="one"$'
|
assertGrep "$SERVALINSTANCE_PATH/blah/"*.log '^DEBUG:.*echo:argv\[1\]="one"$'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user