2
* This is all for Solaris 2.6.
4
* Sun defined a new API in Solaris2.6 to be used when manipulating large
5
* (>2Gbyte) files. This API isn't present in 2.5.x, so we can't simply
6
* call it -- that would mean two binaries, one for 2.5.x and the other for
7
* 2.6. Not pretty. So, what we do here is determine the OS on which we're
8
* running at runtime, and adjust the underlying Berkeley DB calls to use
9
* the new API if it's there.
12
/* This must match the definition of stat64 in Solaris2.6 */
15
long st_pad1[3]; /* reserve for dev expansion */
24
timestruc_t mst_atime;
25
timestruc_t mst_mtime;
26
timestruc_t mst_ctime;
28
longlong_t st_blocks; /* large file support */
29
char st_fstype[_ST_FSTYPSZ];
30
long st_pad4[8]; /* expansion area */
33
#define MEGABYTE (1024 * 1024)
35
typedef int (*open_fn)(const char *path, int flags, ...);
36
typedef longlong_t (*lseek64_fn)(int fildes, longlong_t offset, int whence);
37
typedef longlong_t (*fstat64_fn)(int fildes, struct our_stat64 *s);
38
typedef void* (*mmap64_fn)(void* addr, size_t len, int prot, int flags,
39
int filedes, longlong_t off);
41
static fstat64_fn os_fstat64_fn = NULL;
42
static lseek64_fn os_lseek64_fn = NULL;
43
static mmap64_fn os_mmap64_fn = NULL;
44
static open_fn os_open64_fn = NULL;
46
static int dblayer_load_largefile_fns()
48
void *lib_handle = NULL;
49
void *function_found = NULL;
52
lib_handle = dlopen(NULL, RTLD_NOW);
53
if (NULL == lib_handle)
56
function_found = dlsym(lib_handle,"open64");
57
if (NULL == function_found)
59
os_open64_fn = (open_fn)function_found;
61
function_found = dlsym(lib_handle,"lseek64");
62
if (NULL == function_found)
64
os_lseek64_fn = (lseek64_fn)function_found;
66
function_found = dlsym(lib_handle,"fstat64");
67
if (NULL == function_found)
69
os_fstat64_fn = (fstat64_fn)function_found;
71
function_found = dlsym(lib_handle,"mmap64");
72
if (NULL == function_found)
74
os_mmap64_fn = (mmap64_fn)function_found;
79
/* Helper function for large seeks */
80
static int dblayer_seek_fn_solaris(int fd,
81
size_t pgsize, db_pgno_t pageno, u_long relative, int whence)
83
longlong_t offset = 0;
86
if (NULL == os_lseek64_fn) {
90
offset = (longlong_t)pgsize * pageno + relative;
92
ret = (*os_lseek64_fn)(fd,offset,whence);
94
return (ret == -1) ? errno : 0;
97
/* Helper function for large file mmap */
98
static int dblayer_map_solaris(fd, len, is_private, is_rdonly, addr)
99
int fd, is_private, is_rdonly;
106
flags = is_private ? MAP_PRIVATE : MAP_SHARED;
107
prot = PROT_READ | (is_rdonly ? 0 : PROT_WRITE);
109
if ((p = (*os_mmap64_fn)(NULL,
110
len, prot, flags, fd, (longlong_t)0)) == (void *)MAP_FAILED)
117
/* Helper function for large fstat */
118
static int dblayer_ioinfo_solaris(const char *path,
119
int fd, u_int32_t *mbytesp, u_int32_t *bytesp, u_int32_t *iosizep)
121
struct our_stat64 sb;
123
if (NULL == os_fstat64_fn) {
127
if ((*os_fstat64_fn)(fd, &sb) == -1)
130
/* Return the size of the file. */
132
*mbytesp = (u_int32_t) (sb.st_size / (longlong_t)MEGABYTE);
134
*bytesp = (u_int32_t) (sb.st_size % (longlong_t)MEGABYTE);
137
* Return the underlying filesystem blocksize, if available. Default
138
* to 8K on the grounds that most OS's use less than 8K as their VM
142
*iosizep = sb.st_blksize;
148
* A similar mess to Solaris: a new API added in IRIX6.2 to support large
149
* files. We always build on 6.2 or later, so no need to do the same song
150
* and dance as on Solaris -- we always have the header files for the
154
/* Helper function for large seeks */
155
static int dblayer_seek_fn_irix(int fd,
156
size_t pgsize, db_pgno_t pageno, u_long relative, int whence)
161
offset = (off64_t)pgsize * pageno + relative;
163
ret = lseek64(fd,offset,whence);
165
return (ret == -1) ? errno : 0;
168
/* Helper function for large fstat */
169
static int dblayer_ioinfo_irix(const char *path,
170
int fd, u_int32_t *mbytesp, u_int32_t *bytesp, u_int32_t *iosizep)
174
if (fstat64(fd, &sb) == -1) {
178
/* Return the size of the file. */
180
*mbytesp = (u_int32_t) (sb.st_size / (off64_t)MEGABYTE);
182
*bytesp = (u_int32_t) (sb.st_size % (off64_t)MEGABYTE);
185
*iosizep = sb.st_blksize;
190
static int dblayer_override_libdb_functions(dblayer_private *priv)
192
#if defined(OS_solaris)
195
ret = dblayer_load_largefile_fns();
197
Debug("Not Solaris2.6: no large file support enabled\n");
199
/* Means we did get the XXX64 functions, so let's use them */
200
db_jump_set((void*)os_open64_fn, DB_FUNC_OPEN);
201
db_jump_set((void*)dblayer_seek_fn_solaris, DB_FUNC_SEEK);
202
db_jump_set((void*)dblayer_ioinfo_solaris, DB_FUNC_IOINFO);
203
db_jump_set((void*)dblayer_map_solaris, DB_FUNC_MAP);
204
Debug("Solaris2.6: selected 64-bit file handling.\n");
208
db_jump_set((void*)dblayer_seek_fn_irix, DB_FUNC_SEEK);
209
db_jump_set((void*)dblayer_ioinfo_irix, DB_FUNC_IOINFO);
211
#endif /* OS_solaris */