C & Android kernel module: what happened with f_flags here? - android

I have a self-coded kernel module in Android which I open with O_RDONLY|O_NONBLOCK.
O_NONBLOCK is 2048 in both the user-program and the kernel module.
I checked that with
print..("O_NONBLOCK is %d", O_NONBLOCK)
in user- & kernel-space.
But now, when I try to check if O_NONBLOCK was set, I got a really strange problem:
static int my_open(struct inode *inode, struct file *filp) {
if (filp->f_flags & O_NONBLOCK) {
printk("O_NONBLOCK");
} else {
printk("NOT O_NONBLOCK");
printk("O_NONBLOCK in my_open is: %d", O_NONBLOCK); // -> prints 2048
printk("filp->f_flags in my_open is: %d", filp->f_flags); // -> prints 1, not 2048 or larger
}
..
}
I tried something else:
cat my_device
but again, filp->f_flags is 1.
I would assume maybe 0 for O_RDONLY but not 1 which means O_WRONLY.
Anyone an idea or explanation?
EDIT:
I also don't expect cat beeing O_NONBLOCK, but O_WRONLY is totally wrong.
I open it this way:
pcm->dfd=open(fname, O_RDONLY|O_NONBLOCK);
and there's no fcntl later (and that shouldn't affect my_open at all.
But of course I also tried to "re-set" O_NONBLOCK with fcntl without luck.

You need to make sure that the userspace, indeed, passes what you think it must be passing. I find it hard to believe, for example, that "cat" would pass "NONBLOCK". It has no reason to.
Use strace on the userspace end to test what actually gets passed in.
Also, and a bit offtopic, are you sure you care whether O_NONBLOCK is set during open? Please remember that it may also be set using fcntl later on.
Shachar

Related

What is the purpose of using double underscore ( __ ) before the start and after the end of an file name in c?

I'm studying the android kernel as a beginner. I can read the messages thrown from the macro ERROR() inside the function main() at system/core/init/init.c using dmesg command through adb. I observed that after calling the function open_devnull_stdio() inside main(), dmesg no longer displays the messages thrown by ERROR().
To find the reason, I started digging into the declaration of open_devnull_stdio() inside system/core/init/util.c and I found this line I can't understand
static const char *name = "/dev/__null__";
Actually there was no file named __null__ inside /dev/ in the device, but there was a file named null and I was able to grab it using adb pull and it was a 0 byte (empty) file.
So why is a file name wrapped with double underscore (__) ?
Here is the link for the util.c
There is no special purpose of using double underscore before the start, after the end or both in C. From the point of view of C the file name is just a string, the operating system is free to interpret in whatever way it chooses. From the point of view of Linux, the same applies. Underscores in file names are just characters. They are not treated differently from the letters b and t.
If I guessed right and I'm reading the same file as you (it might be a good idea to link to the source code you're reading) then it should be pretty obvious what the code does on the lines after the one you mentioned. The next lines are:
if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
fd = open(name, O_RDWR);
unlink(name);
Which creates the null device which is then opened and immediately deleted again.
I suspect this is done so that programs can run without access to the root filesystem and still be able to open the equivalent of /dev/null.
I don't know the answer but I have an idea:
The following page shows an "strace" output where /dev/__null__ is used:
https://gist.github.com/tetsu-koba/1522515
Under Linux device files have a 33-bit (?) number which identifies the device. (At least under old Linux versions) you could delete some file in /dev and you could restore it or even create it in another directory (!) when you know the 33-bit number! (So you can delete the device /dev/sda2 and create the device (not file!) /home/myuser/sda2 instead.)
The trace in the link above shows the following three lines:
mknod("/dev/__null__", S_IFCHR|0600, makedev(1, 3)) = 0
open("/dev/__null__", O_RDWR|O_LARGEFILE) = 3
unlink("/dev/__null__") = 0
These lines will create the device file /dev/__null__ (with the 33-bit number identifying /dev/null). Then it opens that file and then it removes the file again.
Maybe this is done because the tool shall be able to run both on Linux installations where the device file "/dev/null" is present (in this case the file should not be overwritten) and on installations where that file is missing (in this case a replacement file must be created using the known 33-bit number).
As other people have pointed out this just tells it's the "null device", not a regular file called "null". null is supposed to act like an information sink, not like a normal file where you dump your data to. Hope this helps.

