List all mount points in kernel module - c

I'm trying to list all the mount points in a kernel module. The method in this answer doesn't list all the mount point, and this answer is for older kernel version.
I'm working on kernel version 4.15.0.
I found this method (iterate_mounts) and wrote this simple kernel module.
int mount_f(struct vfsmount *mnt, void *arg)
{
char *tmp, *path;
if(mnt == NULL || mnt->mnt_root == NULL)
{
return 0;
}
tmp = (char*)__get_free_page(GFP_KERNEL);
path = dentry_path_raw(mnt->mnt_root, tmp, PAGE_SIZE);
if(!IS_ERR(path))
{
pr_info("mounted path=%s\n", path);
}
free_page((unsigned long)tmp);
return 0;
}
int init_module(void)
{
struct path path;
struct vfsmount *root_mnt;
int err;
err = kern_path("/", 0, &path);
if (err)
{
return -1;
}
root_mnt = path.mnt;
path_put(&path);
if (IS_ERR(root_mnt))
{
return -1;
}
iterate_mounts(mount_f, NULL, root_mnt);
return 0;
}
but it doesn't print the correct path (it prints just "/" for all mounts).
Am I missing something here?
Also, which methods gets called when a new mount is mounted or unmounted?
I'm assuming for unmounting (do_umount) gets called?
Edit: another question, how can I identify the mount if it's removable or not? any flags in the struct vfsmount or struct super_block that can help me identify that?

Related

libxml2 get offset into XML text of node

I need to know at which offset into an xml string a specific arbitrary node somewhere in dom can be found after xmlReadMemory was used to get dom. The problem is I can't figure out where to get the xmlParserCtxtPtr from to pass as first argument to xmlParserFindNodeInfo because my entire process of parsing yields no such context; only a xmlDoc.
The following code worked for me (libxml2 documentation leaves little to desire, had to download source code and dig in the lib until I understood enough to hack this together). The key is:
xmlSetFeature(ctxt, "gather line info", (void *)&v);
Here is some code to illustrate:
const char *xml = ...
xmlParserCtxt *ctxt = NULL;
xmlDoc *doc = NULL;
if (!(ctxt = xmlCreateDocParserCtxt((const unsigned char *)xml)))
return -1;
int v = 1;
xmlSetFeature(ctxt, "gather line info", (void *)&v);
if (xmlParseDocument(ctxt) == -1)
{
xmlFreeParserCtxt(ctxt);
return -1;
}
else
{
if ((ctxt->wellFormed) || ctxt->recovery)
doc = ctxt->myDoc;
else
{
xmlFreeParserCtxt(ctxt);
return -1;
}
}
// use doc to get a node and then xmlParserFindNodeInfo(ctxt, node)
…
xmlFreeParserCtxt(ctxt);

