Sparse file creation, not zero fill

If all we wanted to do was create a file of size N, then we can simply write at byte N in the file. This can be a significant savings in IO and is called sparse file creation.

Here is a simple Python script which does just that:

#
# Does not account for size < 1
#
def punch(file, size) :
    try :
        f = open(file, "wb")
        f.seek(size-1)
        f.write(b'\x00')

    finally:
        f.close()

punch("p1024.out", 1024)
punch("p1023.out", 1023)
punch("p64.out", 64)
punch("p1025.out", 1025)
punch("p10250.out", 10250)

And it yields:

[thomas@snakey src]$ ./punch.py 
[thomas@snakey src]$ ls -la p*out
-rw-r--r-- 1 thomas wheel  1023 Feb 13 16:05 p1023.out
-rw-r--r-- 1 thomas wheel  1024 Feb 13 16:05 p1024.out
-rw-r--r-- 1 thomas wheel 10250 Feb 13 16:05 p10250.out
-rw-r--r-- 1 thomas wheel  1025 Feb 13 16:05 p1025.out
-rw-r--r-- 1 thomas wheel    64 Feb 13 16:05 p64.out

Can we detect a difference between the two outputs?

[thomas@snakey src]$ uname -a
Linux snakey 2.6.35.11-83.fc14.x86_64 #1 SMP Mon Feb 7 07:06:44 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
[thomas@snakey src]$ cmp p1023.out h1023.out 
[thomas@snakey src]$ cmp p10250.out h10250.out 

That asks the question over whether the OS is dumping data down there for me or not. Hmm, let's try this:

[thomas@snakey src]$ du -sh p10250.out h10250.out 
4.0K	p10250.out
12K	h10250.out

So the sparse one is 1/3rd the size. If we do an additional file 10x the size of this one, we see:

[thomas@snakey src]$ cmp p102500.out h102500.out 
[thomas@snakey src]$ du -sh p102500.out h102500.out 
4.0K	p102500.out
104K	h102500.out

So the sparse file creation is working in the sense that we are seeing a block being written. (Which must perforce be 4k.)

So why then does cmp not squawk? Well, when this OS reads the missing pages, it reports them as 0s to the caller. We can also see that this OS is zero filling the page for us.

Learning Python – mkfile

I’m trying to learn Python, again, and the problem is in trying to code things which would be simple in C/Perl/etc which are hard in Python.

I talked about how cool mkfile was in Creating a small zpool for testing and so I thought I would try to code that up in Python. Remember, this is my first whack at Python in 2 years, so it is all pretty much fresh and I’m in a learning mode.

I struggled with strings, bytearrays, and bufferedreaders. I still don’t know how to open a bufferedreader.

But I finally got to a working piece of code:

import array

def mkfile(file, size) :
    chunk = 1024
    loopto = size // chunk
    filler = size % chunk

    bite = bytearray(chunk)

    try :
        f = open(file, "wb")
        for n in range(loopto) :
            f.write(bite)

        if filler > 0 :
            f.write(bytearray(filler))

    finally:
        f.close()

mkfile("h1024.out", 1024)
mkfile("h1023.out", 1023)
mkfile("h64.out", 64)
mkfile("h1025.out", 1025)
mkfile("h10250.out", 10250)

And it actually yields appropriately sized files:

[thomas@snakey src]$ ls -la h*.out
-rw-r--r-- 1 thomas wheel  1023 Feb 13 15:47 h1023.out
-rw-r--r-- 1 thomas wheel  1024 Feb 13 15:47 h1024.out
-rw-r--r-- 1 thomas wheel 10250 Feb 13 15:47 h10250.out
-rw-r--r-- 1 thomas wheel  1025 Feb 13 15:47 h1025.out
-rw-r--r-- 1 thomas wheel    64 Feb 13 15:47 h64.out

Now I need to check to see if they are all zeros:

[thomas@snakey src]$ dd if=/dev/zero of=z10250.out bs=10250 count=1
1+0 records in
1+0 records out
10250 bytes (10 kB) copied, 4.6629e-05 s, 220 MB/s
[thomas@snakey src]$ cmp z10250.out h10250.out 

So yeah, there are really easy ways to accomplish mkfile.

Waiting on a Triwing #0

I ordered a 9.5 mm SATA Optical Bay SATA Hard Drive Enclosure from iFixit.com. I should have paid more attention – I had the Torq screwdriver I needed on the older MacBook Pros, but I didn’t have the #0 Triwing I needed with the newer models.

I spent last Saturday afternoon trying to find one in town. I could get down to a #2, but no luck on the #0. So I ordered one from iFixit.com. It wasn’t their fault and they had a speedy turn around. It shipped just quick enough to get caught in the snow storm.

My son said he saw a USPS truck in the nearby apartment complex, but they seem afraid of our cul-de-sac.

Speaking of ugly code

