Can I use Linux kernel linked list outside kernel code? - linux

I want to play with kernel linked list before I use it in some part of the kernel code. But if I just include list.h, it doesn't work due to dependencies.
How can I write code using list in a single.c file e.g. test.c so that I can test my code just by compiling test.c? Looking forward to hearing from you soon.
Also, how can I use nested linked list?

You can get a userspace port from http://www.mcs.anl.gov/~kazutomo/list/list.h.
It says:
Here is a recipe to cook list.h for user space program
copy list.h from linux/include/list.h
remove
#ifdef KERNE and its #endif
all #include line
prefetch() and rcu related functions
add macro offsetof() and container_of

It is not meant to use the list in Userspace since its made for inside Kernel use and has several dependencies of kernel types and so on. You can see this by compiling your code with correct include paths:
gcc -I path-to-kernel-src/include/ test.c
When test.c contains this code:
#include <stdio.h>
#include <stdlib.h>
#include <linux/list.h>
int main(int argc, char **argv) { }
It fails to compile since there are includes in list.h which conflicts the userspace include (stdlib.h).
Nevertheless, the dependencies of such a data structures like list are pretty small. You need to sort them out in order to break the list.h dependencies from other kernel. In a short test, I removed the includes to and from list.h and added the data types struct list_head/hlist_head and hlist_node.

Related

O_DIRECT not defined on Arch LInux

I'm trying to write some low latency disk access code. The issue is that the library I'm using has the following code:
#ifdef O_DIRECT
int flags = O_DIRECT;
#else
int flags = 0;
#endif
and my installation doesn't have O_DIRECT defined.
I've confirmed this via this simple program:
#include <stdio.h>
int main(void){
#ifdef O_DIRECT
printf("O_DIRECT");
#else
printf("Otherwise");
#endif
}
Which prints Otherwise.
So the question is why is this not defined? And additionally how to resolve this?
The macro is actually defined in <fcntl.h>, not stdio.h.
Second, to access the definition, you need to #define _GNU_SOURCE as it is Linux-specific. Note that the definition must go before any libc header includes, not just before fcntl.h.

Controlling the memory map of another process

Is it possible, somehow, to change the memory map of another process in Linux? As opposed, that is, to only being able to control it by way of code running in the process itself calling mmap.
The reason I'm asking is because I'd like to be able to build a process with a very custom memory map, and without being able to use shared libraries or even the vDSO, I don't see any way to do that inside the process itself that does not involve basically writing my own libc to handle syscalls and such. (Even if I were to link libc statically, wouldn't it attempt to use the vDSO?)
mmap mapped memory is preserved by fork but wiped by system calls from the exec family, therefore this can't be acheived by the classic sequence fork, setup stuff then exec.
A simple solution is to use an LD_PRELOAD hook. Let's place this code in add_mmap.c.
#include <sys/mman.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void add_mmap(void) __attribute__((constructor));
void add_mmap(void)
{
int fd;
void *addr;
printf("calling mmap() before main...\n");
fd = open("/etc/passwd", O_RDONLY);
printf("fd=%d\n", fd);
/* map the first 100 bytes of the file to an address chosen by the kernel */
addr = mmap(0, 100, PROT_READ, MAP_SHARED, fd, 0);
printf("addr=%llx\n", (long long unsigned)addr);
}
Then, build it as a dynamic library:
gcc -Wall -g -fPIC -shared -o add_mmap.so add_mmap.c
And finally run some existing program with it:
$ LD_PRELOAD=./add_mmap.so /bin/cat
calling mmap() before main...
fd=3
addr=7fe4916f8000
We can check that the mapping was set up and preserved before cat was run:
$ cat /proc/27967/maps
...
7f2f7f2d0000-7f2f7f2d1000 r--s 00000000 09:00 1056387 /etc/passwd
...
EDIT
I only show here how to add a memory mapping before the program starts, but my example can be easily extended to transparently inject a "memory manger" thread inside the program. This thread would receive orders through an IPC mechanism like a socket and manipulate the mappings accordingly.

Using <linux/types.h> in user programs, or <stdint.h> in driver module code...does it matter?