Freeing memory gives segmentation fault [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I've been trying to work with structures, pointers and memory in C.
I have created this structure
typedef struct {
int id;
char *name;
} Object;
here is constructor
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if(sizeof(o->name)!=sizeof(name))
{
o->name=NULL;
}
else
{
strcpy(o->name, name);
}
}
here is decleration of o1
char tmp_name[] = "Hello 1";
Object o1;
object_ctor(&o1, 1, tmp_name);
here is destructor
void object_dtor(Object *o)
{
if(o->name != NULL)
{
free(o->name);
o->name = NULL;
}
}
printing object
void print_object(Object *o)
{
printf("ID: %d, NAME: %s\n", o->id, o->name);
}
calling copy
Object copy;
print_object(object_cpy(&copy, &o1));
and I´m trying create a copy of one structure to another (I have already constructed them).
Object *object_cpy(Object *dst, Object *src)
{
if(src!=NULL)
{
const size_t len_str=strlen(src->name)+1;
dst->name = malloc(10000000);
dst->id = src->id;
strncpy (dst->name, src->name,len_str);
}
if (strcmp(dst->name,src->name)!=0)
{
dst->name = NULL;
}
return dst;
}
But then when I'm trying to free both copy and original src I get a segmentation fault. I've been trying to run it through gdb and it said that I'm freeing same memory twice so I assume that the code for copying is wrong, but I don't know where.
And here is code that gives me segmentation fault
printf("\nCOPY EMPTY\n");
object_dtor(&copy);
o1.id = -1;
free(o1.name);
o1.name = NULL;
object_cpy(&copy, &o1);
print_object(&copy);
print_object(&o1);
I´m including these libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
I'm using the std=c99 flag for to compile.
There is at least a problem here:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if (sizeof(o->name) != sizeof(name))
{
o->name = NULL;
}
else
{
strcpy(o->name, name);
}
}
sizeof(name) is not the length of the string pointed by name. You need strlen(name) + 1 (+1 for the NUL terminator).
And your test if (sizeof(o->name) != sizeof(name)) is pointless, and I'm not sure what you're trying to achieve here.
You probably want this:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(strlen(name) + 1);
if (o->name != NULL)
strcpy(o->name, name);
}
There are similar problems in object_cpy:
pointless use of strncpy
pointless allocation of a 10Mb buffer
pointless test strcmp(dst->name, src->name)
You probably want this:
Object *object_cpy(Object *dst, Object *src)
{
if (src != NULL)
{
const size_t len_str = strlen(src->name) + 1;
dst->name = malloc(len_str);
if (dst->name != NULL)
{
dst->id = src->id;
strcpy(dst->name, src->name);
}
}
return dst;
}
With these corrections following code works fine:
int main()
{
char tmp_name[] = "Hello 1";
Object o1, copy;
object_ctor(&o1, 1, tmp_name);
object_cpy(&copy, &o1);
print_object(&copy);
print_object(&o1);
object_dtor(&o1);
object_dtor(&copy);
}
Event if this is not directly an answer to your problem, I'll give you how I organize my code in order to avoid memory problem like yours.
First, it all resolve around a structure.
To each structure, if needed, I do a "Constructor" and a "Destructor".
The purpose of the constructor is simply to set the structure in a coherent state. It can't never fail (implying that any code that could fail, like malloc, should not be in the constructor).
The purpose of the destructor is to clean the structure.
One little trick that I like to use is to put the constructor in a macro, allowing me to do something like 'Object var = OBJET_CONSTRUCTOR'.
Of course, it's not alway possible, it's up to you to be carreful.
For your code, it could be :
typedef struct {
int id;
char *name;
} Object;
#define OBJECT_CONSTRUCTOR {.id = -1,\ \\ Assuming -1 is relevant in your case, like an error code or a bad id value. Otherwise, it's useless.
.name = NULL}
void Object_Constructor(Object *self)
{
Object clean = OBJECT_CONSTRUCTOR;
*self = clean;
}
void Object_Destructor(Object *self)
{
free(self->name);
}
Here we go.
How to use it is simple : You always begin by the constructor, and you alway end by the destructor. That's why it's useless to set the char pointer "name" to NULL in the destructor, because it should not be used after by any other function that the constructor.
Now, you can have "initialisation" function. You can do a plain initialisation (it is your constructor function), or a copy initialisation, etc etc
Just keep in mind that the structure have been called into the constructor. If not, it's the developer fault and you do not have to take that in count.
A behavior that can be nice is, in case of error, to not modify the structure.
Either the structure is entierly modified in succes, or not at all.
For complex structure that can fail at many point, you can do that by "swapping" the result at the end.
void Object_Swap(Object *first, Object *second)
{
Object tmp = OBJECT_CONSTRUCTOR;
tmp = *fisrt;
*first = *second;
*second = tmp;
}
bool Object_InitByPlainList(Object *self, int id, consr char *name)
{
Object newly = OBJECT_CONSTRUCTOR;
bool returnFunction = false;
newly.id = id;
if (!(newly.name = strdup(name))) {
printf("error : %s : strdup(name) : name='%s', errno='%s'.\n", __func__, name, strerror(errno));
goto END_FUNCTION;
}
// Success !
Object_Swap(self, &newly);
returnFunction = true;
/* GOTO */END_FUNCTION:
Object_Destructor(&newly);
return (returnFunction);
}
It may be seem overcomplicated at the first glance, but that organization allow you to add more futur step "that can fail" cleanly.
Now, you can even do something this simply :
bool Object_InitByCopy(Object *dst, Object *src)
{
return (Object_InitByPlainList(dst, src->id, src->name));
}
All you have to do is to say in the documentation :
The first function to be called have to be "Object_Constructor"
After the "Object_Constructor", only the "Object_Init*" function can be called.
The last function to be call have to be "Object_Destructor"
That's all. You can add any "Object_*" function that you whant, like :
void Object_Print(const Object *self)
{
printf("ID: %d, NAME: %s\n", self->id, self->name);
}
Hope this organization will solve your memory problem.
An example :
int main(void)
{
Object test = OBJECT_CONSTRUCTOR;
Object copy = OBJECT_CONSTRUCTOR;
if (!Object_InitByPlainList(&test, 1, "Hello World !")) {
// The function itself has logged why it has fail, so no need to add error printf here
return (1);
}
Object_Print(&test);
if (!Object_Copy(&copy, &test)) {
return (1);
}
Object_Destructor(&test);
Object_Destructor(&copy);
return (0);
}

