Skip to content

Commit 8d1588b

Browse files
committed
Automated build and datadir init
1 parent 5fce1aa commit 8d1588b

File tree

10 files changed

+193
-122
lines changed

10 files changed

+193
-122
lines changed

README_WASM.md

Lines changed: 23 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,94 +3,35 @@
33

44
## Compilation
55

6-
export EMMAKEN_CFLAGS="-Wl,--allow-undefined"
7-
emconfigure ./configure CFLAGS='-Oz' --without-readline --without-zlib --disable-thread-safety --disable-spinlocks
8-
export EMMAKEN_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0 -s TOTAL_MEMORY=65536000 -s EMULATE_FUNCTION_POINTER_CASTS=1"
9-
emmake make -j4
6+
Prerequisites:
7+
* emscripten/3.1.0
8+
* nodejs
109

11-
## Setup the data directory
1210

13-
emcc src/bin/initdb/initdb.o -L src/port/ -L src/common -L src/fe_utils -L src/interfaces/libpq -lpq -lpgfeutils -lpgcommon -lpgport -o initdb.js
11+
To build postgres.wasm and datadir bundle:
12+
```
13+
make -f wasm/Makefile debug-build
14+
make -f wasm/Makefile debug-datadir
15+
```
1416

15-
# create empty datadir
16-
rm -rf datadir
17-
mkdir datadir
18-
chmod 0750 datadir
19-
touch datadir/postgresql.conf
20-
touch datadir/postgresql.auto.conf
21-
touch datadir/pg_ident.conf
22-
touch datadir/pg_hba.conf
23-
echo '15devel' > datadir/PG_VERSION
24-
mkdir -p datadir/global
25-
mkdir -p datadir/pg_wal/archive_status
26-
mkdir -p datadir/pg_commit_ts
27-
mkdir -p datadir/pg_dynshmem
28-
mkdir -p datadir/pg_notify
29-
mkdir -p datadir/pg_serial
30-
mkdir -p datadir/pg_snapshots
31-
mkdir -p datadir/pg_subtrans
32-
mkdir -p datadir/pg_twophase
33-
mkdir -p datadir/pg_multixact
34-
mkdir -p datadir/pg_multixact/members
35-
mkdir -p datadir/pg_multixact/offsets
36-
mkdir -p datadir/base
37-
mkdir -p datadir/base/1
38-
echo '15devel' > datadir/base/1/PG_VERSION
39-
mkdir -p datadir/pg_replslot
40-
mkdir -p datadir/pg_tblspc
41-
mkdir -p datadir/pg_stat
42-
mkdir -p datadir/pg_stat_tmp
43-
mkdir -p datadir/pg_xact
44-
mkdir -p datadir/pg_logical
45-
mkdir -p datadir/pg_logical/snapshots
46-
mkdir -p datadir/pg_logical/mapping
17+
You can check it in the browser. Wasm file would not be loaded as 'file://' links, so you need to have an http server on localhost, e.g.:
18+
```
19+
cd wasm
20+
python3 -m http.server
21+
```
4722

23+
Now navigate to `http://localhost:8000/`
4824

49-
# add that keys to postgres.o compilation:
50-
--preload-file /Users/stas/datadir --preload-file /usr/local/pgsql/share/
5125

52-
cd src/backend
26+
## TODO
5327

54-
node postgres --boot -x1 -X 16777216 -d 5 -c dynamic_shared_memory_type=mmap -D /data
28+
- [x] separate fs packaging from compiling
29+
- [x] read from events
30+
- [x] somehow report back results
31+
- [x] identify and fix FUNCTION_POINTER_CASTS
32+
- [x] identify and fix corrupt memory error
5533

56-
57-
58-
node postgres --single -F -O -j -c search_path=pg_catalog -c dynamic_shared_memory_type=mmap -d 5 -D /data template1
59-
60-
61-
62-
63-
------
64-
65-
66-
var Module = {
67-
preRun: [function() {
68-
function stdin() {
69-
// Return ASCII code of character, or null if no input
70-
}
71-
72-
function stdout(asciiCode) {
73-
// Do something with the asciiCode
74-
}
75-
76-
function stderr(asciiCode) {
77-
// Do something with the asciiCode
78-
}
79-
80-
FS.init(stdin, stdout, stderr);
81-
}]
82-
};
83-
84-
85-
# todo
86-
87-
+ separate fs packaging from compiling
88-
+ read from events
89-
+ somehow report back
90-
+ identify and fix FUNCTION_POINTER_CASTS
91-
+ fix report back corrupt memory
92-
93-
* automate datadir process
34+
- [x] automate datadir process
9435
* split to commits, ensure usual postgres is properly built
9536
* provide js wrapper
9637
* nice UI
@@ -103,4 +44,6 @@ var Module = {
10344

10445
* regress test? =)
10546