The following violates many coding principals that I normally hold true to, but it was actually cool to code using the string variables as a stack.


#!/usr/bin/perl

# print hostlets
#
# 192.168.$i.0
$titan = "";
for ($i = 0; $i < 11; $i++) {
        $j = 0;
        $l = 0;
        $m = 0;
        $n = 0;
        $monster = "";
        $groupzilla = "";
        while ($j < 256) {
                $monster .= " hostlet_" . $i . "_" . $l;

                print "hostlet_" . $i . "_" . $l . " ";
                for ($k = 0; $k < 10 && $j < 256; $k++) {
                        print "(192.168.$i.$j,,) ";
                        $j++;
                }
                print "\n";
                $l++;

                if (($l % 5 == 0) || $j >= 255) {
                        $groupzilla .= " monster_" . $i . "_" . $m;
                        print "monster_" . $i . "_" . $m . $monster . "\n";
                        $monster = "";
                        $m++;
                }
        }

        $titan .= " groupzilla_" . $i;
        print "groupzilla_" . $i . $groupzilla . "\n";
}

print "titan" . $titan . "\n";

Allowing root ssh logins to Solaris machines

I’ve been away from Solaris for 5 months, but I need some VMs for NFSv4 testing, which means beating my head against modernization such as RBAC, pfexec, and NWAM.

I prefer to treat my lab Unix machines as inter-changable boxes and do all of my configuration up front. I want to be able to do an SSH root login, especially if the system goes out of the way to make that hard.

There are currently 3 things you have to do to violate this security truism on either OpenSolaris or Solaris 11:

1) Modify PermitRootLogin to yes in /etc/ssh/sshd_config.

2) Comment out the “CONSOLE=/dev/console” line in /etc/default/login.

3) Remove “;type=role” from the root entry in /etc/user_attr.

Really nasty Solaris 11 install

I just installed two VMs with the Solaris 11 express (snv_151a) and when I turned off nwam, one worked and the second did not:

svcadm disable svc:/network/physical:nwam
svcadm enable svc:/network/physical:default

The network would come up, both ifconfig and netstat -rn showed reasonable values, but the machine would only ping iff nwam were turned on.

It turned out to be ipfiltering:


root@snarf:~# ping 172.16.1.2
ping: sendto Network is unreachable
root@snarf:~# ipfstat -io
block out log all
pass out quick on lo0 all
pass out quick proto udp from any to any port = bootps
block in log all
pass in quick on lo0 all
pass in quick proto udp from any to any port = bootpc
root@snarf:~# svcadm disable svc:/network/ipfilter
root@snarf:~# ping 172.16.1.2
172.16.1.2 is alive
root@snarf:~# ipfstat -io
empty list for ipfilter(out)
empty list for ipfilter(in)

It was not enabled on the first machine, but was on the second. I have no clue what I did differently in the first install.

Configuring Fedora Core 14 network interfaces in a dual-hosted VM

I’ve got several VMs running with eth0 being bridged and eth1 being host only. I see the routes:

[thomas@mage ~]$ ip route
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.21 
172.16.1.0/24 dev eth1  proto kernel  scope link  src 172.16.1.3 
default via 172.16.1.1 dev eth1

The problem being that is flipped from what I want for the default route. I suspect the issue is that eth0 is set up to be configured via DHCP.

I read a bit and it was suggested that not only does /etc/sysconfig/network-scripts/ifcfg-eth0 have to have:

DEFROUTE=yes

But /etc/sysconfig/network-scripts/ifcfg-eth1 should have:

DEFROUTE=no

I made that change and cleared that hurdle:

[thomas@mage ~]$ ip route
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.21 
172.16.1.0/24 dev eth1  proto kernel  scope link  src 172.16.1.3 
default via 192.168.1.1 dev eth0 

FWIW, here are my config files:

[thomas@mage ~]$ more /etc/sysconfig/network-scripts/ifcfg-eth?
::::::::::::::
/etc/sysconfig/network-scripts/ifcfg-eth0
::::::::::::::
DEVICE="eth0"
NM_CONTROLLED="no"
ONBOOT=yes
HWADDR=00:50:56:2E:52:F0
TYPE=Ethernet
BOOTPROTO=dhcp
DEFROUTE=yes
PEERROUTES=yes
IPV6INIT=no
UUID=5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03
::::::::::::::
/etc/sysconfig/network-scripts/ifcfg-eth1
::::::::::::::
DEVICE=eth1
HWADDR=00:0C:29:97:74:DB
TYPE=Ethernet
BOOTPROTO=none
IPADDR=172.16.1.3
PREFIX=24
GATEWAY=172.16.1.1
DNS1=172.16.1.2
DOMAIN=internal.loghyr.com
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
UUID=539d9802-fe1a-4b44-8d80-8a03f35aa844
ONBOOT=yes
DEFROUTE=no