Event.h library using event_new() function in C

First off, I am not a programmer, I do electrical engineering. I have done some programming, but would never say that I am a good programmer. This question will probably be downvoted, but that is ok because I have been trying to do this for two months now.
I no nothing about event.h, but I have an existing code that works and uses this. It goes like this (I changed some things to hide information, but the code works):
struct event_base *base;
struct event *read_event;
struct event *signal_event;
typedef struct sample_ctx {
sens_handle_t *sens_handler;
sens_data_t data;
} sample_ctx_t;
// signal handler to break the event loop
void
signal_handler(evutil_socket_t sock, short event, void *user_data)
{
event_base_loopbreak(base);
}
// receive callback
void
sens_recv_cb(evutil_socket_t sock, short event, void *user_data)
{
static int i = 0;
int timeout = 0;
static struct timeval timestamp;
struct timeval timestamp2;
struct timeval diff;
sens_status_t status;
sample_ctx_t *ctx;
ctx = (sample_ctx_t *)user_data;
if (i == 0) {
gettimeofday(&timestamp, NULL);
i = 1;
}
status = sens_read(&ctx->data, ctx->sens_handler);
if ((status == SENS_SUCCESS) &&
!isnan(ctx->data.info1) &&
!isnan(ctx->data.info2) &&
!isnan(ctx->data.info3) &&
!isnan(ctx->data.info4)) {
fprintf(stderr, "%lf %lf %lf %lf\n",
ctx->data.info1,
ctx->data.info2,
ctx->data.info3,
ctx->data.info4);
gettimeofday(&timestamp, NULL);
} else {
gettimeofday(&timestamp2, NULL);
timersub(&timestamp2, &timestamp, &diff);
timeout = diff.tv_sec + (diff.tv_usec / 1000000);
}
}
int main()
{
int fd;
status_t status;
sample_ctx_t ctx;
memset(&ctx, 0, sizeof(ctx));
status = sensor_open(&fd, &ctx.gps_handler);
if (status != V2X_SUCCESS) {
fprintf(stderr, "Open failed ... sensor might not be running\n");
goto deinit_4;
}
base = event_base_new();
if (!base) {
fprintf(stderr, "Failed to create event base\n");
goto deinit_3;
}
// register for the read events
read_event = event_new(base, fd, EV_PERSIST|EV_READ, sens_recv_cb, &ctx);
if (!read_event) {
fprintf(stderr, "Failed to create read event\n");
goto deinit_2;
}
// register for the SIGINT signal on ctrl + c key combo
signal_event = evsignal_new(base, SIGINT, signal_handler, NULL);
if (!signal_event) {
fprintf(stderr, "Failed to create signal event\n");
goto deinit_1;
}
event_add(read_event, NULL);
evsignal_add(signal_event, NULL);
event_base_dispatch(base);
evsignal_del(signal_event);
deinit_1:
event_free(read_event);
deinit_2:
event_base_free(base);
deinit_3:
sensor_close(ctx.sens_handler);
deinit_4:
return 0;
}
This code retrieves data from a sensor and prints it to the screen. It's purpose is pretty simple, but the way it has to be done is what is complicated; for me at least.
Ok, so in the sens_recv_cb function, the ctx->data is printed to the screen, but I need to access that in the main function. The only time this function is called is in the event_new function in main. Is there a way get that data in main? Like lets say I just want to print ctx->data.info1 in main while still printing out everything from before in the sens_recv_cb function.
Is what I want to do possible without changing the entire code?
Because main and sens_recv_cb are asynchronous, you'll need a way to signal between them and a way for the call-back to store the data. You can combine both with a linked list:
struct node {
sample_ctx_t data;
struct node *next;
struct node *previous;
}
struct node *head = NULL;
struct node *tail = NULL;
The event handler adds to the head of the list and the main function removes them from the tail. It's a FIFO. You'll need to use atomic operations when reading/writing data to the list. The links provide what you need to know, and if you search, you'll find lots of example code around here and at other sites. You can probably find an open source, thread-safe linked list implementation on GitHub.
Basically, when the list is empty, there's nothing for main to consume.

