Deleting a sysfs entry - linux-kernel

i was trying to learn sysfs and was trying to write a simple sysfs directory. The code is as below
static struct kobject *example_kobject;
static int __init mymodule_init (void)
{
pr_debug("Module initialized successfully \n");
example_kobject = kobject_create_and_add("kobject_example",
kernel_kobj);
if(!example_kobject)
return -ENOMEM;
return 0;
}
static void __exit mymodule_exit (void)
{
pr_debug ("Module un initialized successfully \n");
// kobject_put(example_kobject); <-- Forgot to delete
}
module_init(mymodule_init);
module_exit(mymodule_exit);
As shown in the mymodule_exit, i had by mistake forgot to uncomment the code and then inserted and rmmod the module.
Now when i try to insert the module again, the initialization is failing as the entry is already present.
I know, it does not make sense to allow userspace to remove the entry that the kernel made. But, i was still wondering if there is any other way to remove the particular /sys/kernel/kobject_example entry other than rebooting the box.

Firstly, merely doing kobject_put() is not good enough, you must use kobject_del() instead. kobject_put() does not do complete clean-up. In your case, since kobject_example is a file (not dir), mere 'put' will still leave the entry in the parent dir (kset).
If you must, there is a away to remove such an entry without reboot, and that is by writing another module to do that. Here is what the module should be doing:
/* Find the kobj from the path and parent kset */
kobj = kset_find_obj(kernel_kobj->kset, "kobject_example");
...
/* check kobj is not null etc. */
...
/* Remove the sysfs entry */
kobject_del(kobj);
This will delete the sysfs entry. Reboot is easy, but this is nifty when your system does not have an option to go out of service.

Related

mapping a memory region from kernel

I have a register which needs to be accessed from more then one driver.
It is a global read-only register resides in FPGA space
The register address is exported via device tree.
The first call to "request_mem_region" is ok, but any consecutive call fails.
Is there a way to share a register between drivers ?
Linux Kernel release is 4.14 , using petalinux
Thanks,
Ran
You need to remap the memory region with something like ioremap() after you have requested it.
Then, as Tsyvarev and others mentioned, create and export a function in your "parent" driver that returns the mapped memory.
Here is some rough code:
void * mapped_mem;
void * map_addr(unsigned int phy_addr, char * name) {
struct resource * resource;
void * mapped_mem;
resource = request_mem_region(phy_addr, page_size * 4, name);
// check for errors
mapped_mem= ioremap_nocache(phy_addr, page_size * 4);
// check for errors
return mappedMem;
//handle errors
}
void * get_mapped_addr(void) {
return mapped_mem
}
EXPORT_SYMBOL( get_mapped_addr);
Now, mapped_mem should actually be tracked as part of your devices private info, but I figure thats beyond the scope of the question. Also, make sure to check for all possible errors. Make sure that request_mem_region() returns something >0 and not Null.

C++(Visual Studio 2012): Copying a function's parameter char* to a dynamically allocated one

I have this structure defined and a class in my project. It is a class that holds id numbers generated by GetIdUsingThisString(char *), which is a function that loads a texture file into GPU and returns an id(OpenGL).
The problem is, when I try to read a specific file, the program crashes. When I run this program in VS with debugging it works fine, but running .exe crashes the program(or running without debugging from MSVS). By using just-n-time debugger I have found out that, for num of that specific file, Master[num].name actually contains "\x5" added(concatenation) at the end of the file path, and this is only generated for this one file. Nothing out of this method could do it, and I also use this type of slash / in paths, not \ .
struct WIndex{
char* name;
int id;
};
class Test_Class
{
public:
Test_Class(void);
int AddTex(char* path);
struct WIndex* Master;
TextureClass* tex;
//some other stuff...
};
Constructor:
Test_Class::Test_Class(void)
{
num=0;
Master=(WIndex*)malloc(1*sizeof(WIndex));
Master[0].name=(char*)malloc(strlen("Default")*sizeof(char));
strcpy(Master[0].name,"Default");
Master[0].id=GetIdUsingThisString(Master[0].name);
}
Adding a new texture:(The bug)
int Test_Class::AddTex(char* path)
{
num++;
Master=(WIndex*)realloc(Master,(num+1)*sizeof(WIndex));
Master[num].name=(char*)malloc(strlen(path)*sizeof(char));
strcpy(Master[num].name,path);<---HERE
Master[num].id=GetIdUsingThisString(path);
return Master[num].id;
}
At runtime, calling AddTex with this file would have path with the right value, while Master[num].name will show this modified value after strcpy(added "\x5").
Question:
Is there something wrong with copying(strcpy) to a dynamically allocated string? If i use char name[255] as a part of the WIndex structure, everything works fine.
More info:
This exact file is called "flat blanc.tga". If I put it in a folder where I intended it to be, fread in GetIdUsingThisString throws corrupted heap errors. If I put it in a different folder it is ok. If I change it's name to anything else, it's ok again. If I put a different file and give it that same name, it is ok too(!!!). I need the program to be bug free of this kind of things because I won't know which textures will be loaded(if I knew I could simply replace them).
Master[num].name=(char*)malloc(strlen(path)*sizeof(char));
Should be
Master[num].name=(char*)malloc( (strlen(path)+1) * sizeof(char));
There was not place for the terminating NULL character
From http://www.cplusplus.com/reference/cstring/strcpy/:
Copies the C string pointed by source into the array pointed by
destination, including the terminating null character (and
stopping at that point).
The same happens here:
Master[0].name=(char*)malloc(strlen("Default")*sizeof(char));
strcpy(Master[0].name,"Default");
Based on the definitions (below) - you should use strlen(string)+1 for malloc.
A C string is as long as the number of characters between the beginning of the string and the terminating null character (without including the terminating null character itself).
The strcpy() function shall copy the string pointed to by s2 (including the terminating null byte)
Also see discussions in How to allocate the array before calling strcpy?

