December 9, 2010

how to fill your disk with random data

When using full-disk encryption, it is useful to prefill the disk in question with (pseudo)random data. This makes it harder to tell how much of the encrypted volume's space is already written to - in other words, how much data you have on the volume.

There are many ways to do it - specialized tools, reading from /dev/urandom (reasonably fast), reading from /dev/random (true randomness, but unless you have a HWRNG, it will take 1000 years to fill a disk). Trouble is, generating pseudorandom data is slow. While your average HDD can write at speeds over 50MB/s, you can only generate randomness at, say, 8MB/s (with one core, that is)

The usual recommended method is this:
dd if=/dev/urandom of=/dev/sda
It will take a very long time, because generating the random numbers is slower than writing them to the disk. The problem is that the kernel is only using one CPU core to generate the /dev/urandom stream - the CPU core on which your process runs.

Now if only there was some kind of a trick to make kernel use all four of my CPU cores...
You could, of course, run four dds and make them write to different areas of your disk - but wait, wouldn't that force the disk to seek back and forth? Wouldn't that be a little stupid? Yeah, I thought so.

That's why i wrote this tiny program called urandread. It will open four (or how many you need) processes to read from /dev/urandom, and then combine their output into a stream that is four times faster.
Then you can do this:
./urandread | dd of=/dev/sda
and you're BLAZING!

urandread.c

October 17, 2010

how to correctly execute su from Android application

This way:
Runtime.getRuntime().exec(new String[]{"/system/bin/su", "-c", "setprop ctl.stop zygote"});
If you are getting failures like this:
W/su ( 1043): request rejected (0:0->0:0 /system/bin/setprop)
that means that
  • you didn't send "-c", or
  • you didn't give it a parameter, or
  • you gave it more than one parameter
You have to make sure that after "-c" you only send one parameter. Alternate syntax would be this:
Runtime.getRuntime().exec("/system/bin/su -c 'setprop ctl.stop zygote'");

Starting and stopping Android core services from command line

Imagine, for example, that you need to stop the Zygote service and start it again later, because you're toying with Android internals and Zygote is getting in the way.
Or maybe you want to test out a new bootanimation binary, and for some reason running /system/bin/bootanimation directly is not what you want.
This is what you do instead:
setprop ctl.stop zygote
setprop ctl.start bootanim

Simple, right? Then how come it's ungooglable?

You can do all this from Java too, just use System.setProperty(). See this article for more detailed info about properties.

October 2, 2010

you gotta be effin kidding me

While trying to solve this issue, i have found a document from RIM's Knowledge Base about verification errors in Java packages.
This is it.
Some choice tidbits:
7. Comment out any non-executable code. Verification errors might be related to the size of the main code file and the library files. If you comment out non-executable code, the file sizes change, which may correct the problem.
2. Remove any System.out.* calls. These generally do nothing on the BlackBerry smartphone, but they might cause verification errors.
3. Remove unused import statements.

I have nothing. My mind is blown. How can anyone ever develop anything for this device?

May 7, 2010

how to tell git that you just want effin THEIRS version of a file

Imagine a situation: You are using git (maybe you like it, or maybe you just have to deal with it because people on the other end do that), you are starting to get familiar with it, make some changes to some source code, then want to synchronize with upstream.
You know that your changes are nothing dramatic, a line here, a word there.
So you go ahead and type git pull, expecting the merge to go seamlessly.
BAM! a conflict! (as it happens, upstream decided to throw out the file and put something completely different in its place)
No biggie, you say, i don't care about my changes, just give me their version. svn revert path/to/file would solve that in a whim.
First of all, you need to locate the file. "git status" won't tell you. Instead, type git commit.
It will say that there are conflicts and list them.
For each conflicting file, git checkout --theirs path/to/file will take the remote version. Similarly, --ours throws away remote changes.
Then just git add the files as usual, or simply go ahead and git commit -a. Done, voila!

March 29, 2010

vim folding makes me happy

When I'm not working with NetBeans and Java, I'm working with vim and python. Vim is unquestionably the best text editor of all time, but this post is not meant as an evangelism. This is aimed at those of you who are already using it.

Maybe you know that vim can do folding. That means that you type "zc" and the piece of code under your cursor neatly folds itself into one line (very much like in NetBeans/Visual Studio/Eclipse etc.), then type "zo" to unfold this line to the whole code. Alternately, use "za" to toggle.
This usually works either manually (you create folds with "zc" and "zf" and whatnot) or via a specialized filetype plugin that will create folds from, for example, sections delimited by curly braces.

It can also work based on indentation. Which happens to work very well for sanely formatted code, and especially for python, where sane formatting is part of syntax. Simplest way to get to this is to simply set foldmethod=indent in your .vimrc.

But this has its own share of drawbacks, namely, the autofolds do not contain a leading line.

For example, in this code:
if something():
do_stuff(1)
do_stuff(2)
do_stuff(3)

the autofolder will collapse the three do_stuff()s into one line labeled "+--- 3 lines:do_stuff(1)". I would like to collapse all four lines into one saying "if something()"

To accomplish this, you have to use a different method. This is what I added to my .vimrc (update: escaped the '<' sign that disappeared when rendering html):
setlocal foldmethod=expr
setlocal foldexpr=(getline(v:lnum)=~'^$')?-1:((indent(v:lnum)<indent(v:lnum+1))?('>'.indent(v:lnum+1)):indent(v:lnum))
set foldtext=getline(v:foldstart)
set fillchars=fold:\ "(there's a space after that \)


You also probably want to have all folds open by default:
set foldlevelstart=999


And to make things ultimately convenient, remap <SPACE> key to open/close a fold in normal mode
nnoremap <space> za

and create a new fold from selection
vnoremap <space> zf


There! Happy faces all around.

(note that this will mess up your foldlevel math, because there will be many foldlevels without corresponding folds. so don't expect serious use of zm/zr. me, i don't care.)

February 1, 2010

few notes on Samsung's IO

J2ME implementation on new Samsung phones has a few peculiarities. Yes, they're doing everything right by the spec - but they do it just slightly differently than most of the others.

First of all, InputStream.read() method, the one that reads single character, seems to be rather slow. When you say something like:
while (true) {
int ch = istream.read();
if (ch == -1) throw new IOException ("end of stream");
if (ch == '\n') break;
}

then the phone will do what you want, ssssssssllllllllllloooooooooowwwwwwwwwwwwllllllyyyyyyy.
Instead, make use of InputStream.available(), for example like this:
int av = istream.available();
if (av > 0) {
byte[] buf = new byte[av];
istream.read(buf);
} else {
int ch = istream.read();
}
The else is there for a reason. Two reasons, actually. First, some phones won't tell you what is available. So you should try to read anyway. Second, if nothing is actually available at that moment, read() will block and hopefully provide opportunity for other threads to run. (That is, if your phone implementation isn't completely retarded. Which, unfortunately, some can be.)

Now you've seen how Samsung reads from streams in large chunks. As it turns out, the chunks aren't as large as they could be.
Let's say you want to read a chunk of data from a file. Consider this:
DataInputStream dis = filehandle.openDataInputStream();
int length = dis.readInt();
byte[] buf = new byte[length];
dis.read(buf);

Can you spot the problem? Of course, the read(byte[]) method doesn't guarantee that it fills the buffer. But interestingly enough, on a vast majority of phones, it will actually do that when you're reading from a file.
Not on a Samsung.
So remember, kids, always check the return value of read(...) calls. Or, if you're using DataInput, as shown here, just readFully(...).