Skip to content

Commit

Permalink
Work on symlinks
Browse files Browse the repository at this point in the history
  • Loading branch information
charmoniumQ committed Jan 20, 2025
1 parent 9de390d commit 9fb8086
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 195 deletions.
3 changes: 2 additions & 1 deletion libprobe/include/libprobe/prov_ops.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
struct Path {
int32_t dirfd_minus_at_fdcwd;
const char* path; /* path valid if non-null */
int16_t mode_and_type;
dev_t device_major;
dev_t device_minor;
ino_t inode;
Expand All @@ -11,7 +12,7 @@ struct Path {
bool dirfd_valid;
};

static const struct Path null_path = {-1, NULL, -1, -1, -1, {0}, {0}, 0, false, false};
static const struct Path null_path = {-1, NULL, -1, -1, -1, -1, {0}, {0}, 0, false, false};
/* We don't need to free paths since I switched to the Arena allocator */
/* static void free_path(struct Path path); */

Expand Down
173 changes: 0 additions & 173 deletions libprobe/src/fd_table.c

This file was deleted.

5 changes: 5 additions & 0 deletions libprobe/src/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ typedef int (*fn_ptr_int_void_ptr)(void*);

static void maybe_init_thread();
static void reinit_process();
/*
** TODO: Remove disable/enable
** We always call unwrapped_syscall in libprobe
** So we don't need to disable library first.
*/
static void prov_log_disable();
static int get_exec_epoch_safe();
static bool __process_inited = false;
Expand Down
43 changes: 28 additions & 15 deletions libprobe/src/prov_ops.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
static struct Path create_path_lazy(int dirfd, BORROWED const char* path, int flags) {
if (likely(prov_log_is_enabled())) {
struct Path ret = {
dirfd - AT_FDCWD,
(path != NULL ? EXPECT_NONNULL(arena_strndup(get_data_arena(), path, PATH_MAX)) : NULL),
-1,
-1,
-1,
{0},
{0},
0,
false,
true,
};
struct Path ret = null_path;
ret.dirfd_minus_at_fdcwd = dirfd - AT_FDCWD;
ret.path = (path != NULL ? EXPECT_NONNULL(arena_strndup(get_data_arena(), path, PATH_MAX)) : NULL);
ret.dirfd_valid = true;

/*
* If path is empty string, AT_EMPTY_PATH should probably be set.
Expand All @@ -26,18 +18,22 @@ static struct Path create_path_lazy(int dirfd, BORROWED const char* path, int fl
/*
* if path == NULL, then the target is the dir specified by dirfd.
* */
prov_log_disable();
struct statx statx_buf;
int stat_ret = unwrapped_statx(dirfd, path, flags, STATX_INO | STATX_MTIME | STATX_CTIME | STATX_SIZE, &statx_buf);
prov_log_enable();
flags = flags | AT_SYMLINK_NOFOLLOW | AT_STATX_DONT_SYNC;
int mask = STATX_TYPE | STATX_MODE | STATX_INO | STATX_MTIME | STATX_CTIME | STATX_SIZE;
int stat_ret = unwrapped_statx(dirfd, path, flags, mask, &statx_buf);
if (stat_ret == 0) {
ret.mode_and_type = statx_buf.stx_mode;
ret.device_major = statx_buf.stx_dev_major;
ret.device_minor = statx_buf.stx_dev_minor;
ret.inode = statx_buf.stx_ino;
ret.mtime = statx_buf.stx_mtime;
ret.ctime = statx_buf.stx_ctime;
ret.size = statx_buf.stx_size;
ret.stat_valid = true;
if (statx_buf.stx_type & S_IFMT == S_IFLNK) {
link_deref(dirfd, path, &ret);
}
} else {
DEBUG("Stat of %d,%s is not valid", dirfd, path);
}
Expand All @@ -48,6 +44,23 @@ static struct Path create_path_lazy(int dirfd, BORROWED const char* path, int fl
}
}

void link_deref(int dirfd, BORROWED const char* pathname, const Path* path) {
/* Some magic symlinks under (for example) /proc and /sys
report 'st_size' as zero. In that case, take PATH_MAX as
a "good enough" estimate. */
if (inode_table_put_if_not_exists(get_symlink_table(), path)) {
size_t symlink_size = path->size == 0 ? PATH_MAX : path->size + 1;
char* referent_pathname = EXPECT_NONNULL(arena_calloc(get_data_arena(), symlink_size, 1));
ssize_t readlink_ret = unwrapped_readlinkat(dirfd, path, referent_pathname, symlink_size);
assert(readlink_ret < symlink_size);
referent_pathname[readlink_ret] = '\0';
Path referent_path = create_path_lazy(dirfd, path, flags);
SymlinkInfo* info = EXPECT_NONNULL(arena_calloc(get_symlink_arena(), SymlinkInfo, 1));
info->pathname = referent_pathname;
info->path = referent_path;
}
}

void path_to_id_string(const struct Path* path, BORROWED char* string) {
CHECK_SNPRINTF(
string,
Expand Down
6 changes: 3 additions & 3 deletions probe_py/probe_py/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ def file_closure(
out_console = rich.console.Console()
with parse_probe_log_ctx(probe_log) as prov_log:
closure = file_closure_mod.get_file_closure(prov_log)
for resolved_path, maybe_path in closure:
if maybe_path and show_metadata:
out_console.print(resolved_path, maybe_path)
for resolved_path, path_metadata, path_copy in closure:
if path_metadata and show_metadata:
out_console.print(resolved_path, path_metadata, path_copy, path_copy.stat() if path_copy else None)
else:
out_console.print(resolved_path)

Expand Down
20 changes: 17 additions & 3 deletions probe_py/probe_py/file_closure.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def build_oci_image(
text=True,
)

cmd = ["buildah", "rm", image_name]
cmd = ["buildah", "rm", container_id]
if verbose:
console.log(shlex.join(cmd))
subprocess.run(
Expand All @@ -144,7 +144,7 @@ def build_oci_image(

def get_file_closure(
prov_log: ProvLog,
) -> list[tuple[pathlib.Path, Path | None]]:
) -> list[tuple[pathlib.Path, Path | None, pathlib.Path | None]]:
"""
Return a list of paths read by the executable
"""
Expand Down Expand Up @@ -195,7 +195,21 @@ def get_file_closure(
for dependent_dlib in dependent_dlibs:
closure[pathlib.Path(dependent_dlib)] = None

return list(closure.items())
return [
(
path,
path_metadata,
prov_log.inodes.get(InodeVersionLog(
path_metadata.device_major,
path_metadata.device_minor,
path_metadata.inode,
path_metadata.mtime.sec,
path_metadata.mtime.nsec,
path_metadata.size,
)) if path_metadata is not None else None,
)
for path, path_metadata in closure.items()
]


def copy_file_closure(
Expand Down

0 comments on commit 9fb8086

Please sign in to comment.