mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Get rid of the separate "FATAL" log level, as it was applied so inconsistently as to be meaningless. This mostly involves s/pg_log_fatal/pg_log_error/g. Create a macro pg_fatal() to handle the common use-case of pg_log_error() immediately followed by exit(1). Various modules had already invented either this or equivalent macros; standardize on pg_fatal() and apply it where possible. Invent the ability to add "detail" and "hint" messages to a frontend message, much as we have long had in the backend. Except where rewording was needed to convert existing coding to detail/hint style, I have (mostly) resisted the temptation to change existing message wording. Patch by me. Design and patch reviewed at various stages by Robert Haas, Kyotaro Horiguchi, Peter Eisentraut and Daniel Gustafsson. Discussion: https://postgr.es/m/1363732.1636496441@sss.pgh.pa.us
105 lines
3.0 KiB
C
105 lines
3.0 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* pg_backup_utils.c
|
|
* Utility routines shared by pg_dump and pg_restore
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/bin/pg_dump/pg_backup_utils.c
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include "postgres_fe.h"
|
|
|
|
#include "parallel.h"
|
|
#include "pg_backup_utils.h"
|
|
|
|
/* Globals exported by this file */
|
|
const char *progname = NULL;
|
|
|
|
#define MAX_ON_EXIT_NICELY 20
|
|
|
|
static struct
|
|
{
|
|
on_exit_nicely_callback function;
|
|
void *arg;
|
|
} on_exit_nicely_list[MAX_ON_EXIT_NICELY];
|
|
|
|
static int on_exit_nicely_index;
|
|
|
|
/*
|
|
* Parse a --section=foo command line argument.
|
|
*
|
|
* Set or update the bitmask in *dumpSections according to arg.
|
|
* dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
|
|
* pg_restore so they can know if this has even been called.
|
|
*/
|
|
void
|
|
set_dump_section(const char *arg, int *dumpSections)
|
|
{
|
|
/* if this is the first call, clear all the bits */
|
|
if (*dumpSections == DUMP_UNSECTIONED)
|
|
*dumpSections = 0;
|
|
|
|
if (strcmp(arg, "pre-data") == 0)
|
|
*dumpSections |= DUMP_PRE_DATA;
|
|
else if (strcmp(arg, "data") == 0)
|
|
*dumpSections |= DUMP_DATA;
|
|
else if (strcmp(arg, "post-data") == 0)
|
|
*dumpSections |= DUMP_POST_DATA;
|
|
else
|
|
{
|
|
pg_log_error("unrecognized section name: \"%s\"", arg);
|
|
pg_log_error_hint("Try \"%s --help\" for more information.", progname);
|
|
exit_nicely(1);
|
|
}
|
|
}
|
|
|
|
|
|
/* Register a callback to be run when exit_nicely is invoked. */
|
|
void
|
|
on_exit_nicely(on_exit_nicely_callback function, void *arg)
|
|
{
|
|
if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY)
|
|
pg_fatal("out of on_exit_nicely slots");
|
|
on_exit_nicely_list[on_exit_nicely_index].function = function;
|
|
on_exit_nicely_list[on_exit_nicely_index].arg = arg;
|
|
on_exit_nicely_index++;
|
|
}
|
|
|
|
/*
|
|
* Run accumulated on_exit_nicely callbacks in reverse order and then exit
|
|
* without printing any message.
|
|
*
|
|
* If running in a parallel worker thread on Windows, we only exit the thread,
|
|
* not the whole process.
|
|
*
|
|
* Note that in parallel operation on Windows, the callback(s) will be run
|
|
* by each thread since the list state is necessarily shared by all threads;
|
|
* each callback must contain logic to ensure it does only what's appropriate
|
|
* for its thread. On Unix, callbacks are also run by each process, but only
|
|
* for callbacks established before we fork off the child processes. (It'd
|
|
* be cleaner to reset the list after fork(), and let each child establish
|
|
* its own callbacks; but then the behavior would be completely inconsistent
|
|
* between Windows and Unix. For now, just be sure to establish callbacks
|
|
* before forking to avoid inconsistency.)
|
|
*/
|
|
void
|
|
exit_nicely(int code)
|
|
{
|
|
int i;
|
|
|
|
for (i = on_exit_nicely_index - 1; i >= 0; i--)
|
|
on_exit_nicely_list[i].function(code,
|
|
on_exit_nicely_list[i].arg);
|
|
|
|
#ifdef WIN32
|
|
if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
|
|
_endthreadex(code);
|
|
#endif
|
|
|
|
exit(code);
|
|
}
|