Sparse files - what, why, and how

Sparse files are basically just like any other file except that blocks that only contain zeros (i.e., nothing) are not actually stored on disk. This means you can have an apparently 16G file - with 16G of “data” - only taking up 1G of space on disk.

This can be particularly useful in situations where the full disk may never be completely used. One such situation would be virtual machines. If a virtual machine never fills the disk entirely, then a certain amount of the disk will never have anything but zeros in it - permitting the saving of disk space by using a sparse file.

The operating system (which supports sparse files) knows that the block “exists” but is null, so it provides the zero-filled block out of thin air. As soon as the block contains data, the data is written to disk in the appropriate way and the file on disk grows.

There are problems with using sparse files. The most egregious would be that any utility that does not recognize or utilize sparse files can replicate the entire file on disk, so that a 500M sparse file could suddenly balloon to 6G. Even utilities that can work with sparse files must be told to do so, so this trap is easy to fall into.

Another problem is that everything about disk management is based on how many sectors or blocks are used - and the disk size reported for a sparse file is the full size of the file (not the actual number of blocks on disk). This also means that any utilities that work solely with blocks on disk (e.g., du) will report different amounts than other utilities.

Yet another problem is whether backup programs recognize or preserve sparse files. A backup program that does not recognize (and store) sparse files may well be quite oversized. A restore of this flawed backup - or indeed, a restore that does not recognize properly backed up sparse files - will balloon in size as mentioned before. In a worst case, there would not be enough room on disk to restore the data, if the sparse file expands enough to fill the disk.

To get the ls command to report actual on-disk sizes (instead of just the file size typically reported) use these options:

# ls -ls
total 96
8 -rw-r–r– 1 root root 2003 Aug 14 2006 anaconda-ks.cfg
68 -rw-r–r– 1 root root 59663 Aug 14 2006 install.log
8 -rw-r–r– 1 root root 3317 Aug 14 2006 install.log.syslog
12 -rw——- 1 root root 10164 Oct 25 2006 mbox

The blocks used are in the left side column; the bytes used are in their usual column just before the date. In this case, all of the files are using appropriate number of blocks - that is, none of these files are sparse.

Creating a sparse file basically amounts to a simple process: create a file, and seek to the desired end of the file. This can be done at the command line with a command like (to create a 1M sparse file):

dd if=/dev/zero of=sparse-file bs=1 count=1 seek=1024k

Here is an example, run on HP-UX:

# dd if=/dev/zero of=sparse bs=1 count=1 seek=1024k
1+0 records in
1+0 records out
# ls -ls sparse*
2 -rw-r–r– 1 root sys 1048577 May 22 12:58 sparse
#

Looking at HP-UX (and perhaps other environments), there does not appear to be a wide amount of support for sparse files in the typical utilities (such as tar, cp, cpio, etc.), even as the operating system itself will dutifully create sparse files.

However, GNU cp supports the –sparse option. By default, GNU cp attempts to detect sparse files and recreates them as warranted. A file can be copied into a sparse format using –sparse=always, or into a nonsparse format using –sparse=never. The default, alluded to earlier, is –sparse=auto.

GNU tar uses the –sparse option (or the equivalent -S option) to make tar store sparse files appropriately.

GNU cpio supports the –sparse option, which operates similarly: any suitable length of zeros is recorded as a “empty” and the file is stored or created as a sparse file.

The command rsync, while not a GNU project, does support sparse files. The option –sparse (or -S) will attempt to handle sparse files efficiently, that is, not creating file blocks full of only zeros.

It appears that utilities pax, scp, sftp, and ftp do not in general support sparse files. Using such a utility, then, would make a sparse file balloon in size.

Given this utility support for sparse files, the best native environment is proably Linux or MacOS X, or other open platform. More specifically, any platform where the GNU utilities are available, along rsync.

Recognizing a sparse file can be done at the command line with the previously mentioned ls -ls command. To see a sparse file (right down to the block level), one way would be to write a C program (or other language) to start at the end of the file, and truncate the file one block shorter - if the file on disk becomes shorter, then that block was on disk; if not, then it was a sparse block. Of course, any block that contains data is on disk; it is only blocks with zeros with which there is any question as to whether it is on disk or not. Jonathan Corbet had an article in December of 2007 in the Linux Weekly News that described a method that the Solaris ZFS developers had proposed, and posed the question as to whether Linux should support similar system calls that will seek to the next hole or the next set of data in a file.

Add comment 23 May 2008

Using QEMU

Using QEMU allows you to run a virtual machine on a UNIX system. Unlike other emulators, QEMU is a generic emulator - which means that it is portable, and that it emulates more than one system. There are versions for Windows, MacOS X, Linux, and OpenSolaris.

