September 9, 2008

Shell Command Substitution

Drew Stephens @ 8:08 pm — Tags: ,

The other day I wanted to diff a pair of files on two different hosts, stg1 and stg2. Normally, I would do so by copying on of the files to the other host, or grabbing them both onto my workstation with scp; “there must be a better way,” I thought.

Enter command substitution, a process by which you use the output from an executed command as the input to another. Many people have used this in a simple manner such as ls /usr/src/linux-`uname -r`which takes the output of uname -r, namely the kernel release you’re running, and uses that to flesh out the ls command. There is a more complicated form, however, that I use for diffing remote files. In the aforementioned example, I used the following command to diff the files:

vimdiff <(ssh stg1 cat /etc/rc.d/init.d/httpd) <(ssh stg2 cat /etc/rc.d/init.d/httpd)

Much like a subselect in MySQL, the cat commands are executed on the remote machine and then piped to vimdiff allowing for single command, no-file-copying diffs.

September 5, 2008

Speeding up SSH Logins in Ubuntu

Drew Stephens @ 1:23 pm — Tags: , ,

After getting access to some new machines, I noticed that SSHing too them was excruciatingly slow, taking 5-10 seconds to ask for a password and no faster using keys. I pulled open the global SSH config file, /etc/ssh/ssh_config on my Ubuntu machine and found a couple of GSSAPI things that were enabled by default:

GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes

The machines I was SSHing to don’t do GSSAPI, so every time I tried to connect my client had to wait a short timeout before trying other authentication methods. Since I don’t care about GSSAPI (few people use it), I simply set those options to no and now my SSH sessions start much more quickly.

June 25, 2008

Apache Won’t Start: No space left on device

Drew Stephens @ 2:10 pm — Tags: , , ,

I doing some development involving Apache handlers which involves lots of restarting it and occasionally Apache shutting down uncleanly. After numerous restarts, the webserver refused to start printing the following in the error log:

[Wed Jun 25 18:57:11 2008] [emerg] (28)No space left on device: Couldn't create accept lock

After being confused because there certainly is enough disk space, I Googled for other possibilities and it turns out I had hit another limit, that of active semaphores. When some of my processes were killed, they died uncleanly and didn’t clean up their open semaphores, filling the maximum number available to my user. It’s easy to tell that this is the root of the issue; running ipcs -s showed a list of 95 open semaphores. Clearing them up is just as easy:

~$ for id in ipcs -s |awk '/USERNAME/ {print $2}'; do ipcrm -s $id; done

That prints the list of semaphores, grabs the ID ({print $2}) for lines containing USERNAME (your own or that which the webserver runs under) and then ipcrm’s those semaphores.

June 10, 2008

Keeping Your Home Directory in Subversion

Drew Stephens @ 1:25 am — Tags: , ,

I’ve heard of doing this for a long time, but always figured it’d be a huge jump to put my home directory into a revision control system. For years I’ve scp’d files to a new machine when I moved in and when I made changes to my vimrc or ssh config, it was hell to propagate the changes to my other machines. No more is this an issue, since I’ve commited my home directory. The process is really quite trivial.

I first created a subversion repository on my Linux server. A special machine isn’t required, nor is root access; you just need somewhere that can be accessed with SSH from the intertubes.

~$ svnadmin create subversion

It’s as easy as that. To begin with, let’s create the standard subversion directory structure.

~$ svn co file://$home/subversion/ foo
~/foo$ cd foo
~/foo$ mkdir homedir
~/foo$ svn add homedir
~/foo$ svn commit
~/foo$ cd ..
~$ rm -rf foo

So now we have a repository with a homedir directory in the root; this is where all of the files from your home directory will be checked into the repository. To begin with, check out this new project into the root of your home directory.

~$ svn co file://$home/subversion/homedir .

Since there isn’t anything in there, nothing will actually be checked out, but subversion will setup source control on ., your home directory. So let’s add something to it. I have a .vimrc that ought to be identical across environments, so I’ll check that and my .vim support directory into the repository

~$ svn add .vim*
A         .vimrc
A         .vim/colors/drew.vim
A         .vim/plugin/feraltogglecommentify.vim
~$ svn commit -m "adding stuff for the first time!"

Easy as that, all of my vim configuration files are in subversion. Now for the awesome part. Like I mentioned, I have a number of machines and, things like vim configuration files should be the same on all systems. So now, I hop onto another machine and checkout the homedir project. First I remove the existing .vim* files since they will be replaced with the repository versions.

Caligula:~$ rm -rf .vim*
Caligula:~$ svn co svn+ssh://dinomite.net/home/dinomite/subversion/homedir .
A    .vim
A    .vim/colors
A    .vim/colors/drew.vim
A    .vim/plugin
A    .vim/plugin/feraltogglecommentify.vim
Updated to revision 1.

