PostgreSQL Source Code git master
pg_tablespace.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * pg_tablespace.c
4 * routines to support manipulation of the pg_tablespace relation
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/catalog/pg_tablespace.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include <unistd.h>
18#include <sys/stat.h>
19
21#include "commands/tablespace.h"
22#include "miscadmin.h"
23
24
25/*
26 * get_tablespace_location
27 * Get a tablespace's location as a C-string, by its OID
28 */
29char *
31{
32 char sourcepath[MAXPGPATH];
33 char targetpath[MAXPGPATH];
34 int rllen;
35 struct stat st;
36
37 /*
38 * It's useful to apply this to pg_class.reltablespace, wherein zero means
39 * "the database's default tablespace". So, rather than throwing an error
40 * for zero, we choose to assume that's what is meant.
41 */
42 if (tablespaceOid == InvalidOid)
43 tablespaceOid = MyDatabaseTableSpace;
44
45 /*
46 * Return empty string for the cluster's default tablespaces
47 */
48 if (tablespaceOid == DEFAULTTABLESPACE_OID ||
49 tablespaceOid == GLOBALTABLESPACE_OID)
50 return pstrdup("");
51
52 /*
53 * Find the location of the tablespace by reading the symbolic link that
54 * is in pg_tblspc/<oid>.
55 */
56 snprintf(sourcepath, sizeof(sourcepath), "%s/%u", PG_TBLSPC_DIR, tablespaceOid);
57
58 /*
59 * Before reading the link, check if the source path is a link or a
60 * junction point. Note that a directory is possible for a tablespace
61 * created with allow_in_place_tablespaces enabled. If a directory is
62 * found, a relative path to the data directory is returned.
63 */
64 if (lstat(sourcepath, &st) < 0)
67 errmsg("could not stat file \"%s\": %m",
68 sourcepath));
69
70 if (!S_ISLNK(st.st_mode))
71 return pstrdup(sourcepath);
72
73 /*
74 * In presence of a link or a junction point, return the path pointed to.
75 */
76 rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
77 if (rllen < 0)
80 errmsg("could not read symbolic link \"%s\": %m",
81 sourcepath));
82 if (rllen >= sizeof(targetpath))
84 errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
85 errmsg("symbolic link \"%s\" target is too long",
86 sourcepath));
87 targetpath[rllen] = '\0';
88
89 return pstrdup(targetpath);
90}
int errcode_for_file_access(void)
Definition: elog.c:886
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
Oid MyDatabaseTableSpace
Definition: globals.c:96
char * pstrdup(const char *in)
Definition: mcxt.c:1759
#define MAXPGPATH
char * get_tablespace_location(Oid tablespaceOid)
Definition: pg_tablespace.c:30
#define snprintf
Definition: port.h:239
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
#define PG_TBLSPC_DIR
Definition: relpath.h:41
unsigned short st_mode
Definition: win32_port.h:258
#define lstat(path, sb)
Definition: win32_port.h:275
#define S_ISLNK(m)
Definition: win32_port.h:334
#define readlink(path, buf, size)
Definition: win32_port.h:226