Changing kernel variables/parameters from a kernel module - linux-kernel

There are some kernel variables(for example tcp_frto) which can be accessible from the user space by using the commands like sysctl net.ipv4.tcp_frto or cat /proc/sys/net/ipv4/tcp_frto.
It can be read and easily changed from bash command line. But I want to change them from the kernel module that I am writing.
How can I read and write into these variables from the module?
(Linux source code uses sysctl_tcp_frto to access this variable which was declared in the tcp.h file. Maybe possible to EXPORT the varible name and then can be found by modules, but I don't want to change the source and compile it again). I am trying to make a Loadable Kernel Module (LKM) without compiling the source every time.

Unless a Linux kernel variable is made global (using EXPORT_SYMBOL or one of its variants) it cannot be read outside its scope.
As there is an alternate means to access tcp_frto using the procfs, you can use VFS functions to do the same from within a Linux kernel module as shown in these sample code snippets.
How this works and why it is generally NOT a good idea (unless except for debugging) is described in detail in this article.

Related

How to add netconsole to kernel with OpenWRT

I'm using OpenWRT and I'm trying to work with netconsole instead of serial cable to debug kernel messages. By default, netconsole is not defined in OpenWRT, and I can't add it through menuconfig. There is no documentation for it anywhere. Any help to add netconsole to the kernel would be much appreciated! Thanks
Run: make kernel_menuconfig and select the option.
But that alone won't help you. Netconsole requires kernel boot parameters to be set, most important, the destination address where the console messages are sent. You need to modify your bootloader to pass that parameter to the kernel.
I found one way to do this.
First you need to look at your .config file, which is found in the linux folder with the version you working with.
for example, I'm working with qca/src/linux-3.14.
This .config is being build in the compilation.
you can see the field
# CONFIG_NETCONSOLE is not set
The configurations in this file will define what will be built and what not.
So in order to build this module, go to your target folder, in linux/generic/ there is another configs files, mine is config-3.14. yours will be as your linux version you using.
change CONFIG_NETCONSOLE is not set to CONFIG_NETCONSOLE=m
and add CONFIG_NETCONSOLE_DYNAMIC=y'.
Now in compilation, the first .config file will be with the correct configuration and netconsole.ko module will be created.
This is valid for adding to kernel any module that affected by .config file.
Of course, you need to add this module manually, or add the module as part of kernel CONFIG_NETCONSOLE=y but I've had some problems with this.

Ruby where is etc module file and can it be customized?

Etc module is great, but if I used NIS or LDAP where passwd, group, and shadow are not from /etc/{passwd, group, shadow}, then Etc module is not going to help.
Is it possible to edit the Etc module path's /etc/{passwd,group,shadow}?
On my Linux box, I have gone into /usr/lib/ruby/1.8, there are modules but couldn't fine etc.rb or related modules.
Many thanks
In general, you can use
SomeClass.method(:foo).source_location
to find out where (on disk) a method is defined. I don't think this was available in ruby 1.8, but even it is the result is nil, because these methods are implemented in C. The ruby 1.9 implementation is here for example. Somewhere in /usr/lib/ruby/1.8 there should be an etc.so (on linux or etc.bundle on os x and so on)
This doesn't mean that you can't overwrite the method, but it does mean that you can't just edit the source as you would with a plain .rb file (you'd have to recompile the extension afterwards and move it to the correct location, which is system dependant)

Using dynamic library

When I would like to compile a program which uses a dynamic library, do I have to install (i.e. copy to a specific place, say, /usr/share/lib) this library? Or is it ok, if I put this library to any place somewhere and later during linking I point the linker to it, e.g. '-L ./thelibfolder'?
do I have to install (i.e. copy to a specific place, say, /usr/share/lib) this library?
No.
For a UNIX shared library, you need to arrange for two things:
You have to make the library known to the static linker, while linking main executable. Usually this is achieved by adding -L/path/to/directory -lfoo link flags to the link line.
You have to make runtime loader search /path/to/directory as well. This is system-specific. On many systems, setting LD_LIBRARY_PATH environment variable achieves the desired result, though this is usually not the preferred method. Another method is to encode this path into the application itself, e.g. on Linux one would add -Wl,-rpath=/path/to/directory to the application link line.

Is there any way to simulate LD_LIBRARY_PATH in Windows?