UTHash in function call does iteration once but not second time

I am having some issues with usage of a uthash on a local variable.
My code looks something like this, query_dict is a local variable uthash:
main functions:
query* query_dict = NULL;
split_query_into_terms(querystr, &query_dict);
print_query_struct(&query_dict);
prefetch_tokens(&query_dict);
more closely:
void prefetch_tokens(query** query_dict) {
query* entry;
for(entry=*query_dict; entry != NULL; entry=entry->hh.next) {
handle_token(entry->term);
}
}
void add_term_to_query(query** query_dict, char* term, dictionary_entry* dict_entry) {
// if query in hashtable, increase score:
query* myq = NULL;
if(*query_dict != NULL)
HASH_FIND_STR(*query_dict, term, myq);
if(myq == NULL) {
myq = init_alloc_query(term);
myq->dict_entry = dict_entry;
HASH_ADD_KEYPTR(hh, *query_dict, myq->term, strlen(myq->term), myq);
} else {
myq->score += 1.0f;
}
}
void split_query_into_terms(char* querystr, query** query_dict) {
char* myquery = strdup(querystr);
char* reentrant_saver;
char* token;
token = strtok_r(myquery, " \n", &reentrant_saver);
while(token != NULL) {
dictionary_entry* dict_entry = find_dict_entry(token);
if(dict_entry) {
add_term_to_query(query_dict, token, dict_entry);
}
token = strtok_r(NULL, " \n", &reentrant_saver);
}
}
void print_query_struct(query** query_dict) {
query* entry;
for(entry=*query_dict; entry != NULL; entry=entry->hh.next) {
fprintf(stdout, "%s: %f\n", entry->term, entry->score);
}
}
The call to print_query_struct runs fine, but the call to prefetch tokens, does one iteration, then crashes with:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000000
0x0000000100004959 in prefetch_tokens (query_dict=0x7fff5fbffa30) at search/c_port/search.c:241
241 handle_token(entry->term);
(gdb) bt
0 0x0000000100004959 in prefetch_tokens (query_dict=0x7fff5fbffa30) at search/search.c:241
1 0x00000001000049d2 in search (querystr=0x7fff5fbffbe5 "wash") at search/search.c:255
2 0x0000000100004a20 in main (argc=2, argv=0x7fff5fbffa80) at search/search.c:263
the address, 0x0000001000000000 always being the same.
I have been trying all kinds of different things, but could not get it working.
Does anyone here know what's going on?
structs:
typedef struct {
char* word;
uint32_t byte_offset;
uint32_t occurences;
uint32_t occurences_abstract;
postings_entry* posting;
UT_hash_handle hh; /* makes this structure hashable */
} dictionary_entry;
/* query has a number of terms (strings) */
typedef struct {
char* term;
float score;
dictionary_entry* dict_entry;
UT_hash_handle hh;
} query;
Edit:
I have simplified the code quite a bit and made a smaller runnable example, but in essence, this is the code that fails: http://pastebin.com/qdDiQMG0
compile, then run with ./binary
eg. ./binary "wash help"
Edit 2:
Solved it even though I do not quite understand why it worked:
rewrote the init_alloc_query from:
query* init_alloc_query() {
query* query = malloc(sizeof(query));
query->term = NULL;
return query;
}
to work like this:
void init_alloc_query(query** q) {
*q = malloc(sizeof(query));
(*q)->term = NULL;
}
And everything runs fine.
Solved it even though I do not quite understand why it worked: rewrote the init_alloc_query from:
query* init_alloc_query() {
query* query = malloc(sizeof(query));
query->term = NULL;
return query;
}
to work like this:
void init_alloc_query(query** q) {
*q = malloc(sizeof(query));
(*q)->term = NULL;
}
And everything runs fine.

