Mercurial > minori
diff dep/animia/src/fd/kvm.cc @ 201:8f6f8dd2eb23
dep/animia: finish kvm backend
dep/animia: cmake: don't use kvm on unsupported systems, use private and public includes properly
cmake: why are we defining target include directories twice?
author | paper@DavesDouble.local |
---|---|
date | Sun, 19 Nov 2023 19:13:28 -0500 |
parents | e44b7c428d7c |
children | 71832ffe425a |
line wrap: on
line diff
--- a/dep/animia/src/fd/kvm.cc Sun Nov 19 17:30:38 2023 -0500 +++ b/dep/animia/src/fd/kvm.cc Sun Nov 19 19:13:28 2023 -0500 @@ -7,128 +7,65 @@ ** NetBSD. */ +#include "animia/fd/kvm.h" +#include "animia/fd.h" +#include "animia.h" + +#include <sys/types.h> +#include <sys/user.h> +#include <sys/file.h> +#include <sys/filedesc.h> +#include <sys/param.h> +#include <sys/vnode.h> +#include <sys/queue.h> +#include <sys/sysctl.h> + #include <kvm.h> +#include <string> + namespace animia::internal::kvm { -static bool GetFilename(kvm_t* kvm, struct vnode *vp, std::string& name) { - struct vnode vn; - if (!kvm_read(kvm, vp, &vn, sizeof(*vn))) - return 0; - - struct filestat fst; - const char* type = vfilestat(vn, &fst); - if (type == dead) +bool KvmFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { + char errbuf[_POSIX2_LINE_MAX]; + kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); + if (!kernel) return false; - for (DEVS* d = devs; d != NULL; d = d->next) { - if (d->fsid == fst->fsid && d->ino == fst->fileid) { - name = d->name; - break; - } - } + int entries = 0; + struct kinfo_proc* kinfo = kvm_getprocs(kernel, KERN_PROC_ALL, 0, &entries); + if (!kinfo) + return false; + + for (int i = 0; i < entries; i++) + if (!process_proc({kinfo[i].ki_paddr->p_pid, kinfo[i].ki_paddr->p_comm})) + return false; + + kvm_close(kernel); return true; } -static bool GetFilePath(kvm_t* kvm, fdfile_t* fp, std::string& path) { - struct file file; - fdfile_t fdfile; - - if (!kvm_read(kvm, fp, &fdfile, sizeof(fdfile))) - return false; - - if (!fdfile.ff_file) - return false; - - if (!kvm_read(fdfile.ff_file, &file, sizeof(file))) - return false; - - if (file.f_type != DTYPE_VNODE) - return false; - - return GetFilename(kvm, file.f_data, path); -} - -static bool OpenFiles(kvm_t* kvm, struct kinfo_proc* p, open_file_proc_t open_file_proc) { - if (p->proc->p_fd == 0 || p->proc->p_cwdi == 0) - return false; - - struct filedesc filed; - if (!kvm_read(kvm, p->proc->p_fd, &filed, sizeof(filed))) - return false; - - if (filed.fd_lastfile == -1) - return false; - - struct cwdinfo cwdi; - if (!kvm_read(kvm, p->proc->p_cwdi, &cwdi, sizeof(cwdi))) - return false; - - struct fdtab dt; - if (!kvm_read(kvm, filed.fd_dt, &dt, sizeof(dt))) - return false; - - /* check for corrupted files? */ - if ((unsigned)filed.fd_lastfile >= dt.dt_nfiles || filed.fd_freefile > filed.fd_lastfile + 1) - return false; - - /* open files */ - std::unique_ptr<fdfile_t*[]> ofiles = nullptr; - { - ofiles.reset(malloc((filed.fd_lastfile + 1) * sizeof(fdfile_t*))); - if (!ofiles.get()) - return false; - } - - if (!kvm_read(kvm, &filed.fd_dt->dt_ff, ofiles.get(), filed.fd_lastfile + 1 * (sizeof(fdfile_t*)))) - return false; - - for (int i = 0; i <= filed.fd_lastfile; i++) { - if (!ofiles[i]) - continue; - std::string name; - GetFilePath(kvm, ofiles[i], name); - if (!open_file_proc(p->proc->p_pid, name)) - return false; - } - - return true; -} - -bool EnumerateOpenProcesses(process_proc_t process_proc) { +bool KvmFdTools::EnumerateOpenFiles(std::set<pid_t>& pids, open_file_proc_t open_file_proc) { char errbuf[_POSIX2_LINE_MAX]; - kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); - if (!kernel) - return false; - - int entries = 0; - struct kinfo_proc* kinfo = kvm_getprocs(kernel, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &nentries); - if (!kinfo) - return false; - - for (int i = 0; i < entries; i++) - if (!process_proc({kinfo[i].p_pid, kinfo[i].p_comm})) - return false; - - return true; -} - -bool EnumerateOpenFiles(std::set<pid_t>& pids, open_file_proc_t open_file_proc) { - kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); if (!kernel) return false; for (const auto& pid : pids) { int cnt; - struct kinfo_proc* kinfo = kvm_getprocs(kernel, KERN_PROC_PID, pid, &cnt); - if (!kinfo) + struct kinfo_file* kfile = kvm_getfiles(kernel, KERN_FILE_BYPID, pid, &cnt); + if (!kfile) return false; - for (int i = 0; i < cnt; i++) { - OpenFiles(kernel, kinfo, open_file_proc); - } + for (int i = 0; i < cnt; i++) + if (!open_file_proc({pid, kfile[i].kf_path})) + return false; } + + kvm_close(kernel); + + return true; } }