Hello fellows,
I'm new to writing a FreeBSD kernel module and want your help to port the following linux kernel module.
The module itself does: starts a new thread and calls run_it which uses an integer and char arrays to store the processes pid and their commands. Outputs only the new non existing pids and commands to dmesg and fills the integer and char arrays too with the new pids/commands. Upon reaching 999 or more entries we reset the arrays to 0 and store the new entries in them.
So my question is: How do I start/stop a new thread with the desired function name upon loading/unloading the module ? How do I sleep within the thread ? How do I print the desired information to dmesg ?
Here's the linux module:
and here's the FreeBSD code that replaces the linux for_each_process:
I'm new to writing a FreeBSD kernel module and want your help to port the following linux kernel module.
The module itself does: starts a new thread and calls run_it which uses an integer and char arrays to store the processes pid and their commands. Outputs only the new non existing pids and commands to dmesg and fills the integer and char arrays too with the new pids/commands. Upon reaching 999 or more entries we reset the arrays to 0 and store the new entries in them.
So my question is: How do I start/stop a new thread with the desired function name upon loading/unloading the module ? How do I sleep within the thread ? How do I print the desired information to dmesg ?
Here's the linux module:
C:
/*
08/16/2018
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/sched/signal.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/udp.h>
#include <linux/mm.h>
#include <linux/kthread.h>
#include <linux/pid.h>
unsigned int quit = 0U;
struct task_struct *thread;
static int run_it(void *data) {
static unsigned int x = 0U;
static unsigned int idx = 0U;
static unsigned int skip = 0U;
static unsigned int i_arr[1000] = {0U};
static char c_arr[1000][256] = {""};
while (1) {
struct task_struct *task = NULL;
if (1U == quit) {
break;
}
for_each_process(task) {
if (idx >= 999U) {
memset(i_arr, 0, sizeof(i_arr));
memset(c_arr, 0, sizeof(c_arr));
idx = 0U;
}
for (x = 0U; x <= idx; x++) {
if (i_arr[x] == (unsigned int)(task->pid) && 0 == (strcmp(task->comm, c_arr[x]))) {
skip = 1U;
break;
}
}
if (0 == (strcmp(task->comm, "")) ||
(int)pid_nr(get_task_pid(thread, PIDTYPE_PID)) == task->pid) {
skip = 1U;
}
if (1U != skip) {
i_arr[idx] = (unsigned int)task->pid;
snprintf(c_arr[idx], 255, "%s", task->comm);
printk("%d %s\n", task->pid, task->comm);
idx++;
}
skip = 0U;
schedule();
}
ssleep(5);
}
do_exit(0);
return 0;
}
static int __init init_hello(void) {
thread = kthread_run(run_it, NULL, "list processes");
if (thread) {
wake_up_process(thread);
}
return 0;
}
static void __exit init_exit(void) {
quit = 1U;
kthread_stop(thread);
}
module_init(init_hello);
module_exit(init_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("su8");
MODULE_DESCRIPTION("List all processes and log them to dmesg");
and here's the FreeBSD code that replaces the linux for_each_process:
C:
/*
09/03/2018
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <kvm.h>
int main (void) {
struct kinfo_proc *kp = NULL;
int x = 1;
int count = 0;
FILE *fp = NULL;
kvm_t *kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, "error: ");
if (NULL == kd) {
return EXIT_FAILURE;
}
if (NULL == (fp = fopen("/tmp/log", "a"))) {
goto err;
}
kp = kvm_getprocs(kd, KERN_PROC_PROC, 0, &count);
for (; x < count; x++) {
fprintf(fp, "%d %s\n", kp[x].ki_pid, kp[x].ki_comm);
}
err:
if (NULL != fp) {
fclose(fp);
}
kvm_close(kd);
return EXIT_SUCCESS;
}