error with pymtp to work on python 3

I want to access a android device from python to download some photos.
libmtp works from the CLI.
Than pymtp. It's been around for a while but it's designed for python 2 and i'm using python 3. Meanwhile fixed several minor issues but i'm stuck at an error from function get_filelisting
specially this section:
ret = []
next = files
while next:
ret.append(next.contents)
if (next(next.contents) is None):
break
next = next(next.contents)
The error is related to the "next".
That section looks strange to me, i've been coding in python for a while but i'm new to ctypes. Tried a lot of variants, they all failed. The "next" could be confusing with python buildin function so i renamed it to nextpointer and came to this code:
ret = []
nextpointer = files
while nextpointer:
ret.append(nextpointer.contents)
nextpointer = nextpointer.contents.next
It seems to work but did it work by accident ? does it have any design flaws ? Could anyone with experience on python ctypes confirm this a solution ? Any suggestion welcome.
From python2.7 documentation
next(iterator[, default])
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is
exhausted, otherwise StopIteration is raised.
from python3 documentation
next(iterator[, default])
Retrieve the next item from the iterator by calling its __next__() method. If default is given, it is returned if the iterator is
exhausted, otherwise StopIteration is raised.
Notice that next() method was removed from python3 but the function still exists.
This is all I can say about the next function and .next()/__next__() methods.
I downloaded the pymtp module and get_filelisting() is slightly different from what you posted in your ported code, here it is:
ret = []
next = files
while next:
ret.append(next.contents)
if (next.contents.next == None):
break
next = next.contents.next
If none of this helped you (which probably didn't :D), the version of pymtp library that I am using is 0.0.6 download using pip.

why just after initializing the zram read is issued before write?

I am newbie to Linux kernel and just started to know how zram works. Initial testing, I am seeing that READ is issued before WRITE just after the zram is being initialized. But I am just eager to know, why this is so ?
As an activity I took the dump_stack() and followed the path form where to how this zram read is being performed.
zram get to know this info whether it has to do READ or WRITE operation on issued bio->bi_rw. Code flow is like that zram_make_request API is being called from create_device in zram driver. And zram_make_request internally called __zram_make_request which called the zram_bvec_rw API.
In zram_bvec_rw API check the available info of bio->bi_rw and correspondingly issued the READ and WRITE call.
Now, in this case what is happening: READ is being encapsulated inside bio struct itself. As triage I found that submit_bh fills all the entry of bio and issued the submit_bio.
I was wondering who is actually sets the bio->bi_rw as READ. By enabling the few prints I found that ll_rw_block API is being called by __block_write_begin with READ, later ll_rw_block calls the submit_bh API where rest of bio struct entries are filled.
But I am still not getting the answer why READ is issued for ll_rw_block from __block_write_begin ?
zram driver:
https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/block/zram/zram_drv.c?id=refs/tags/v3.18.14
in file: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/fs/buffer.c?id=refs/tags/v3.18.14
if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
!buffer_unwritten(bh) &&
(block_start < from || block_end > to)) {
ll_rw_block(READ, 1, &bh);
*wait_bh++=bh;
}
buffer_uptodate(bh), /* Contains valid data */
buffer_delay(bh), /* Buffer is not yet allocated on disk */
buffer_unwritten(bh), /* Buffer is allocated on disk but not written */
Please can someone give an explaination/answer to my question ?
How I am concluding that read is perfomed before write ??
I just check the num_reads and num_writes count. And num_reads count is set to 1 while num_writes is found 0 when we do mkswap /dev/block/zram0 and after calling the swapon /dev/block/zram0 the final counts are num_reads = 2 and num_writes=1.
NOTE: This is the case when we don't performing any additional zram activity. We got this behavior in case as explained above.
Because of this as far as i can see: block_start < from || block_end > to (respecting other conditions of course, buffer_uptodate() etc.) .
i.e. bio will write a whole block so if a region to be updated smaller than submited block you obviously need a fresh copy.