Bam. I’ve now got the exact same files on both machines. If I’m at the office and find some flash vim option that I want to use, I simply add it to my .vimrc, check it in with svn ci .vimrc and when I svn up from the other machines, they’ll get the new changes. In reality, I keep a bunch of stuff in my homedir subversion repository: .bashrc, .screenrc, bin directory and many others. Subversion helps me keep all of my config files in sync across a number of different machines that I use on a daily basis; if you use more than one system with any frequency, I highly suggest checking in your home directory.

May 6, 2008

Installing Proggy Fonts in Ubuntu

Drew Stephens @ 3:56 pm — Tags: , ,

I don’t recall how I came across the free Proggy font family but I wanted to try them out on my Ubuntu workstation for use in Eclipse. After some searching, I figured out how to install TrueType (.ttf) fonts and the process is pretty straightforward. I downloaded and unpacked the fonts into ~/.fonts, created a fonts.dir metadata file, added them to the font cache and when I restarted Eclipse, they were available.

~$ mkdir .fonts
~$ cd .fonts
~/.fonts$ wget http://www.proggyfonts.com/download/download_bridge.php?get=ProggyCl
ean.ttf.zip
~/.fonts$ wget http://www.proggyfonts.com/download/download_bridge.php?get=ProggySq
uare.ttf.zip
~/.fonts$ wget http://www.proggyfonts.com/download/download_bridge.php?get=ProggyS
mall.ttf.zip
~/.fonts$ ttmkfdir -o fonts.dir
~/.fonts$ fc-cache -f -v

April 21, 2008

Auto-remove Old Items from The Trash in Mac OS X

Drew Stephens @ 1:37 pm — Tags:

Having a purgatory for files that are on their way to deletion, such as the trash can in Mac OS or the recycle bin in Windows, is a great idea, for even the most careful users occasionally delete something only to find that they later need it. Unfortunately, the two aforementioned implementations, as well as those in Gnome and KDE, only allow you to empty the trash all at once. Much more useful is to have a timeout where files that are sent to the trash are automatically removed after a period of time. I finally got around to implementing this myself in Mac OS by putting the following in my crontab:

0 5 * * * /usr/bin/find /Users//.Trash -mindepth 1 -maxdepth 1 -mtime +14 -exec rm -rf {} \;

Every day at 5 minutes after midnight any item more than 14 days old is delete from the trash can. To install it, read the linked article above or, if you know the command line, open a terminal, type crontab -e, paste the above (substituting your username) and save the file.

March 2, 2008

Rsync from Mac OS X to a Linux Machine

Drew Stephens @ 11:15 am — Tags: ,

If you try to rsync from a Mac OS X machine using the -E switch (capture extended attributes & resource forks - you want this) to a Linux or BSD computer, you’ll get something like the following error:

rsync: on remote machine: -vlogDtprzE: unknown option
rsync error: syntax or usage error (code 1) at main.c(1108)
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at /SourceCache/rsync/rsync-30/rsync/io.c(359)

What’s the holdup? Well, resource forks are a purely Mac OS construct (though NTFS has Alternative Data Streams that aren’t often used) allowing specific data, such as icons and application metadata, to be shoved into a file. The standard version of rsync doesn’t support these containers, so Apple includes a patched version in Mac OS X to handle them and in order to get this support on a non-Mac, you must install this patched version. Doing so is a fairly simple affair, since Apple makes the patch readily available through their Darwin source site.

Since I’m running Mac OS 10.5.2 (the latest update to Leopard), the files I need are in the 10.5.2 branch of the darwinsource directory; change that number to your version of OS X or navigate from the above mentioned Darwin source site.

wget http://www.opensource.apple.com/darwinsource/10.5.2/rsync-30/rsync-2.6.3.tar.gz \
http://www.opensource.apple.com/darwinsource/10.5.2/rsync-30/patches/EA.diff

Don’t ask me why the directory is rsync-30 when they’re using rsync-2.6.3. Now it’s just a simple matter of unpacking the source, applying the patch and compiling rsync:

tar zxf rsync-2.6.3.tar.gz && cd rsync-2.6.3 && patch < ../EA.diff && \
./configure --enable-ea-support && make && sudo make install

By default, it installs to /usr/local/bin/rsync so installing this version won’t trash that put in place by your sytem’s package manager. I also found a post on macosxhints.com concerning rsync interacting with the disk indexing of Spotlight. If you are writing tons of files to a Spotlight-indexed disk on a Mac, the indexer can become overwhelmed. The solution is to disable Spotlight on the disk in question with mdutil -i off <mountpoint> or to write into a directory appended with .noindex.

February 15, 2008

Linux Filesystem Internals

Drew Stephens @ 6:18 pm — Tags: , ,

Someone asked me questions about filesystems recently and, though I used to have a good handle on them, my knowledge has waned over the years. I figured writing about filesystem internals was a good way to brush up on that knowledge.

