Skip to content

Commit

Permalink
Replace extended attributes with an NDBM-API-compatible database
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Oct 29, 2017
1 parent a637c42 commit 63a9ff0
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 113 deletions.
2 changes: 1 addition & 1 deletion app/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ @implementation AppDelegate

- (int)startThings {
NSString *resourcePath = NSBundle.mainBundle.resourcePath;
int err = mount_root(resourcePath.UTF8String);
int err = mount_root(&realfs, resourcePath.UTF8String);
if (err < 0)
return err;

Expand Down
66 changes: 66 additions & 0 deletions fs/fake.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <ndbm.h>
#include <string.h>
#include <fcntl.h>
#include "kernel/fs.h"

struct ish_stat {
dword_t mode;
dword_t uid;
dword_t gid;
dword_t rdev;
};

static datum read_meta(struct mount *mount, const char *path, const char *type) {
DBM *db = mount->data;
if (db == NULL) {
char db_path[PATH_MAX];
strcpy(db_path, mount->source);
char *basename = strrchr(db_path, '/') + 1;
assert(strcmp(basename, "data") == 0);
strncpy(basename, "meta", 4);
db = dbm_open(db_path, O_RDWR, 0666);
assert(db != NULL);
}
char keydata[MAX_PATH+strlen(type)+1];
strcpy(keydata, type);
strcat(keydata, ":");
strcat(keydata, path);
datum key = {.dptr = keydata, .dsize = strlen(keydata)};
return dbm_fetch(db, key);
}

static int fakefs_stat(struct mount *mount, char *path, struct statbuf *fake_stat, bool follow_links) {
int err = realfs_stat(mount, path, fake_stat, follow_links);
if (err < 0)
return err;
datum d = read_meta(mount, path, "meta");
if (d.dptr != NULL) {
assert(d.dsize == sizeof(struct ish_stat));
struct ish_stat *ishstat = (void *) d.dptr;
fake_stat->mode = ishstat->mode;
fake_stat->uid = ishstat->uid;
fake_stat->gid = ishstat->gid;
fake_stat->rdev = ishstat->rdev;
}
return 0;
}

static int fakefs_fstat(struct fd *fd, struct statbuf *fake_stat) {
// this is truly sad, but there is no alternative
char path[MAX_PATH];
int err = fd->ops->getpath(fd, path);
if (err < 0)
return err;
return fakefs_stat(fd->mount, path, fake_stat, false);
}

const struct fs_ops fakefs = {
.open = realfs_open,
.unlink = realfs_unlink,
.stat = fakefs_stat,
.access = realfs_access,
.readlink = realfs_readlink,
.fstat = fakefs_fstat,
.statfs = realfs_statfs,
.flock = realfs_flock,
};
44 changes: 0 additions & 44 deletions fs/ishstat.h

This file was deleted.

41 changes: 12 additions & 29 deletions fs/real.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "kernel/fs.h"
#include "fs/dev.h"
#include "fs/tty.h"
#include "fs/ishstat.h"

static int getpath(int fd, char *buf) {
#if defined(__linux__)
Expand Down Expand Up @@ -46,7 +45,7 @@ char *strnprepend(char *str, const char *prefix, size_t max) {

// TODO translate goddamn flags

static struct fd *realfs_open(struct mount *mount, char *path, int flags, int mode) {
struct fd *realfs_open(struct mount *mount, char *path, int flags, int mode) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return ERR_PTR(_ENAMETOOLONG);

Expand Down Expand Up @@ -93,15 +92,7 @@ static void copy_stat(struct statbuf *fake_stat, struct stat *real_stat) {
/* fake_stat->ctime_nsec = real_stat->st_ctim.tv_nsec; */
}

static void copy_xattr_stat(struct statbuf *fake_stat, struct xattr_stat *xstat) {
fake_stat->dev = xstat->dev;
fake_stat->mode = xstat->mode;
fake_stat->uid = xstat->uid;
fake_stat->gid = xstat->gid;
fake_stat->rdev = xstat->rdev;
}

static int realfs_stat(struct mount *mount, char *path, struct statbuf *fake_stat, bool follow_links) {
int realfs_stat(struct mount *mount, char *path, struct statbuf *fake_stat, bool follow_links) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

Expand All @@ -114,26 +105,18 @@ static int realfs_stat(struct mount *mount, char *path, struct statbuf *fake_sta
if (stat_fn(path, &real_stat) < 0)
return err_map(errno);
copy_stat(fake_stat, &real_stat);

struct xattr_stat xstat;
if (lget_ishstat(path, &xstat) == sizeof(xstat))
copy_xattr_stat(fake_stat, &xstat);
return 0;
}

static int realfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
int realfs_fstat(struct fd *fd, struct statbuf *fake_stat) {
struct stat real_stat;
if (fstat(fd->real_fd, &real_stat) < 0)
return err_map(errno);
copy_stat(fake_stat, &real_stat);

struct xattr_stat xstat;
if (fget_ishstat(fd->real_fd, &xstat) == sizeof(xstat))
copy_xattr_stat(fake_stat, &xstat);
return 0;
}

static int realfs_unlink(struct mount *mount, char *path) {
int realfs_unlink(struct mount *mount, char *path) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

Expand All @@ -143,7 +126,7 @@ static int realfs_unlink(struct mount *mount, char *path) {
return res;
}

static int realfs_access(struct mount *mount, char *path, int mode) {
int realfs_access(struct mount *mount, char *path, int mode) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

Expand Down Expand Up @@ -172,7 +155,7 @@ ssize_t realfs_write(struct fd *fd, const void *buf, size_t bufsize) {
return res;
}

static int realfs_readdir(struct fd *fd, struct dir_entry *entry) {
int realfs_readdir(struct fd *fd, struct dir_entry *entry) {
if (fd->dir == NULL)
fd->dir = fdopendir(fd->real_fd);
if (fd->dir == NULL)
Expand All @@ -191,7 +174,7 @@ static int realfs_readdir(struct fd *fd, struct dir_entry *entry) {
return 0;
}

static off_t realfs_lseek(struct fd *fd, off_t offset, int whence) {
off_t realfs_lseek(struct fd *fd, off_t offset, int whence) {
if (whence == LSEEK_SET)
whence = SEEK_SET;
else if (whence == LSEEK_CUR)
Expand All @@ -206,7 +189,7 @@ static off_t realfs_lseek(struct fd *fd, off_t offset, int whence) {
return res;
}

static int realfs_mmap(struct fd *fd, off_t offset, size_t len, int prot, int flags, void **mem_out) {
int realfs_mmap(struct fd *fd, off_t offset, size_t len, int prot, int flags, void **mem_out) {
int mmap_flags = 0;
if (flags & MMAP_PRIVATE) mmap_flags |= MAP_PRIVATE;
if (flags & MMAP_SHARED) mmap_flags |= MAP_SHARED;
Expand All @@ -218,7 +201,7 @@ static int realfs_mmap(struct fd *fd, off_t offset, size_t len, int prot, int fl
return 0;
}

static ssize_t realfs_readlink(struct mount *mount, char *path, char *buf, size_t bufsize) {
ssize_t realfs_readlink(struct mount *mount, char *path, char *buf, size_t bufsize) {
if (strnprepend(path, mount->source, MAX_PATH) == NULL)
return _ENAMETOOLONG;

Expand All @@ -228,7 +211,7 @@ static ssize_t realfs_readlink(struct mount *mount, char *path, char *buf, size_
return size;
}

static int realfs_getpath(struct fd *fd, char *buf) {
int realfs_getpath(struct fd *fd, char *buf) {
int err = getpath(fd->real_fd, buf);
if (err < 0)
return err;
Expand All @@ -241,14 +224,14 @@ static int realfs_getpath(struct fd *fd, char *buf) {
return 0;
}

static int realfs_statfs(struct mount *mount, struct statfsbuf *stat) {
int realfs_statfs(struct mount *mount, struct statfsbuf *stat) {
stat->type = 0x7265616c;
stat->namelen = NAME_MAX;
stat->bsize = PAGE_SIZE;
return 0;
}

static int realfs_flock(struct fd *fd, int operation) {
int realfs_flock(struct fd *fd, int operation) {
int real_op = 0;
if (operation & LOCK_SH_) real_op |= LOCK_SH;
if (operation & LOCK_EX_) real_op |= LOCK_EX;
Expand Down
13 changes: 13 additions & 0 deletions kernel/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct mount {
const char *source;
const struct fs_ops *fs;
struct mount *next;
void *data;
};
extern struct mount *mounts;

Expand Down Expand Up @@ -180,6 +181,15 @@ int path_normalize(struct fd *at, const char *path, char *out, bool follow_links

// real fs
extern const struct fs_ops realfs;

struct fd *realfs_open(struct mount *mount, char *path, int flags, int mode);
int realfs_stat(struct mount *mount, char *path, struct statbuf *fake_stat, bool follow_links);
int realfs_fstat(struct fd *fd, struct statbuf *fake_stat);
int realfs_unlink(struct mount *mount, char *path);
int realfs_access(struct mount *mount, char *path, int mode);
ssize_t realfs_readlink(struct mount *mount, char *path, char *buf, size_t bufsize);
int realfs_statfs(struct mount *mount, struct statfsbuf *stat);
int realfs_flock(struct fd *fd, int operation);
extern const struct fd_ops realfs_fdops;
ssize_t realfs_read(struct fd *fd, void *buf, size_t bufsize);
ssize_t realfs_write(struct fd *fd, const void *buf, size_t bufsize);
Expand All @@ -188,6 +198,9 @@ int realfs_close(struct fd *fd);
// adhoc fs
struct fd *adhoc_fd_create(void);

// fake fs
extern const struct fs_ops fakefs;

// TODO put this somewhere else
char *strnprepend(char *str, const char *prefix, size_t max);

Expand Down
4 changes: 2 additions & 2 deletions kernel/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
#include "kernel/calls.h"
#include "fs/tty.h"

int mount_root(const char *source) {
int mount_root(const struct fs_ops *fs, const char *source) {
char source_realpath[MAX_PATH + 1];
if (realpath(source, source_realpath) == NULL)
return err_map(errno);
mounts = malloc(sizeof(struct mount));
mounts->point = "";
mounts->source = strdup(source_realpath);
mounts->fs = &realfs;
mounts->fs = fs;
mounts->next = NULL;
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "fs/tty.h"

int mount_root(const char *source);
int mount_root(const struct fs_ops *fs, const char *source);
int create_init_process(const char *program, char *const argv[], char *const envp[]);
int create_stdio(struct tty_driver driver);

Expand Down
9 changes: 6 additions & 3 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ src = [
'fs/generic.c',
'fs/path.c',
'fs/real.c',
'fs/fake.c',
'fs/poll.c',
'fs/adhoc.c',

Expand All @@ -71,21 +72,23 @@ src = [
cified_vdso,
]

cc = meson.get_compiler('c')
threads = dependency('threads')
librt = meson.get_compiler('c').find_library('rt', required: false)
librt = cc.find_library('rt', required: false)
softfloat = subproject('softfloat').get_variable('softfloat_dep')
dbm = [cc.find_library('gdbm', required: false), cc.find_library('gdbm_compat', required: false)]

libish = library('ish', src,
include_directories: includes,
dependencies: [librt, threads, softfloat])
dependencies: [librt, threads, softfloat, dbm])
ish = declare_dependency(
link_with: libish,
include_directories: includes)

# ptraceomatic et al
subdir('tools')

executable('ish', ['main.c'], dependencies: [ish, softfloat, threads])
executable('ish', ['main.c'], dependencies: [ish, softfloat, threads, dbm])

gdb_scripts = ['ish-gdb.gdb']
foreach script : gdb_scripts
Expand Down
5 changes: 2 additions & 3 deletions tools/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ if build_machine.system() == 'linux'
'ptutil.c',
cified_vdso,
]
executable('ptraceomatic', ['ptraceomatic.c', 'undefined-flags.c', transplant_src], dependencies: [ish, softfloat, threads])
executable('ptraceomatic', ['ptraceomatic.c', 'undefined-flags.c', transplant_src],
dependencies: [ish, softfloat, threads, dbm])
configure_file(input: 'ptraceomatic-gdb.gdb', output: '@PLAINNAME@', configuration: configuration_data())

# tools for messing with vdsos
# executable('vdso-dump', ['vdso-dump.c'], c_args: ['-m32'], link_args: ['-m32'])
executable('vdso-transplant', ['vdso-transplant-main.c', transplant_src],
include_directories: includes)
endif

executable('xattrify_fs', ['xattrify_fs.c'], include_directories: includes)
2 changes: 1 addition & 1 deletion tools/ptraceomatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static void step_tracing(struct cpu_state *cpu, int pid, int sender, int receive
case 145: { // readv
struct io_vec vecs[regs.rdx];
(void) user_get(regs.rcx, vecs);
for (int i = 0; i < regs.rdx; i++)
for (unsigned i = 0; i < regs.rdx; i++)
pt_copy(pid, vecs[i].base, vecs[i].len);
break;
}
Expand Down
Loading

0 comments on commit 63a9ff0

Please sign in to comment.