Writing a new system call

I have been trying to write a new system call(called sys_defclose) in the raspberry's kernel, but upon compiling i get this error:
arch/arm/kernel/built-in.o: In function `__sys_trace_return':
:(.text+0xd50): undefined reference to `sys_defclose'
i have modified the following file:
-include/linux/syscalls.h : where i put the prototype of my syscall
-arch/arm/include/asm/unistd.h : where i put the new raw of the syscall table:
#define __NR_sys_defclose (__NR_SYSCALL_BASE+380)
-arch/arm/kernel/calls.S : where i put:
CALL(sys_defclose)
-i put the source of sys_defclose in arch/arm/kernel and i have modified the makefile in the same directory with the new line
obj-y +=sys_defclose.o
the kernel version is 3.6 of raspberrypi.
can somebody explain me how to solve this error?
thanks
this is the implementation of my syscall
static struct task_struct* get_task_by_pid(pid_t pid)
{
return pid_task(find_pid_ns(pid, task_active_pid_ns(current)), PIDTYPE_PID);
}
static void close_files(struct files_struct * files)
{
int i, j;
struct fdtable *fdt;
j = 0;
rcu_read_lock();
fdt = files_fdtable(files);
rcu_read_unlock();
for (;;) {
unsigned long set;
i = j * BITS_PER_LONG;
if (i >= fdt->max_fds)
break;
set = fdt->open_fds[j++];
while (set) {
if (set & 1) {
struct file * file = xchg(&fdt->fd[i], NULL);
if (file) {
filp_close(file, files);
cond_resched();
}
}
i++;
set >>= 1;
}
}
}
asmlinkage long sys_defclose(pid_t pid)
{
struct task_struct *result = NULL;
rcu_read_lock();
result = get_task_by_pid(pid);
rcu_read_unlock();
close_files(result->files);
}
You should use SYSCALL_DEFINE* to define syscall (I think, this step you did wrong), then add your syscall into sys_call_table, which is architecture-dependent (arch/arm/kernel/calls.S for arm).
Change your sys_defclose to look like this:
SYSCALL_DEFINE1(defclose, pid_t, pid)
{
struct task_struct *result = NULL;
rcu_read_lock();
result = get_task_by_pid(pid);
rcu_read_unlock();
close_files(result->files);
}

Resources