This information applies generally to UFS, FFS, ext2/3 and XFS. [ReiserFS[(http://en.wikipedia.org/wiki/ReiserFS) and HFS(+) employ B-trees for organization of file metadata rather than inode lists, so they are somewhat different. ZFS is the tits and all of its shenanigans are handled differently.

At a low level, Unix filesystems are made up of three main pieces on the disk: a superblock, inodes and data blocks. The superblock contains information about the filesystem: a magic number to identify the type, the size of the filesystem, free data blocks and other gross information. After the superblock comes a list of inodes, each of which contains metadata about a file including the permissions, the number of links to the file, the file type (symlink, directory, etc.) and the datablocks that hold the actual file data. Note the conspicuous lack of a filename in the inode; more on this later. The balance of the space on a partition is made up of those data blocks which hold the actual file data.

As mentioned previously, inodes only store metadata; the actual data is stored in one or more data blocks, the inode merely keeps a list of the blocks that contain the data for the file. In ext2/3, each inode has 15 blocks that can each refer to a single data block, each of which is usually 1 kilobyte meaning that the maximum filesize on ext2 is 15 kilobytes…but that’s certainly not true. The 15 data-referencing blocks are actually allocated more intelligently than that. The first 12 (0..11) are direct blocks, pointing to the first 12 blocks (kilobytes) of a file. The 12th block is the indirect block; instead of pointing to data blocks that contain data, it points to a data block that contains a list of up to 2060 addresses of blocks that contain data. Since a maximum filesize of (2060+12) 2072 kilobytes isn’t sufficient for most peoples needs, the 13th block is doubly-indirect and the 14th is triply-indirect. With all that indirection, the maximum filesize on ext2/3 is about 35 gigabytes, which ought to be enough for anyone.

So, when you want to read a file, the operating system first checks the metadata in the inode to ensure you have permission to access said file. Assuming you do, data is pulled from the data blocks listed in the inode, with appropriate indirection depending upon the size of the file.

I mentioned previously that filenames are not part of the inode, which seems odd as the filename seems to be a type of file metadata. The rub is that in POSIX systems a file can have multiple names; my home directory can be referred to as /home/dinomite, /home/dinomite/., /home/dinomite/bin/.. or a number of other names. How is this handled and where are filenames actually put? In directories. A directory boils down to nothing more than a list of names and their associated inode numbers, which we refer to has a link, giving name to the system call unlink which most people refer to as delete. When you refer to a file by name, the operating system starts at the root node (/), which is always inode number 2. Beginning with the root directory listing, it matches filenames to inode numbers, cascading this lookup until it has found the file that you referenced.

The important thing mentioned in the previous paragraph is that filenames in a directory list are links to a file; each of those links is noted in the file’s inode as the link count. Whenever a file is given a name (either by being created or a hard link via ln), the link count is incremented; when a link is deleted, the link count is decremented. When the link count reaches zero, the kernel releases those data block, unless the file is currently open. In the latter case, the data blocks are freed when the file is closed. This also lends insight into how undelete programs work and what computer people mean when they say deleting something doesn’t actually get rid of the data on the disk. When you delete a file, more properly known as unlinking it, the only thing that actually goes away is the data in the inode. Until they are overwritten, the data blocks still contain the data prior to being deleted. fsck works in a similar manner, searching for inodes that have positive link counts, but no references in directories.

Finally, there are symbolic links. With a symlink, an inode is allocated and has its symlink bit set. If the file pointed to by the symlink is 60 bytes or less, it is stored directly in the inode. If its longer, the pointed-to file is stored in data blocks and they are pointed to by the inode in the normal fashion. Note that symbolic links to not affect an inode’s link count, hence broken links.

References

December 4, 2007

Connecting to Oracle Without a Password on Windows

Drew Stephens @ 10:56 am — Tags: ,

If you have forgotten, were never given or otherwise don’t have the password to an Oracle database, never fear, there is a method to accessing the database. From the local machine you must be a user in the group “ora_dba”. Run “sqlplus” (the command line version) with the option “/nolog”, which tells SQL*Plus not to login. At the “SQL>” prompt, type “connect / as sysdba” which ought to log you in. At that point, you can change the password for any account (sys would be a good one to change, since apparently you don’t know it) using the command alter user <username> identified by "<password>";. Make sure to commit; after doing that.

December 2, 2007

Disconnecting: Corrupted MAC on input.

Drew Stephens @ 9:25 pm — Tags: , ,

I woke up to find the entitled error in the rsnapshot logs on one of my machines, which occurred as it was trying to remotely backup, via SSH, another. A quick search and reading through a number of threads revealed this message stating that this problem was encountered with a Linksys router involved. Lo and behold, my home network was just switched to a Linksys BEFSR41 when the problem began.

I think the router may also be the culprit for the occasional “error establishing encrypted connection code -12192″ that Firefox has been giving me since the switch.

Older Posts »

Powered by WordPress