changeset 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
files CMakeLists.txt dep/animia/CMakeLists.txt dep/animia/include/animia/fd/kvm.h dep/animia/src/fd.cc dep/animia/src/fd/kvm.cc
diffstat 5 files changed, 72 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sun Nov 19 17:30:38 2023 -0500
+++ b/CMakeLists.txt	Sun Nov 19 19:13:28 2023 -0500
@@ -195,8 +195,7 @@
 set_property(TARGET minori PROPERTY AUTOMOC ON)
 set_property(TARGET minori PROPERTY AUTORCC ON)
 
-target_include_directories(minori PUBLIC ${CURL_INCLUDE_DIRS} PRIVATE ${INCLUDE})
-target_include_directories(minori PUBLIC ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS})
+target_include_directories(minori PUBLIC ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} PRIVATE ${INCLUDE})
 target_compile_options(minori PRIVATE -Wall -Wpedantic -Wextra -Wsuggest-override -Wold-style-cast)
 if(APPLE)
 	target_compile_definitions(minori PUBLIC MACOSX)
--- a/dep/animia/CMakeLists.txt	Sun Nov 19 17:30:38 2023 -0500
+++ b/dep/animia/CMakeLists.txt	Sun Nov 19 19:13:28 2023 -0500
@@ -73,16 +73,15 @@
 			list(APPEND DEFINES LIBUTIL)
 			list(APPEND SRC_FILES src/fd/libutil.cc)
 		endif() # LIBUTIL_GOOD
-	elseif(LIBKVM_LIBRARY) # BSD libkvm
-		get_filename_component(LIBKVM_DIR ${LIBKVM_LIBRARY} DIRECTORY)
+	elseif(LIBKVM_LIBRARY) # OpenBSD kvm
+		include(CheckSymbolExists)
+		# Check if we can get open files by PID
+		check_symbol_exists(KERN_FILE_BYPID "kvm.h" HAVE_BYPID)
 
-		include(CheckLibraryExists)
-		check_library_exists(kvm kvm_getprocs ${LIBKVM_DIR} LIBKVM_GOOD)
-
-		if(LIBKVM_GOOD)
+		if(HAVE_BYPID)
 			list(APPEND LIBRARIES ${LIBKVM_LIBRARY})
 			list(APPEND DEFINES LIBKVM)
-			list(APPEND SRC_FILES src/fd/libkvm.cc)
+			list(APPEND SRC_FILES src/fd/kvm.cc)
 		endif() # LIBUTIL_GOOD
 	endif() # LINUX
 
@@ -128,5 +127,5 @@
 )
 
 target_compile_definitions(animia PUBLIC ${DEFINES})
-target_include_directories(animia PRIVATE include PUBLIC ${INCLUDE_DIRS})
+target_include_directories(animia PUBLIC include PRIVATE ${INCLUDE_DIRS})
 target_link_libraries(animia PUBLIC ${LIBRARIES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animia/include/animia/fd/kvm.h	Sun Nov 19 19:13:28 2023 -0500
@@ -0,0 +1,20 @@
+#ifndef __animia__animia__fd__kvm_h
+#define __animia__animia__fd__kvm_h
+
+#include <set>
+#include <string>
+
+#include "animia/fd.h"
+#include "animia/types.h"
+
+namespace animia::internal::kvm {
+
+class KvmFdTools final : public BaseFdTools {
+	public:
+		bool EnumerateOpenProcesses(process_proc_t process_proc) override;
+		bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override;
+};
+
+} // namespace animia::internal::kvm
+
+#endif // __animia__animia__fd__kvm_h
--- a/dep/animia/src/fd.cc	Sun Nov 19 17:30:38 2023 -0500
+++ b/dep/animia/src/fd.cc	Sun Nov 19 19:13:28 2023 -0500
@@ -8,6 +8,8 @@
 #	include "animia/fd/xnu.h"
 #elif defined(LIBUTIL)
 #   include "animia/fd/libutil.h"
+#elif defined(LIBKVM)
+#   include "animia/fd/kvm.h"
 #endif
 
 namespace animia::internal {
@@ -20,6 +22,8 @@
 xnu::XnuFdTools os_fd;
 #elif defined(LIBUTIL)
 libutil::LibutilFdTools os_fd;
+#elif defined(LIBKVM)
+kvm::KvmFdTools os_fd;
 #else
 BaseFdTools os_fd;
 #endif
--- 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;
 }
 
 }