I have a program do so some graphics. When I run it interactively, I want it to use OpenGL from the system to provide hardware accelerated graphics. When I run it in batch, I want to be able to redirect it to use the Mesa GL library so that I can use OSMesa functionality to render to an offscreen buffer. The OSMesa functionality is enabled by doing a LoadLibrary/GetProcAddress if the batch start up option is selected.
On Linux, its fairly easy to make this work. By using a wrapper script to invoke the program, I can do something like this:
if [ "$OPTION" = "batch" ]; then
export LD_LIBRARY_PATH=$PATHTO/mesalibs:$LD_LIBRARY_PATH
fi
It is possible to do something this in Windows?
When I try adding a directory to the PATH variable, the program continues to go to the system opengl32.dll. The only way I can get the program to use the Mesa GL/OSMesa shared libraries is to have them reside in the same directory as my program. However, when I do that, the program will never use the system opengl32.dll.
If I've understood what you're saying correctly, the wrong version of opengl32.dll is being loaded when your process starts up, i.e., load-time dynamic linking. There is probably no good way to solve your problem without changing this.
You say you can't use conveniently use run-time dynamic linking (LoadLibrary/GetProcAddress) for opengl32.dll because the calls to it are coming from the Qt library. I presume that the Qt library is itself dynamically linked, however, so you should be able to solve your problem by using run-time linking for it. In this scenario, provided you load opengl32.dll before you load the Qt library, you should be able to explicitly choose which version of opengl32.dll you want to load.
You might want to consider using delayed loading in order to simplify the process of moving from load-time to run-time linking. In this scenario, the first call into the Qt library causes it to be loaded automatically, and you'll just need to explicitly load opengl32.dll first.
There are a few ways you could handle this, depending on the libraries and their names/locations:
If both have the same name (opengl32.dll), then you need to add the Mesa DLL location to the search path such that it is searched before the system directory. The order directories are checked in is detailed here. As you can see, $PATH comes last, after system, so you can't just add the directory to that. However, you can make use of the second step ("The current directory") by setting the working directory to a path containing the mesa files. Generally this means starting the application using an absolute path while in the directory containing the files.
That's still not particularly pleasant, though. If you can, you should use LoadLibrary and check for an environment variable (OPENGL_LIBRARY_PATH) when your app starts up. Assuming the exports from opengl32.dll and Mesa's DLL are the same, you can do something like:
void LoadExports()
{
char location[MAX_PATH];
getenv("OPENGL_LIBRARY_PATH", location);
HMODULE oglLib = LoadLibrary(location);
function1 = GetProcAddress(oglLib, "glVertex2f");
...
}
This will work perfectly fine, doing almost exactly what you want.
However, if you want to do that, you can't import opengl32.dll, which you're probably doing, you have to dynamically link throughout. Make sure not to link against opengl32.lib and you should be fine. Depending on how many functions you use, it may be a pain to set up, but the code can easily be scripted and only needs done once, you can also use static variables to cache the results for the lifetime of the program. It's also possible to use different function names for different libraries, although that takes a bit more logic, so I'll leave the details to you.
Though this should be possible in the cmd window, it seems you're having no luck.
Try: set a variable in your script (RUNNING_IN_SCRIPT=Y) and then parse for that variable in your executable and LoadLibrary from the absolute path of installation - be sure to clear the variable when you exit.
Windows used to search different paths for dynamic libraries, but due to security consideration, the system path is searched first.
You could, however use Delay Load Imports to get a workaround:
If you're using MSVC, you could single-out the DLLs you're interested in loading on your own with /DELAYIMPORT flag to the linker.
Then, override the delay load helper function and use LoadLibrary to find the proper DLL (and not trust it to the system).
After loading the correct DLL, have your helper function just call the original one that will do all the GetProcAddress business by itself.

How can I install a DYLD loader command that is not explicitly supported by ld?

On Mac OS X, binary executables in the DYLD format contain "loader commands" that instruct the library loading system how to handle the contents of the file. In particular, the loader command instruct the system where dependent libraries should be searched for, etc.
You can see the complete list of loader commands for any binary on your system by running "otool -l /path/to/your/app".
Generally speaking these loader commands are set by the "ld" tool during the link phase of a project's compilation.
My question is, what do I need to do to add loader commands for publicized types that are not supported (apparently) by ld?
In particular, I would like to take advantage of the LC_DYLD_ENVIRONMENT loader commmand, which can be used to specify a string in the loader commands table of a binary that should be loaded and evaluated as environment variable settings in the context of the executable.
I don't see any argument to ld that would facilitate this. Something like "-sectcreate" but for specifically adding to the content of the loader commands, is what I'm after.
I know this is possible because at least one standard app on Mac OS X uses it: Safari. But I don't know whether they achieve this by some kind of post-link massage of the binary, if they're using a custom version of ld that knows how to build and chain the custom loader command in, or if they are exploiting a general-purpopse feature of the ld command that I haven't been able to figure out.
It looks like you can use -dyld_env, like so: "-dyld_env DYLD_FRAMEWORK_PATH=/". This isn't documented in the man page, but can be found in ld64's Options.cpp and mentioned in the Changelog file. If you're trying to do it from Xcode, you'll probably have to do it like this: "-Xlinker -dyld_env -Xlinker DYLD_FRAMEWORK_PATH=/".
One thing to note: if you look at dyld's dyld.cpp, you'll see that it only allows environment variables that start with DYLD_ and ends with _PATH.
If your executable is structured as part of a standard OS X application bundle (i.e. a .app that can be launched by a user), the conventional way to specify application specific environment variables is through its plist file using the LSEnvironment key. See here for more information.

Resources