The QEMU emulator allows you to emulate an i386, an AMD-64, PowerPC, SPARC, and others. Not all are usable, but the i386, AMD-64, and PowerPC are usable.

Running QEMU on a Pentium III results in a slow emulated machine, but it is usable. Running Windows 2000 in 128M or 256M of memory is not too bad if you are patient. Running it on a modern machine is much more useful and much easier on the patience.

QEMU has some nifty features. The monitor, for instance, can be attached to a virtual console, to a pseudoterminal, or to a serial port. Likewise, the emulated serial port can be attached to a pseudoterminal, to a host serial port, or other locations - and more than one serial port is possible.

One very interesting feature is that the emulated machine can use a VNC session for its display, allowing you to access the host machine from anywhere on the network that you have a VNC viewer. This also suggests that you could have multiple emulated machines running, with all of them available over the network to VNC clients.

Unfortunately, there are no reliable control panels, and only two session managers for standard installations (or perhaps only one if you’ve not installed QT 4 yet). The only innate method of controlling QEMU emulators is through the text console. There is Qtemu (which, on my FreeBSD system, required all of QT4 to be installed), and there is qemu-launcher (which only requires the basics that are on any system). Unfortunately, QTEMU does not provide a way to open an existing virtual machine, nor does it offer a way to utilize machines and info created by qemu-launcher.

The only control panel I could find was the one used by qemu-launcher, qemuctl - which crashes.

Add comment 19 May 2008

Why you should know vi

I won’t make any excuses; I love vi. Folks at The Register called vi Bill Joy’s greatest gift to mankind (who am I to argue?) However, being able to use vi well goes beyond whether you like it or not.

Why should you know vi (well)? For one thing, it is on every UNIX and Linux system. Emacs certainly isn’t, and neither are the other worthy competitors like pico, elm, nano, and others. None of these editors, good though they may be, are ubiquitous enough. In fact, every last one requires special installation on virtually every platform - that is, there are no default installations that include them.

Even vim is not ubiquitous - although it may be available for lots of environments, it is not necessarily installed by default. For a long time, I used vim in vi-compatible mode for just this reason. (My favorite vim-specific idea? :set nowrap).

Vi has an interesting history. Vi was written by Bill Joy, starting with the basics of the em editor from George Coulouris of Queen Mary College, University of London. Bill wrote vi to be able to work at 300 baud (as he says, that’s all he had and the fellows at MIT doing EMACS had the equivalent of fiber for that day and age). UNIX Review did an interview with Bill in August of 1984.

The original vi is now available under a BSD license. In contrast to EMACS and vim, both of which number in the multi-megabytes, vi was 160k on the i386.

So what editor does Bill use? ed.

UPDATE: Eric Raymond in his book The Art of UNIX Programming (also available online) has a very interesting analysis in Chapter 11 of the complexity and contrast (and psychology) between EMACS and vi.

2 comments 15 May 2008

Fedora 9 Announced

Yesterday Fedora 9 was announced. Using Fedora can give you a look at what may be in Red Hat Enterprise Linux down the road - and give you an exciting Linux distribution to boot.

There are a number of new exciting features to be found in Fedora 9. First, everything is updated to the latest versions, including GNOME 2.22, KDE 4.0.3, and Xfce 4.4.2.

Fedora 9 introduces the new filesystem ext4 as an option. While ext4 remains an experimental filesystem, it may be good to try it out. Like ext3, it remains compatible in both directions (an ext4 filesystem can be mounted as ext3, and vice versa).

Fedora 9 also replaces the System V initd process with an event-based replacement, upstart. Upstart was created and developed for Ubuntu Linux, and has spread to Fedora and Debian. Each process is started through a response to an event, and each process may generate another event.

Fedora 9 has several different spins or variations based on different sets of packages. For example, there could be a KDE spin, a GNOME spin, and a Xfce spin for example. The Fedora project has a page tracking spins for those who might be interested in custom spins.

This version of Fedora introduces support for Jigdo, which is a CD distribution mechanism that the Debian project has used for years. I’ve not used Jigdo, but the description given in the release notes suggests a large speedup if you have most of the data already.

It sounds like a very exciting distribution; I’ll be looking around my electronic wasteland to see where to install it.

Add comment 13 May 2008

Book Review: Disk and File Management Tasks on HP-UX

Using LVM on HP-UX can be troublesome, and any deviation from the usual steps can cause problems. Specifically, if the data on disk and the data in the system vary, then there can be a variety of problems. The usual symptom is that the LVM environment tools won’t let you do something that seems obvious (like removing a volume group when the relevant disk volume is missing).

The book Disk and File Management Tasks on HP-UX (by Tom Madell) is basically a guide to all things LVM. Despite its age (1996), it is still relevant, and covers LVM, OnlineJFS, and VxFS. The book is also not standard publishing quality, but is a bound set of facsimile pages - this doesn’t detract from the contents however.

