Saturday, March 27, 2010

Create a file of a given size on linux

Let's say you want to create a file whose size is 1K. You can achieve that by using either of following two commands:

    dd if=/dev/zero of=file bs=1024 count=1

    dd of=file bs=1024 count=0 seek=1

In my test, the generated files are different. The second command generates a file with holes. You can try command stat file. The output in my machine is:

  File: `bigfile'
  Size: 1024            Blocks: 0          IO Block: 4096   regular file

The number of allocated blocks is 0 although size of the file is 1024.
Note: if sparse file is not supported, it may write 1024K zeros to the file.

As a user, you don't need to worry about whether the file is sparse or not. It will grow as needed.

Thursday, March 25, 2010

Ubuntu package downgrade

I tried to use some Karmic sources for my Intrepid. Of course, this is bad. The reason I had to do it was the package of new version I needed only exist in Karmic repository.
After installing a package, suddenly I got the following error when I tried to use gvim
"gvim: error while loading shared library: libgailutil.so.18: cannot open shared object file: No such file or directory"

Obviously, the old libgail18 was removed which is needed by Intrepid. Because I used unmatched sources, the apt-get did not detect any problem.

I tried to install libgail18 using command
    sudo apt-get install libgail18
It did not work and the error message is

Package libgail18 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  libgtk2.0-0
E: Package libgail18 has no installation candidate

Finally, I figured out the cause is package libgtk2.0-0, libgtk2.0-0-common, etc. These packages are too new for Intrepid. They are for Karmic. So I tried to remove these packages using command
    sudo apt-get remove libgtk2.0-0 libgtk2.0-0-common etc
However, apt-get always gave error messages which told me those packages were needed by lots of other packages. It is obviously true. Also I tried command
    sudo apt-get install --reinstall libgtk2.0-0
It also did not work. The error message is the package cannot be found. Again the cause I think was the those installed packages were too new and did not match version of ubuntu.

It turned out that I need to use dpkg command
    dpkg --remove –-depends libgtk2.0-0 libgtk2.0-0-common etc

Then use following command to fix the broken dependencies:
    sudo apt-get install –f
libgtk2.0-0, libgtk2.0-0-common of correct versions are downloaded and installed.

Probably following commands are needed to clean up:
    sudo dpkg --configure –a
    dpkg-reconfigure

One big difficult I encountered was it was hard to collect detailed log about which files are created/updated/removed by which package during installation. It makes much easier to locate those packages which remove needed files.

SSH, XAuth and X11 Forward after user switch at remote site

Problem

User A connects to server S using ssh. X11 forward is enabled using –Y option. Then X11 should work smoothly.
User A connects to server S using ssh. X11 forward is enabled. Then user A switches to another User B (using command su B or ssh localhost –l B). After that, X11 forward won't work. The error should look like
"SSH gateway: X11 authentication failed. Error: Can't open display:" or
"Error: Can't open display:".
Readers may ask why user A does not directly connect to server S as user B given user A knows password of user B. The reason is that sometimes user B is a restricted user account so that he cannot log in remotely.

Solution

  1. Run command
        echo ${DISPLAY}
    Sample result:
        localhost:11.0
  2. Command: xauth list
    The output should be like:   
    your_host_name/unix:11  MIT-MAGIC-COOKIE-1  d1e63de6fd7bc3800d868c3b64ca4531
    your_host_name/unix:0  MIT-MAGIC-COOKIE-1  e044d47b672dcade1362cd632236f919
    your_host_name/unix:10  MIT-MAGIC-COOKIE-1  2aa3bc47d1c209fd06577f4b45f83383
    Pick the entry with the same display number as the output in step 1)
    In this example, display number is 11, so the entry we pick is
    your_host_name/unix:11  MIT-MAGIC-COOKIE-1  d1e63de6fd7bc3800d868c3b64ca4531
  3. switch to another user using either of the following ways
    1) su user_name
    or su – user_name
    read "man su" for difference between these two commands.
    2) ssh localhost –l user_name
  4. In step 3), if you ran command "su – user_name" or "ssh localhost –l user_name", you should run command
        export DISPLAY=localhost:11.0
    Value of DISPLAY should be the same as the output in step 1).

    add the entry obtained in step 2) to the .Xauthority file. You can either add it manually to the file or use tool xauth to do it. The way to use xauth to add an entry:
        xauth add :11 . d1e63de6fd7bc3800d868c3b64ca4531
    The cookie string (long string) must match the one in step 2). The display number (:11) must match the result in step 1)
  5. Try command
        xclock

Or you can combine step 1), 2), 3) and 4) into one long command:

    (tmpfile=/tmp/xauth_tmp_entry; \
    xauth extract ${tmpfile} :$(echo $DISPLAY|cut -d : -f 2 ); \
    chmod a+r ${tmpfile}; \
    su user_name -c "xauth merge ${tmpfile}"; \
    rm ${tmpfile} )

Note: replace user_name with the real target user name.

Disadvantage

Each time the user reconnects the remote machine using ssh, the whole process described above must be redone :-( The reason is that sshd may choose another display number and cookie value.

How SSH X authorization works?

From ssh manual:

"ssh will also automatically set up Xauthority data on the server machine.  For this purpose, it
will generate a random authorization cookie, store it in Xauthority on the server, and verify
that any forwarded connections carry this cookie and replace it by the real cookie when the
connection is opened.  The real authentication cookie is never sent to the server machine (and
no cookies are sent in the plain)."

http://blogs.gnome.org/markmc/2005/02/25/ssh-x-forwarding-and-xauth/

Every time a user connects to a remote server using ssh, a proxy X server is created. And that X server is used by the sshd process (a new process is forked each time a new connection comes in). The process is like:

  user ---> server ---> fork a new process, 
create a proxy X server
create pseudo terminal, etc. |
                                       |
                                       V
                        a program that needs X is used
                                       |
                                       |
                                       V
  local display <--- verify <--- the X output is forwarded by sshd to client

It seems that after a user connects to a remote server using ssh, another proxy X server is not created when the user ssh to localhost or 127.0.0.1.