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

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.

Related

How to get a full android app UID programmatically?

Edit 10 Apr 2020
I may have misnamed what we are looking for. It may actually be the linux user name of the installed app, rather than its UID. So how should we get that programmatically?
Original question below
When we use adb shell ps even on a non rooted android device, it returns process info where the UID comes in the form u0_xxxx where x represents some arbitrary digits in hex (except for system/root processes).
For example
u0_a464 31481 894 5015336 69200 0 0 S com.example.app_uid_checker
In this example app_uid_checker is my app in user space. When trying to obtain the UID programmatically, though, I get 10464 (the decimal representation of a464), and without the u0 prefix.
I tried
package manager's getApplicationInfo()
activity manager's getAllRunningProcess()
android.os.Process.myUid()
(following suggestions in this post on SO. They all return 10464. How can I get the "full" UID? (for want of a better term, I'm not sure what the u0_a464 version of the UID should be called, as compared to the 10464 version)).
Even if we can programmatically use adb shell ps I think it may not be a good way, as adb needs developer mode to be enabled.
You need to use the geteuid(2) and getpwuid(3) to retrieve the data, as the JVM does not expose it.
extern "C" JNIEXPORT jstring JNICALL Java_com_example_GetUser_getUser(JNIEnv* env) {
uid_t uid = geteuid();
struct passwd *user;
if (uid == -1)
return NULL;
user = getpwuid(uid);
return env->NewStringUTF(user->pw_name);
}
Full working project: https://gitlab.com/hackintosh5/getuser

Obtaining data from my TP-Link router programmatically

I'm trying to design an app that can communicate with my router programmatically using the same endpoints as the web interface (there's a demo on TP-Link's website). My router is a TP-Link TD-W8980, if that matters.
The format appears to be very difficult to decipher. Here is a request which obtains the data for the status part of my app. This can obtain a valid response from the router but I'm not sure why!
I'm especially confused by the #0,0,0,0,0,0#0,0,0,0,0,0] part of the response. It's the only part I haven't managed to work out but I think I recall reading it's to do with the stack?!?
[SYS_MODE#0,0,0,0,0,0#0,0,0,0,0,0]0,1
mode
[LAN_HOST_CFG#1,0,0,0,0,0#0,0,0,0,0,0]1,1
DNSServers
[WAN_DSL_INTF_CFG#1,0,0,0,0,0#0,0,0,0,0,0]2,8
upstreamCurrRate
downstreamCurrRate
upstreamMaxRate
downstreamMaxRate
upstreamNoiseMargin
downstreamNoiseMargin
upstreamAttenuation
downstreamAttenuation
[IGD_DEV_INFO#0,0,0,0,0,0#0,0,0,0,0,0]3,3
softwareVersion
hardwareVersion
upTime
[LAN_IP_INTF#0,0,0,0,0,0#0,0,0,0,0,0]4,2
IPInterfaceIPAddress
X_TPLINK_MACAddress
[LAN_HOST_ENTRY#0,0,0,0,0,0#0,0,0,0,0,0]5,4
leaseTimeRemaining
MACAddress
hostName
IPAddress
[WAN_PPP_CONN#0,0,0,0,0,0#0,0,0,0,0,0]6,4
enable
connectionStatus
externalIPAddress
DNSServers
If it helps, the names in capitals (e.g. SYS_MODE) is the name of the section. The number after the ] is a counter stating the section number (sections can be in any order). The final number following the , is the number of parameters that follow in this section.
There are also request types for each section. In the example above, the URL is http://192.168.1.1/cgi?1&1&1&1&5&5&5. As you can see the two main request types are 1 and 5.
Here is an example response from the server. As you can see, some of the sections can be returned more than once, which makes the first number of the six zeros increment each time.
[0,0,0,0,0,0]0
mode=DSL
[1,0,0,0,0,0]1
DNSServers=x.x.x.x,x.x.x.x
[1,0,0,0,0,0]2
upstreamCurrRate=928
downstreamCurrRate=3072
upstreamMaxRate=1068
downstreamMaxRate=3104
upstreamNoiseMargin=60
downstreamNoiseMargin=57
upstreamAttenuation=295
downstreamAttenuation=546
[0,0,0,0,0,0]3
softwareVersion=0.6.0 1.3 v000e.0 Build 131012 Rel.51720n
hardwareVersion=TD-W8980 v1 00000000
upTime=x
[1,1,0,0,0,0]4
IPInterfaceIPAddress=192.168.1.1
X_TPLINK_MACAddress=xx:xx:xx:xx:xx:xx
[1,0,0,0,0,0]5
leaseTimeRemaining=-1
MACAddress=xx:xx:xx:xx:xx:xx
hostName=X
IPAddress=192.168.1.2
[2,0,0,0,0,0]5
leaseTimeRemaining=-1
MACAddress=xx:xx:xx:xx:xx:xx
hostName=X
IPAddress=192.168.1.4
[3,0,0,0,0,0]5
leaseTimeRemaining=-1
MACAddress=xx:xx:xx:xx:xx:xx
hostName=X
IPAddress=192.168.1.11
[4,0,0,0,0,0]5
leaseTimeRemaining=-1
MACAddress=xx:xx:xx:xx:xx:xx
hostName=X
IPAddress=192.168.1.5
[1,2,1,0,0,0]6
enable=1
connectionStatus=Connected
externalIPAddress=x.x.x.x
DNSServers=x.x.x.x,x.x.x.x
[2,1,1,0,0,0]6
enable=0
connectionStatus=Unconfigured
externalIPAddress=0.0.0.0
DNSServers=0.0.0.0,0.0.0.0
[3,1,1,0,0,0]6
enable=0
connectionStatus=Unconfigured
externalIPAddress=0.0.0.0
DNSServers=0.0.0.0,0.0.0.0
[error]0
I would appreciate any explanation of this format and if it appears anywhere else on the web. I've never seen such a system before!

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.

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

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

Android SSLEngine example

I need to work with a TCP socket over TLS for an app I'm working on. I've been through dozens of examples and while I have no problem getting through the handshake, I can't seem to read the input stream through any means (tried a lot, including readline(), reading to character array, etc). every time I try, the app freezes on that spot. If I debug, it never goes to the next line of code.
In an attempted solution, I decided to move over to using an SSLEngine, since that's supposed to be the Java 1.5 answer to java.nio for SSL. However, I have found one example (here: http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/samples/sslengine/SSLEngineSimpleDemo.java) which is more than a little confusing to me, and I've not been successful implementing it. When I try, the unwrap() call yields an empty buffer, where I know (from using OpenSSL on the command line) that the service in question pushes data back down the pipe.
Suggestions are welcome, I've burned way too much time on this already. Here's the relevant code:
SSLEngine engine = sslContext.createSSLEngine(uri.getHost(), uri.getPort());
engine.setUseClientMode(true);
engine.beginHandshake();
SSLSession session = engine.getSession();
int bufferMax = session.getPacketBufferSize();
int appBufferMax = session.getApplicationBufferSize() + 50;
ByteBuffer cTo = ByteBuffer.allocateDirect(bufferMax);
ByteBuffer sTo = ByteBuffer.allocateDirect(bufferMax);
ByteBuffer out = ByteBuffer.wrap(sessionId.getBytes());
ByteBuffer in = ByteBuffer.allocate(appBufferMax);
debug("sending secret");
SSLEngineResult rslt = engine.wrap(out, cTo);
debug("first result: " + rslt.toString());
sTo.flip();
rslt = engine.unwrap(sTo, in);
debug("next result" + rslt.toString());
This implementation is missing some key pieces. Namely the handshake can bounce between several states NEED_WRAP, NEED_UNWRAP, NEED_TASK to negotiate a connection. This means you cannot just call one and then the other. You will need to loop over the states until a handshake has completed.
while (handshaking) {
switch (state) {
case NEED_WRAP:
doWrap();
break;
case NEED_UNWRAP:
doUnwrap();
break;
case NEED_TASK:
doTask();
break;
}
}
A full working example of Java SSL and NIO
Now that said, you should be aware the SSLEngine on Android is broken. Google recommends using threads and blocking sockets according to that thread.
I have written something to make using SSLEngine easier. It can be used with NIO or for other use cases. Available here SSLFacade
unwrap() can yield an empty buffer if what was unwrapped was an SSL handshake message or alert, rather than application data. There's not enough information here to say more. What was the engine status afterwards?
beginHandshake does not proceed the handshake, it is just used to inform the SSLEngine that you want to perform the handshake for the next calls to wrap/unwrap.
It's useful when you want to do another handshake. For the initial one, it is not needed as the first call to wrap will initiate the handshake.
Besides, you have to check the result of the wrap and unwrap methods to know if all the data has been correctly encoded. It can happen that you have to call the methods several times to process all the data.
The following link might help:
http://onjava.com/onjava/2004/11/03/ssl-nio.html
Or this question:
SSL Handshaking Using Self-Signed Certs and SSLEngine (JSSE)

Categories

Resources