PostgreSQL Source Code  git master
local_source.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * local_source.c
4  * Functions for using a local data directory as the source.
5  *
6  * Portions Copyright (c) 2013-2021, PostgreSQL Global Development Group
7  *
8  *-------------------------------------------------------------------------
9  */
10 #include "postgres_fe.h"
11 
12 #include <fcntl.h>
13 #include <unistd.h>
14 
15 #include "datapagemap.h"
16 #include "file_ops.h"
17 #include "filemap.h"
18 #include "pg_rewind.h"
19 #include "rewind_source.h"
20 
21 typedef struct
22 {
23  rewind_source common; /* common interface functions */
24 
25  const char *datadir; /* path to the source data directory */
26 } local_source;
27 
30 static char *local_fetch_file(rewind_source *source, const char *path,
31  size_t *filesize);
32 static void local_fetch_file_range(rewind_source *source, const char *path,
33  off_t off, size_t len);
35 static void local_destroy(rewind_source *source);
36 
39 {
40  local_source *src;
41 
42  src = pg_malloc0(sizeof(local_source));
43 
50 
51  src->datadir = datadir;
52 
53  return &src->common;
54 }
55 
56 static void
58 {
60 }
61 
62 static char *
63 local_fetch_file(rewind_source *source, const char *path, size_t *filesize)
64 {
65  return slurpFile(((local_source *) source)->datadir, path, filesize);
66 }
67 
68 /*
69  * Copy a file from source to target, starting at 'off', for 'len' bytes.
70  */
71 static void
72 local_fetch_file_range(rewind_source *source, const char *path, off_t off,
73  size_t len)
74 {
75  const char *datadir = ((local_source *) source)->datadir;
77  char srcpath[MAXPGPATH];
78  int srcfd;
79  off_t begin = off;
80  off_t end = off + len;
81 
82  snprintf(srcpath, sizeof(srcpath), "%s/%s", datadir, path);
83 
84  srcfd = open(srcpath, O_RDONLY | PG_BINARY, 0);
85  if (srcfd < 0)
86  pg_fatal("could not open source file \"%s\": %m",
87  srcpath);
88 
89  if (lseek(srcfd, begin, SEEK_SET) == -1)
90  pg_fatal("could not seek in source file: %m");
91 
92  open_target_file(path, false);
93 
94  while (end - begin > 0)
95  {
96  ssize_t readlen;
97  size_t len;
98 
99  if (end - begin > sizeof(buf))
100  len = sizeof(buf);
101  else
102  len = end - begin;
103 
104  readlen = read(srcfd, buf.data, len);
105 
106  if (readlen < 0)
107  pg_fatal("could not read file \"%s\": %m", srcpath);
108  else if (readlen == 0)
109  pg_fatal("unexpected EOF while reading file \"%s\"", srcpath);
110 
111  write_target_range(buf.data, begin, readlen);
112  begin += readlen;
113  }
114 
115  if (close(srcfd) != 0)
116  pg_fatal("could not close file \"%s\": %m", srcpath);
117 }
118 
119 static void
121 {
122  /*
123  * Nothing to do, local_fetch_file_range() copies the ranges immediately.
124  */
125 }
126 
127 static void
129 {
130  pfree(source);
131 }
static void local_traverse_files(rewind_source *source, process_file_callback_t callback)
Definition: local_source.c:57
void open_target_file(const char *path, bool trunc)
Definition: file_ops.c:47
static void local_destroy(rewind_source *source)
Definition: local_source.c:128
void(* finish_fetch)(struct rewind_source *)
Definition: rewind_source.h:53
void write_target_range(char *buf, off_t begin, size_t size)
Definition: file_ops.c:88
rewind_source * init_local_source(const char *datadir)
Definition: local_source.c:38
void(* process_file_callback_t)(const char *path, file_type_t type, size_t size, const char *link_target)
Definition: file_ops.h:26
rewind_source common
Definition: local_source.c:23
void traverse_datadir(const char *datadir, process_file_callback_t callback)
Definition: file_ops.c:362
void(* traverse_files)(struct rewind_source *, process_file_callback_t callback)
Definition: rewind_source.h:29
char *(* fetch_file)(struct rewind_source *, const char *path, size_t *filesize)
Definition: rewind_source.h:37
static char * local_fetch_file(rewind_source *source, const char *path, size_t *filesize)
Definition: local_source.c:63
#define pg_fatal(...)
Definition: pg_rewind.h:37
static void local_fetch_file_range(rewind_source *source, const char *path, off_t off, size_t len)
Definition: local_source.c:72
#define PG_BINARY
Definition: c.h:1271
char data[BLCKSZ]
Definition: c.h:1141
void pfree(void *pointer)
Definition: mcxt.c:1169
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
XLogRecPtr(* get_current_wal_insert_lsn)(struct rewind_source *)
Definition: rewind_source.h:58
#define MAXPGPATH
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
static char * buf
Definition: pg_test_fsync.c:68
char * datadir
void(* queue_fetch_range)(struct rewind_source *, const char *path, off_t offset, size_t len)
Definition: rewind_source.h:47
static void local_finish_fetch(rewind_source *source)
Definition: local_source.c:120
void(* destroy)(struct rewind_source *)
Definition: rewind_source.h:63
const char * datadir
Definition: local_source.c:25
static rewind_source * source
Definition: pg_rewind.c:79
void process_source_file(const char *path, file_type_t type, size_t size, const char *link_target)
Definition: filemap.c:219
#define close(a)
Definition: win32.h:12
#define snprintf
Definition: port.h:216
#define read(a, b, c)
Definition: win32.h:13
char * slurpFile(const char *datadir, const char *path, size_t *filesize)
Definition: file_ops.c:314