The book covers all aspects of disk and file management, including such advanced topics as creating your own bootable root volume, recovering from loss of /etc/lvmtab, and many other details. It covers commands such as vgcreate, vgexport, vgimport, vgreduce, vgremove (and their logical volume counterparts).

It also covers converting to VxFS (from older filesystems), mirroring, and creating striped volumes.

This is a worthy addition to any HP-UX administrator’s library.

Add comment 12 May 2008

More tips on using find

My entry on using find turned out to be popular; I thought I’d throw out some tidbits on using find for various things. So sit back and enjoy the list!

find . -type f | xargs ls -ld

List all standard files in the current hierarchy starting at the working directory.

find . -type d | xargs ls -ld

Get a list of directories, showing the tree structure starting at the working directory.

find . -mtime +2

Show all files older than two days.

find . -size +10000

Show all large files (possibly for freeing up some space?)

find /*bin /usr/*bin /usr/local/*bin -name "somebin"

Find a executable file by the name given in any of the usual locations (including both bin and sbin).

find . -cpio dev

Find files (as specified) and write to a cpio archive specified in the cpio parameter. This is a newer option; check if your find has it first.

find / -nogroup -o -nouser

Find all files on the system that have no group or owner; files such as these are a security risk and should be associated with groups and owners in /etc/group and /etc/passwd. Remember to run a fidn command that starts at / at a time when users will not be inconvenienced by the massive search.

find / -perm -s

Find all files that are suid or guid - again, these may be a security risk. You should know which binaries are (and need to be) suid and guid.

On using the -exec parameter:
if you use the “old school” form, with {} and \; (such as find . -exec rm -f {}\;) then the command will be executed once for each file found. If you use the “new school” form with {} followed by \+ (such as find . -exec rm -f {}\+) then the command will be executed for all files found in one go.

It is unclear whether it will limit the number of parameters (to keep the command line to within acceptable lengths). The xargs command is the usual way to do this; the biggest advantage of xargs over -exec is that no matter how many times the command is executed, it is never pulled again into memory: xargs restarts the command from the beginning without paging in any code. It also allows you to specify the line size limit as well, or a limit on the number of arguments for that matter.

Newer xargs appear to work with shell scripts as well; traditionally, xargs required binaries and shell scripts (or other scripts) would not work.

1 comment 4 May 2008

How much memory is in the box? (all UNIX, OpenVMS)

How much memory is in this machine?

It would seem that answering this question ought to be easy; it is - but every system has the answer in a different place. Most put an answer of some sort into kernel messages reported by dmesg (AIX apparently does not).

Most systems have a program for system inventory which reports a variety of things, including memory.

Rather than go into great detail about each one, we’ll just put these out there for all of you to reference. Each environment has multiple commands that give available memory; each command is listed below.

Without further ado, here are a few answers to this burning question:

Solaris

  1. dmesg | grep mem
  2. prtdiag | grep Memory
  3. prtconf -v | grep Memory

AIX

  1. bootinfo -r
  2. lsattr -E1 sys0 -a realmem
  3. getconf REAL_MEMORY

HPUX

  1. dmesg | grep Physical
  2. /opt/ignite/bin/print_manifest | grep Memory
  3. machinfo | grep Memory

Linux

  1. dmesg | grep Memory
  2. grep -i memtotal /proc/meminfo
  3. free

OpenVMS

  1. show mem /page

Update:

FreeBSD

  1. dmesg | grep memory
  2. grep memory /var/run/dmesg.boot
  3. sysctl -a | grep mem

Add comment 3 May 2008

Core Linux - packages

The new version of Core Linux comes with packages and appears to be fully comprised of packages (like Red Hat Linux, and unlike FreeBSD which has a core application set). These packages are simple: they are just tar.bz2 files that contain files relevant to the application, and a set of files that go under /etc/coretools/pkg.

The directory /etc/coretools contains everything related to core packages; the pkg directory has the details on each package, and the directory exec.d has plugins for the program corepkg. Plugins are just scripts that are called by corepkg.

The program corepkg lists its help if called with no parameters. Some of the more common usages might be:

  • corepkg --list (list current plugins)
  • corepkg --exec=info --pkgname=pkg (package information by name: pkg)
  • corepkg --exec=list (list all installed packages)

The plugins as installed are:

  • contents - list files created by package named
  • count - count packages matching specified options
  • info - information on specified package
  • install - install specified package
  • list - list installed packages
  • remove - removed specified package

The packaging system is simple and driven fully by shell scripts. It should be possible to ignore it without adverse effects. There don’t seem to be any packages beyond the basic system, but that may not be the case. Anyway, the goal of the original Core Linux - and its descendents - is to build your own system through compiling your own code.

2 comments 2 May 2008

Core Linux - Setting up GRUB

To prepare for installing grub, it is necessary to chroot into the system mounted on /mnt. To do this, we need a working /proc and /dev under /mnt; this is accomplished like thus:

mount -t proc none /mnt/proc
mount -o bind /dev /mnt/dev

Then perform the chroot - making the new environment mounted under /mnt our new environment:

chroot /mnt /bin/bash

Note that this makes bash the current shell - not my general choice (I prefer ksh) but things might break if you use the wrong shell….

Now we can install and configure grub:

grub-mkdevicemap
grub-install –grub-setup=/boot/grub/grub.cfg /dev/sda
/sbin/grub-install: line 223: /boot/grub/grub.cfg: Permission denied
grub-setup –directory=/boot/grub –device-map=/boot/grub/device.map /dev/sda
cat /boot/2.6.21.1/grub >> /boot/grub/grub.cfg

The error comes from grub-install apparently trying to write to grub.cfg (which has permissions 644). The directions say this error can be ignored - so that’s what we’ll do.

The resulting grub.cfg looks like this:

# Set timeout
set timeout=30

# Set default entry
set default=0

# Grub configuration for linux-2.6.21.1
menuentry “Core 2.0 GNU/LInux (2.6.21.1)”{
set root=(hd0,1)
linux (hd0,1)/boot/2.6.21.1/bzImage root=/dev/hda1 vga=5
}

In this case, this is certainly wrong. The last stanza is preconfigured for hda and for a single volume root. Since I have two partitions, and am using /dev/sda, it should be:

# Grub configuration for linux-2.6.21.1
menuentry “Core 2.0 GNU/LInux (2.6.21.1)”{
set root=(hd0,1)
linux (hd0,1)/2.6.21.1/bzImage root=/dev/sda3 vga=5
}

Then edit /etc/fstab:

/dev/sda1 /boot ext3 defaults 0 0
/dev/sda3 / ext3 defaults 0 0
/dev/sda2 swap swap defaults 0 0

Then reboot:

exit
cd /
umount /mnt/dev
umount /mnt/proc
umount /mnt/boot
umount /mnt
shutdown -rn now

Next time…. the first boot.

Add comment 1 May 2008

Installing Core Linux

Installing Core Linux is covered in this article (on the front page of coredistro.org as it happens!). The descriptions are clear; however, we will expand on the instructions listed there.

Let’s assume that you’ve already burned the ISO and booted with the CDROM. Once the system has booted, you’ll see this screen:

Core Linux Boot Screen

Log in as root (which has no password). First, figure out which disk to work with. The disk is most likely either /dev/hda (first IDE drive) or /dev/sda (first SCSI drive). You can see whether these disks exist by searching dmesg for sda and for hda.

Once the disk is determined, we must begin laying out the disk. In my configuration, I used fdisk to create three partitions:

  • /boot partition of 500M
  • Swap partition of 1G
  • / partition of the rest (about 7G)

With this configuration, it is then necessary to (of course) create the filesystems:

mkfs -t ext2 -j /dev/sda1
mkfs -t ext2 -j /dev/sda3

The -j option creates what is commonly called an ext3 partition - which is in reality, and ext2 partition with a journal file attached. But that’s another post.

After the filesystems are created, then they must be mounted under /mnt as the complete environment would be layed out. For this example, that means:

mount /dev/sda3 /mnt
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

After this is done, the actual process of installing Core Linux can begin. At the prompt, type:

install_core /mnt

Messages will appear like these:

Core Linux Install Messages

Once this completes, a message comes back:

Install complete - the next step is to chroot into /mnt and install grub

Next installment… setting up grub.

1 comment 30 April 2008

Next Posts Previous Posts


David Douthitt

David is an experienced UNIX and Linux system administrator, a former Linux distribution maintainer, and author of two books ("Advanced Topics in System Administration" and "GNU Screen: A Comprehensive Manual"). View David Douthitt's profile on LinkedIn

Recent Posts

Top Posts

RSS Sharky's Column!

Calendar

July 2008
M T W T F S S
« Jun    
 123456
78910111213
14151617181920
21222324252627
28293031  

Recent Comments

bharat on The Demise of the HP-UX System…
H4mm3r on Avoiding catastrophe!
Vladimir on Argument list too long?
ddouthitt on The UNIX find command and…
Mihir G joshi on The UNIX find command and…

Category Cloud

BSD Career Debian Debugging Fedora FreeBSD HPUX Learning Linux MacOS X Mind Hacks Mobile Computing NetBSD Networking OpenBSD OpenSolaris Open Source OpenVMS Personal Notes Portable Presentations Red Hat Scripting Security Solaris Tips Ubuntu UNIX Wheel Group Windows

Archives

Feeds

Links