PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pg_backup_utils.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * pg_backup_utils.c
4 * Utility routines shared by pg_dump and pg_restore
5 *
6 *
7 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 * src/bin/pg_dump/pg_backup_utils.c
11 *
12 *-------------------------------------------------------------------------
13 */
14#include "postgres_fe.h"
15
16#ifdef WIN32
17#include "parallel.h"
18#endif
19#include "pg_backup_utils.h"
20
21/* Globals exported by this file */
22const char *progname = NULL;
23
24#ifdef WIN32
25
26/*
27 * Flag telling worker threads to stay quiet about query failures because
28 * we're cancelling their queries as part of tearing down the process. See
29 * the comment in pg_backup_utils.h.
30 *
31 * The cancel thread writes it while worker threads read it, so it's marked
32 * volatile to keep the compiler from caching the value. A plain volatile
33 * bool isn't a memory barrier, but it's good enough here. A lot of things
34 * happen between set_cancel_in_progress() in the cancel thread and the other
35 * threads calling is_cancel_in_progress(), including network operations,
36 * which implicitly act as memory barriers. Furthermore, the flag is only
37 * ever flipped one way (false to true) and a worker briefly observing the
38 * stale false just means it would print one error before the process dies.
39 * The only goal of this flag is to make sure workers don't log "query
40 * cancelled" errors during the shutdown process.
41 *
42 * XXX: This should be swapped out for a proper atomic when we have those in
43 * the frontend code, so that we wouldn't need to rationalizee all of the
44 * above.
45 */
46static volatile bool cancelInProgress = false;
47
48void
50{
51 cancelInProgress = true;
52}
53
54bool
56{
57 return cancelInProgress;
58}
59
60#endif /* WIN32 */
61
62#define MAX_ON_EXIT_NICELY 20
63
64static struct
65{
67 void *arg;
69
71
72/*
73 * Parse a --section=foo command line argument.
74 *
75 * Set or update the bitmask in *dumpSections according to arg.
76 * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
77 * pg_restore so they can know if this has even been called.
78 */
79void
80set_dump_section(const char *arg, int *dumpSections)
81{
82 /* if this is the first call, clear all the bits */
83 if (*dumpSections == DUMP_UNSECTIONED)
84 *dumpSections = 0;
85
86 if (strcmp(arg, "pre-data") == 0)
87 *dumpSections |= DUMP_PRE_DATA;
88 else if (strcmp(arg, "data") == 0)
89 *dumpSections |= DUMP_DATA;
90 else if (strcmp(arg, "post-data") == 0)
91 *dumpSections |= DUMP_POST_DATA;
92 else
93 {
94 pg_log_error("unrecognized section name: \"%s\"", arg);
95 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
96 exit_nicely(1);
97 }
98}
99
100
101/* Register a callback to be run when exit_nicely is invoked. */
102void
111
112/*
113 * Run accumulated on_exit_nicely callbacks in reverse order and then exit
114 * without printing any message.
115 *
116 * If running in a parallel worker thread on Windows, we only exit the thread,
117 * not the whole process.
118 *
119 * Note that in parallel operation on Windows, the callback(s) will be run
120 * by each thread since the list state is necessarily shared by all threads;
121 * each callback must contain logic to ensure it does only what's appropriate
122 * for its thread. On Unix, callbacks are also run by each process, but only
123 * for callbacks established before we fork off the child processes. (It'd
124 * be cleaner to reset the list after fork(), and let each child establish
125 * its own callbacks; but then the behavior would be completely inconsistent
126 * between Windows and Unix. For now, just be sure to establish callbacks
127 * before forking to avoid inconsistency.)
128 */
129void
130exit_nicely(int code)
131{
132 int i;
133
134 for (i = on_exit_nicely_index - 1; i >= 0; i--)
137
138#ifdef WIN32
140 _endthreadex(code);
141#endif
142
143 exit(code);
144}
int i
Definition isn.c:77
#define pg_log_error(...)
Definition logging.h:108
#define pg_log_error_hint(...)
Definition logging.h:114
static int on_exit_nicely_index
void exit_nicely(int code)
on_exit_nicely_callback function
#define MAX_ON_EXIT_NICELY
void set_dump_section(const char *arg, int *dumpSections)
void * arg
void on_exit_nicely(on_exit_nicely_callback function, void *arg)
static struct @39 on_exit_nicely_list[MAX_ON_EXIT_NICELY]
const char * progname
#define DUMP_PRE_DATA
void(* on_exit_nicely_callback)(int code, void *arg)
#define DUMP_DATA
#define DUMP_UNSECTIONED
#define is_cancel_in_progress()
#define pg_fatal(...)
#define DUMP_POST_DATA
static int fb(int x)