47+
* "runnable" sql embeds
48+
10649
* work with the remote data

src/backend/Makefile

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,7 @@ ifneq ($(PORTNAME), win32)
6363
ifneq ($(PORTNAME), aix)
6464

6565
postgres: $(OBJS)
66-
$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -s FORCE_FILESYSTEM=1 -s ASYNCIFY=1 -o $@.html
67-
68-
# --preload-file /Users/stas/datadir --preload-file /usr/local/pgsql/share -o $@.html
69-
# --embed-file /Users/stas/datadir --embed-file /usr/local/pgsql/share -lnodefs.js -ltty.js
70-
# --embed-file /Users/stas/datadir/
66+
$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -s FORCE_FILESYSTEM=1 -s ASYNCIFY=1 -lnodefs.js -o $@
7167
endif
7268
endif
7369
endif

src/backend/main/main.c

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -65,37 +65,6 @@ main(int argc, char *argv[])
6565

6666
printf("Hey-hey!\n");
6767

68-
#ifdef EMSCRIPTEN
69-
EM_ASM(
70-
// FS.mkdir('/data');
71-
72-
// FS.mkdir('/usr');
73-
// FS.mkdir('/usr/local');
74-
// FS.mkdir('/usr/local/pgsql');
75-
76-
// FS.mkdir('/Users');
77-
// FS.mkdir('/Users/stas');
78-
79-
FS.mkdir('/Users/stas/datadir/pg_notify');
80-
81-
// FS.mkdir('/Users/stas/datadir/pg_snapshots');
82-
FS.mkdir('/Users/stas/datadir/pg_commit_ts');
83-
// FS.mkdir('/Users/stas/datadir/pg_stat');
84-
85-
// FS.mkdir('/Users/stas/datadir/pg_serial');
86-
FS.mkdir('/Users/stas/datadir/pg_replslot');
87-
// FS.mkdir('/Users/stas/datadir/pg_dynshmem');
88-
FS.mkdir('/Users/stas/datadir/pg_twophase');
89-
FS.mkdir('/Users/stas/datadir/pg_tblspc');
90-
// FS.mkdir('/Users/stas/datadir/pg_dynshmem');
91-
92-
// FS.mkdir('/usr/local/pgsql/share');
93-
94-
// FS.mount(MEMFS, { root: '/Users/stas/datadir' }, '/data');
95-
// FS.mount(MEMFS, { root: '/usr/local/pgsql/share' }, '/usr/local/pgsql/share');
96-
);
97-
#endif
98-
9968
/*
10069
* If supported on the current platform, set up a handler to be called if
10170
* the backend/postmaster crashes with a fatal signal or exception.

src/backend/utils/cache/relcache.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6485,6 +6485,16 @@ RelationCacheInitFileRemove(void)
64856485
struct dirent *de;
64866486
char path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY)];
64876487

6488+
#ifdef EMSCRIPTEN
6489+
/*
6490+
* emscripten 3.0.1 breaks here on traversal up in FS.realPath() on the
6491+
* mount point (it has path field set, but not the name field).
6492+
*
6493+
* TODO: make a standalone repro and report.
6494+
*/
6495+
return;
6496+
#endif
6497+
64886498
snprintf(path, sizeof(path), "global/%s",
64896499
RELCACHE_INIT_FILENAME);
64906500
unlink_initfile(path, LOG);

wasm/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
debug
2+
release