I'm developing a device driver module and associated user libraries to handle the ioctl() calls. The library takes the pertinent info and puts it into a struct, which gets passed into the driver module and unpacked there and then dealt with (I'm omitting a lot of steps, but that's the overall idea).
Some of the data being passed through the struct via the ioctl() is uint32_t type. I've discovered that that type is defined in <stdint.h> AND <linux/types.h>. So far I've been using <linux/types.h> to define that value, including down in the user libraries. But I understand it is bad form to use <linux/*.h> libraries in user space, so if I remove those and use <stdint.h> instead, then when my driver module includes the struct definition, it will have to be including <stdint.h> also.
It seems to me that the point of <linux/types.h> is to define types in kernel files, so I'm not sure if that means using <stdint.h> is bad idea there. I also found that when trying to compile my driver module with <stdint.h>, I get compilation errors about redefinitions that won't go away, even if I replace all instances of <linux/types.h> with <stdint.h> (and put it on the top of the include order).
Is it a bad idea to use linux/*.h includes in user-space code?
Is it a bad idea to use <stdint.h> in kernel-space code?
If the answers to both of those is yes, then how do I handle the situation where a structure containing uint32_t is shared by both the user library and the driver module?
Is it a bad idea to use linux/*.h includes in user-space code?
Yes, usually. The typical situation is that you should be using the C-library headers (in this case, stdint.h and friends), and interface with the C library though those user-space types, and let the library handle talking with the kernel through kernel types.
You're not in a typical situation though. In your case, you're writing the driver library. So you should be presenting an interface to userspace using stdint.h, but using the linux/*.h headers when you interface to your kernel driver.
So the answer is no, in your case.
Is it a bad idea to use stdint.h in kernel-space code?
Most definitely yes.
See also: http://lwn.net/Articles/113349/
Fixed length integers in the Linux kernel
The Linux kernel already has fixed length integers which might interest you. In v4.9 under include/asm-generic/int-ll64.h:
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
LDD3 has a chapter about data sizes as well: https://static.lwn.net/images/pdf/LDD3/ch11.pdf
LDD3 mentions there that the best printk strategy is to cast to just cast to the largest integer possible with correct signedness: %lld or %llu. %ju appears unavailable under the printk formatting centerpiece lib/linux/vsprintf.c.

How to make OpenGL program run on Graphics Card by C++ MFC? [duplicate]

For Intel+NVIDIA dual-GPU "Optimus" setups, an application can export NvOptimusEnablement as explained in OptimusRenderingPolicies.pdf. This option allows an application to ensure the use of the high-speed discrete GPU without needing profile updates or user interaction, which is usually desired for certain classes of applictions.
Is there an equivalent trick for systems with AMD GPUs (Windows-only is fine), and if so, what is it? I have not been able to find any concrete information via Googling; only a lot of people asking the same question on various forums with no answers, or SO articles on the NVIDIA trick with a "maybe AMD has something similar, I don't know" comment.
According to https://community.amd.com/thread/169965
extern "C"
{
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
This will select the high performance GPU as long as no profile exists that assigns the application to another GPU.
Please make sure to use a 13.35 or newer driver. Older drivers do not support this.
This code will be ignored when you compile on non-windows machines:
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif

Setting the thread /proc/PID/cmdline?

On Linux/NPTL, threads are created as some kind of process.
I can see some of my process have a weird cmdline:
cat /proc/5590/cmdline
hald-addon-storage: polling /dev/scd0 (every 2 sec)
Do you have an idea how I could do that for each thread of my process? That would be very helpful for debugging.
If you want to do this in a portable way, something that will work across multiple Unix variations, there are very few options available.
What you have to do is that your caller process must call exec with the argv [0] argument pointing to the name that you would like to see in the process output, and the filename pointing to the actual executable.
You can try this behavior from the shell by using:
exec -a "This is my cute name" bash
That will replace the current bash process with one named "This is my cute name".
For doing this in C, you can look at the source code of sendmail or any other piece of software that has been ported extensively and find all the variations that are needed across operating systems to support this.
Some operating systems have a setproctitle(3) API, some others allow you to override the contents of argv [0] and show that result.
argv points to writable strings. Just write stuff to them:
#include <string.h>
#include <unistd.h>
int
main(int argc, char** argv)
{
strcpy(argv[0], "Hello, world!");
sleep(10);
return 0;
}
Bah.. the code is not that nice, the trick is to reuse the environ (here argv_buffer) pointer:
memset (argv_buffer[0] + len, 0, argv_size - len);
argv_buffer[1] = NULL;
Any better idea?
Is that working for different threads?

Resources