What is the 'export GST_DEBUG=<#>' equivalent for Android?

On Linux systems I've used 'export GST_DEBUG=<#>' to debug problems with a program's use of GStreamer. I'm now working on Android and would like to do the same - see the GStreamer output included in the logcat output.
I have a Google Nexus 5 phone and I'm using the full_hammerhead_userdebug build. I've seen the following suggested:
Add the following in JNI_OnLoad:
setenv("GST_DEBUG", "*:5", 1);
setenv("GST_DEBUG_NO_COLOR", "1", 1);
Unfortunately I'm trying to debug a C library, so I would prefer to set something in the environment to enable the debug output. I tried to add the following lines to build.prop:
export GST_DEBUG=3
GST_DEBUG=3
log.redirect-stdio=true
That didn't work. Either I'm not enabling GST_DEBUG properly or I'm not redirecting it properly. Or I'm way off track and I should be doing something else. How can I enable GST_DEBUG with Android?
P.S. This question is similar to one, but that one didn't completely answer my question.
I ended up going in another direction to solve this problem. First I created my own GstLogFunction()
void gstAndroidLog(GstDebugCategory * category,
GstDebugLevel level,
const gchar * file,
const gchar * function,
gint line,
GObject * object,
GstDebugMessage * message,
gpointer data)
{
if (level <= gst_debug_category_get_threshold (category))
{
__android_log_print(ANDROID_LOG_ERROR, "MY_APP", "%s,%s: %s",
file, function, gst_debug_message_get(message));
}
}
Then after gst_init() is called, I set up the log levels. If I want to see everything, I can set:
gst_debug_set_default_threshold( GST_LEVEL_DEBUG );
If I just want to see what is happening in a specific category, I can set:
gst_debug_set_threshold_for_name ("tcpclientsink", GST_LEVEL_LOG);
Then I just need to register the log function I created:
gst_debug_add_log_function(&gstAndroidLog, NULL);

Android display OpenCore logs

I am trying to display opencore logs. I have already tried the ff. but still logs are not showing in the logcat.
1. created pvlogger.txt in sdcard and still no use.
# echo 8 > /sdcard/pvlogger.txt
2. Edited the PV_LOG_INST_LEVEL from 0 to 5 in the pvlogger.h file but it causes the compilation to fail.
"/android_log_appender.h:75: error:" format not a string literal and no format argument"
So I have just commented out Line 75, although it compiled successfully, opencore logs are still not showing in the logcat.
Is there anyone who were able to display the opencore logs?
Thanks in advance.
artsylar
I had this issue three months ago. Please don't comment out LOGE(stringbuf) in /android_log_appender.h, otherwise there is no log out.
LOGE("%s", stringbuf) instead of LOGE(stringbuf).
1. created pvlogger.txt in sdcard and still no use.
`# echo 8 > /sdcard/pvlogger.txt`
2. Edited the PV_LOG_INST_LEVEL from 0 to 5 in the pvlogger.h.
3. ENABLE_PV_LOGGING from 0 to 1 in the pvlogger.h.
4. LOGE("%s", stringbuf) instead of LOGE(stringbuf) in /android_log_appender.h.
Wish you success!
After trial and errors, I was finally able to show the OpenCore log messages! Here's what I did although I do not know yet if steps 4 and make options are needed.
Added #define PV_LOG_INST_LEVEL 5 to \android\external\opencore\android\thread_init.cpp file.
To solve the "/android_log_appender.h:75: error:" format not a string literal and no format argument" error, just edit \external\opencore\android\android_log_appender.h line 75 from LOGE(stringbuf) to LOGE("%s", stringbuf)
compile the code.
make ENABLE_PV_LOGGING=1
create pvlogger.txt in sdcard.
# echo 8 > /sdcard/pvlogger.txt

Categories

Resources