wasm/Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.PHONY: debug-build debug-datadir
2+
3+
debug-build:
4+
EMCC_CFLAGS="-Wl,--allow-undefined" \
5+
emconfigure ./configure CFLAGS='-Oz' \
6+
--without-readline \
7+
--without-zlib \
8+
--disable-thread-safety \
9+
--disable-spinlocks \
10+
--with-system-tzdata=/usr/share/zoneinfo \
11+
--enable-debug
12+
EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0 -s WARN_ON_UNDEFINED_SYMBOLS=0 -s TOTAL_MEMORY=65536000 -s EMULATE_FUNCTION_POINTER_CASTS=1 -s ASSERTIONS=1" \
13+
emmake make MAKELEVEL=0 -j4
14+
mkdir -p wasm/debug
15+
cp src/backend/postgres wasm/debug/postgres.js
16+
cp src/backend/postgres.wasm wasm/debug/postgres.wasm
17+
18+
debug-datadir:
19+
mkdir -p tmp_install
20+
DESTDIR="$(abspath tmp_install)" \
21+
EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0 -s WARN_ON_UNDEFINED_SYMBOLS=0 -s TOTAL_MEMORY=65536000 -s EMULATE_FUNCTION_POINTER_CASTS=1 -s ASSERTIONS=1" \
22+
emmake make MAKELEVEL=0 -C src/backend/ install
23+
node wasm/initdb.js
24+
cd wasm/debug && \
25+
`em-config EMSCRIPTEN_ROOT`/tools/file_packager pgdata.data --preload ./temp_pgdata@/pgdata --js-output=pgdata.js && \
26+
`em-config EMSCRIPTEN_ROOT`/tools/file_packager share.data --preload ../../tmp_install/usr/local/pgsql/share@/usr/local/pgsql/share --js-output=share.js

build/index.html renamed to wasm/index.html

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html lang=en>
33
<head>
44
<meta charset=utf-8>
5-
<title>zenith</title>
5+
<title>pg-wasm</title>
66
<link rel="preconnect" href="https://fonts.gstatic.com">
77
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&display=swap" rel="stylesheet">
88
<link href="styles.css" rel="stylesheet">
@@ -48,9 +48,15 @@
4848
// };
4949

