in foreground and to show incoming and outgoing events. It must never be
used in an init script.
+ -dA[file] : dump an archive of all dependencies detected at boot time in the
+ designated file in tar format, immediately after the configuration is done
+ loading. This is equivalent to "set-dumpable libs", but instead of keeping
+ the libs in memory, it dumps them into a file. This may be used after a
+ core dump, in order to provide all necessary libraries to developers to
+ permit them to exploit the core. This may not be available on all operating
+ systems. It is highly recommended to use this with the regular
+ configuration files, and optionally with "-c" when used manually, to make
+ haproxy immediately exit after the dump, without starting. Example:
+
+ $ haproxy -dA/tmp/libs.tar -c -f /etc/haproxy/haproxy.cfg
+
-dC[key] : dump the configuration file. It is performed after the lines are
tokenized, so comments are stripped and indenting is forced. If a non-zero
key is specified, lines are truncated before sensitive/confidential fields,
/* storage for collected libs */
extern void *lib_storage;
extern size_t lib_size;
+extern char *lib_output_file;
struct proxy;
struct server;
int dump_libs(struct buffer *output, int with_addr);
void collect_libs(void);
void free_collected_libs(void);
+int copy_libs_to_file(void);
/* Note that this may result in opening libgcc() on first call, so it may need
* to have been called once before chrooting.
/* mapped storage for collected libs */
void *lib_storage = NULL;
size_t lib_size = 0;
+char *lib_output_file = NULL;
int check_kw_experimental(struct cfg_keyword *kw, const char *file, int linenum,
char **errmsg)
#if defined(HA_HAVE_DUMP_LIBS)
" -dL dumps loaded object files after config checks\n"
#endif
+#if defined(HA_HAVE_DUMP_LIBS) && defined(HA_HAVE_DL_ITERATE_PHDR)
+ " -dA[file] collects libs into a tar file at <file>\n"
+#endif
#if defined(USE_CPU_AFFINITY)
" -dc dumps the list of selected and evicted CPUs\n"
#endif
#if defined(HA_HAVE_DUMP_LIBS)
else if (*flag == 'd' && flag[1] == 'L')
arg_mode |= MODE_DUMP_LIBS;
+# if defined(HA_HAVE_DL_ITERATE_PHDR)
+ else if (*flag == 'd' && flag[1] == 'A') {
+ lib_output_file = flag + 2;
+ if (!*lib_output_file) {
+ ha_alert("-dA: missing output file name\n");
+ exit(1);
+ }
+ arg_mode |= MODE_DUMP_LIBS; // stop on libs dump
+ }
+# endif /* HA_HAVE_DL_ITERATE_PHDR */
#endif
else if (*flag == 'd' && flag[1] == 'K') {
arg_mode |= MODE_DUMP_KWD;
#if defined(HA_HAVE_DUMP_LIBS)
if (global.mode & MODE_DUMP_LIBS && !master) {
+# if defined(HA_HAVE_DL_ITERATE_PHDR)
+ if (lib_output_file) {
+ /* we'll dump everything to lib_output_file */
+ if (copy_libs_to_file() < 0)
+ deinit_and_exit(1);
+ /* release memory if no longer needed */
+ if ((global.tune.options & (GTUNE_SET_DUMPABLE | GTUNE_COLLECT_LIBS)) !=
+ (GTUNE_SET_DUMPABLE | GTUNE_COLLECT_LIBS))
+ free_collected_libs();
+ }
+# endif
qfprintf(stdout, "List of loaded object files:\n");
chunk_reset(&trash);
if (dump_libs(&trash, ((arg_mode & (MODE_QUIET|MODE_VERBOSE)) == MODE_VERBOSE)))
void *page;
int i;
+ /* already done */
+ if (lib_storage)
+ return;
+
/* prepend a directory named after the starting pid */
snprintf(dir_name, sizeof(dir_name), "core-%u", getpid());
ctx.prefix = dir_name;
lib_size = 0;
}
+/* Prepare the archive in RAM and copy it to a target file. Returns <0 upon error. */
+int copy_libs_to_file(void)
+{
+ ssize_t len;
+ int ret = -1;
+ int fd = -1;
+
+ fd = open(lib_output_file, O_CREAT | O_WRONLY, S_IRWXU);
+ if (fd < 0) {
+ ha_alert("Cannot create output file to dump dependencies: %s.\n", strerror(errno));
+ goto fail;
+ }
+
+ collect_libs();
+ if (!lib_storage || !lib_size) {
+ ha_alert("Failed to collect dependencies.\n");
+ goto fail;
+ }
+
+ len = write(fd, lib_storage, lib_size);
+ if (len != lib_size) {
+ ha_alert("Failed to write dependencies to output file: %s.\n", strerror(errno));
+ goto fail;
+ }
+
+ /* OK done */
+ ret = 0;
+ fail:
+ if (fd >= 0)
+ close(fd);
+ return ret;
+}
+
# else // no DL_ITERATE_PHDR
# error "No dump_libs() function for this platform"
# endif
{
}
+/* unsupported platform: do not copy anything */
+int copy_libs_to_file(void)
+{
+ return -1;
+}
+
#endif // HA_HAVE_DUMP_LIBS
/*