Ptrace: IMG load detector

How can I detect IMG load? Im trying to detect when the program is loaded into memory in order to put interrupts before each function. I'm trying to do something like PIN's IMG_AddInstrumentFunction.
I'm lost and I can't found info about it.
Thx
This is exactly what r_brk is for. See include/link.h:
struct r_debug
{
.....
/* This is the address of a function internal to the run-time linker,
that will always be called when the linker begins to map in a
library or unmap it, and again when the mapping change is complete.
The debugger can set a breakpoint at this address if it wants to
notice shared object mapping changes. */
ElfW(Addr) r_brk;
....
};
They even go on and explain how to find this value in the debugee:
/* This symbol refers to the "dynamic structure" in the `.dynamic' section
of whatever module refers to `_DYNAMIC'. So, to find its own
`struct r_debug', a program could do:
for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
if (dyn->d_tag == DT_DEBUG)
r_debug = (struct r_debug *) dyn->d_un.d_ptr;
*/

How to convert between shared_ptr<FILE> to FILE* in C++?

I am trying to use a FILE pointer multiple times through out my application
for this I though I create a function and pass the pointer through that. Basically I have this bit of code
FILE* fp;
_wfopen_s (&fp, L"ftest.txt", L"r");
_setmode (_fileno(fp), _O_U8TEXT);
wifstream file(fp);
which is repeated and now instead I want to have something like this:
wifstream file(SetFilePointer(L"ftest.txt",L"r"));
....
wofstream output(SetFilePointer(L"flist.txt",L"w"));
and for the function :
FILE* SetFilePointer(const wchar_t* filePath, const wchar_t * openMode)
{
shared_ptr<FILE> fp = make_shared<FILE>();
_wfopen_s (fp.get(), L"ftest.txt", L"r");
_setmode (_fileno(fp.get()), _O_U8TEXT);
return fp.get();
}
this doesn't simply work. I tried using &*fp instead of fp.get() but still no luck.
You aren't supposed to create FILE instances with new and destroy them with delete, like make_shared does. Instead, FILEs are created with fopen (or in this case, _wfopen_s) and destroyed with fclose. These functions do the allocating and deallocating internally using some unspecified means.
Note that _wfopen_s does not take a pointer but a pointer to pointer - it changes the pointer you gave it to point to the new FILE object it allocates. You cannot get the address of the pointer contained in shared_ptr to form a pointer-to-pointer to it, and this is a very good thing - it would horribly break the ownership semantics of shared_ptr and lead to memory leaks or worse.
However, you can use shared_ptr to manage arbitrary "handle"-like types, as it can take a custom deleter object or function:
FILE* tmp;
shared_ptr<FILE> fp;
if(_wfopen_s(&tmp, L"ftest.txt", L"r") == 0) {
// Note that we use the shared_ptr constructor, not make_shared
fp = shared_ptr<FILE>(tmp, std::fclose);
} else {
// Remember to handle errors somehow!
}
Please do take a look at the link #KerrekSB gave, it covers this same idea with more detail.

Conditional compiling/linking with gcc

I have scientific simulation code written in C that runs from the command line. The user provides an input model as a set of C subroutines in a model.c file that are then compiled into code at runtime.
Certain model properties are not always relevant for a specific problem but currently the user still needs to provide an empty dummy function for that property in order for the code to compile.
Is it possible to have dummy subroutines for the model properties embedded in the source code that are linked only if the user-provided model.c does not contain a subroutine for that property?
As an example, if model.c contains a subroutine called temperature(), the code should link to that one, rather than the subroutine called temperature() found in src/dummy_function.c. If model.c does not have temperature() the compiler should use the dummy function in src/dummy_function.c.
If possible, I would prefer a solution that does not require preprocessor directives in the model.c file.
Yes you can. Suppose you have simple code in file, say undesym.c:
int
main(void)
{
user_routine();
return 0;
}
Create weak stub in say file fakeone.c
#include "assert.h"
int __attribute__((weak))
user_routine(void)
{
assert(0 == "stub user_routine is not for call");
return 0;
}
Now create "user" function in, say goodone.c
#include "stdio.h"
int
user_routine(void)
{
printf("user_routine Ok\n");
return 0;
}
Now if you will link together gcc undesym.c fakeone.c then a.out will run to assert, but if you will add goodone.c to compilation, like gcc undesym.c fakeone.c goodone.c, then it will prefer strong definition to weak, and will run to message.
You may adopt the same mechanism, defining default functions weak.
Since you say that the user's subroutines are "compiled into the code at runtime", you could use dynamic linking to load a user-provided binary and look for their entry points at runtime. In linux (or any POSIX system), this would be based on dlopen()/dlsym() and look more or less like this:
#include <dlfcn.h>
/* ... */
/* Link the UserModule.so into the executable */
void *user_module = dlopen("UserModule.so", RTLD_NOW);
if (!user_module) {
/* Module could not be loaded, handle error */
}
/* Locate the "temperature" function */
void *temperature_ptr = dlsym(user_module, "temperature"):
if (!temperature_ptr) {
/* Module does not define the "temperature" function */
}
void (*user_temperature)() = (void(*)())temperature_ptr;
/* Call the user function */
user_temperature();
See the dlopen documentation for details. A similar facility is very likely available in whatever OS you're using.

Resources