5050
var Module = {
51-
preRun: [],
51+
preRun: [()=> {
52+
FS.mkdir('/pgdata/pg_notify');
53+
FS.mkdir('/pgdata/pg_commit_ts');
54+
FS.mkdir('/pgdata/pg_replslot');
55+
FS.mkdir('/pgdata/pg_twophase');
56+
FS.mkdir('/pgdata/pg_tblspc');
57+
}],
5258
postRun: [],
53-
arguments: ['--single','-F','-O','-j','-c','search_path=pg_catalog','-c','dynamic_shared_memory_type=mmap','-d','0','-D','/Users/stas/datadir','template1'],
59+
arguments: ['--single','-F','-O','-j','-c','search_path=pg_catalog','-c','dynamic_shared_memory_type=mmap','-d','0','-D','/pgdata','template1'],
5460
print: (function() {
5561
return function(text) {
5662
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
@@ -69,6 +75,9 @@
6975
monitorRunDependencies: function(left) {
7076
this.totalDependencies = Math.max(this.totalDependencies, left);
7177
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
78+
},
79+
locateFile: (base, _path) => {
80+
return "debug/" + base;
7281
}
7382
};
7483

@@ -81,9 +90,9 @@
8190
};
8291
};
8392
</script>
84-
<script async type="text/javascript" src="share.js"></script>
85-
<script async type="text/javascript" src="datadir.js"></script>
86-
<script async type="text/javascript" src="postgres.js"></script>
93+
<script async type="text/javascript" src="debug/share.js"></script>
94+
<script async type="text/javascript" src="debug/pgdata.js"></script>
95+
<script async type="text/javascript" src="debug/postgres.js"></script>
8796

8897
</body>
8998
<script src="script.js"></script>

wasm/initdb.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env node
2+
//
3+
// This script generates file packs needed for postgres to start:
4+
//
5+
// * Properly initialized data directory. We use NODEFS driver to share the
6+
// data directory between the host system and wasm. That way initialization
7+
// mostly happens inside of the wasm. Some preliminary steps like creating
8+
// directory strycture and filling BKI file template are done in that script.
9+
//
10+
// * /usr/local/pgsql/share/ directory. Postgres needs it at least for the
11+
// timezone. Probably with a bit of work we could get rid of it.
12+
//
13+
var fs = require('fs');
14+
var path = require('path');
15+
16+
DIRS = [
17+
'global',
18+
'pg_wal',
19+
'pg_wal/archive_status',
20+
'pg_commit_ts',
21+
'pg_dynshmem',
22+
'pg_notify',
23+
'pg_serial',
24+
'pg_snapshots',
25+
'pg_subtrans',
26+
'pg_twophase',
27+
'pg_multixact',
28+
'pg_multixact/members',
29+
'pg_multixact/offsets',
30+
'base',
31+
'base/1',
32+
'pg_replslot',
33+
'pg_tblspc',
34+
'pg_stat',
35+
'pg_stat_tmp',
36+
'pg_xact',
37+
'pg_logical',
38+
'pg_logical/snapshots',
39+
'pg_logical/mapping',
40+
]
41+
42+
43+
FILES = [
44+
'postgresql.conf',
45+
'postgresql.auto.conf',
46+
'pg_ident.conf',
47+
'pg_hba.conf',
48+
]
49+
50+
WASM_PGDATA = '/pgdata'
51+
52+
// Wasm has it's own 32-bit architecture, so wee need to initialize the data directory
53+
// from the wasm itself. Use NODEFS shared directories to do this.
54+
function initDataDir(build_path, share_path) {
55+
56+
let datadir_path = build_path + '/temp_pgdata'
57+
58+
// 1. Create postgres datadir structure
59+
console.log('Creating postgres datadir structure in :', datadir_path)
60+
fs.rmSync(datadir_path, {recursive: true, force: true});
61+
fs.mkdirSync(datadir_path);
62+
fs.chmodSync(datadir_path, '0750');
63+
for (dir of DIRS) {
64+
console.log('Creating directory: ' + datadir_path + '/' + dir);
65+
fs.mkdirSync(datadir_path + '/' + dir);
66+
fs.chmodSync(datadir_path + '/' + dir, '0700');
67+
}
68+
for (file of FILES) {
69+
fs.writeFileSync(datadir_path + '/' + file, '');
70+
}
71+
fs.writeFileSync(datadir_path + '/PG_VERSION', '15devel');
72+
fs.writeFileSync(datadir_path + '/base/1/PG_VERSION', '15devel');
73+
74+
// 2. Fill BKI file template
75+
let bki = fs.readFileSync(share_path + '/postgres.bki', 'utf8')
76+
77+
bki = bki.replaceAll('NAMEDATALEN', '64')
78+
bki = bki.replaceAll('SIZEOF_POINTER', '4')
79+
bki = bki.replaceAll('ALIGNOF_POINTER', 'i')
80+
bki = bki.replaceAll('FLOAT8PASSBYVAL', 'false')
81+
bki = bki.replaceAll('POSTGRES', "'postgres'")
82+
bki = bki.replaceAll('ENCODING', '6') // PG_UTF8
83+
bki = bki.replaceAll('LC_COLLATE', "'en_US.UTF-8'")
84+
bki = bki.replaceAll('LC_CTYPE', "'en_US.UTF-8'")
85+
86+
fs.writeFileSync(share_path + '/postgres_wasm.bki', bki);
87+
88+
// 3. Bootstrap postgres
89+
var Module = {
90+
preRun: () => {
91+
FS.mkdir(WASM_PGDATA);
92+
FS.mount(NODEFS, { root: datadir_path }, WASM_PGDATA);
93+
94+
FS.mkdir('/usr');
95+
FS.mkdir('/usr/local');
96+
FS.mkdir('/usr/local/pgsql');
97+
FS.mkdir('/usr/local/pgsql/share');
98+
FS.mount(NODEFS, { root: share_path }, '/usr/local/pgsql/share');
99+
},
100+
locateFile: (file_path, _dir) => {
101+
let p = path.resolve(build_path, file_path);
102+
console.log('Locate file:', file_path, '->', p);
103+
return p;
104+
},
105+
arguments: ['--boot', '-x1', '-X', '16777216', '-d', '5', '-c', 'dynamic_shared_memory_type=mmap', '-D', WASM_PGDATA]
106+
};
107+
eval(fs.readFileSync(path.resolve(build_path,'postgres.js')).toString());
108+
109+
}
110+
111+
// assumming that this script is located in repo_root/wasm
112+
let build_path = path.resolve(__dirname, 'debug');
113+
let share_path = path.resolve(__dirname, '../tmp_install/usr/local/pgsql/share');
114+
115+
initDataDir(build_path, share_path);
116+
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy