Jim's Depository

this code is not yet written
 

I used to test web pages for IE compatibility by walking around the office, finding a person with IE and asking them to pull up the page. I can’t do that anymore, and it doesn’t seem likely to work well if I go to the local coffee house and try it on a stranger, so I have found a new solution.

Microsoft makes VPC (virtual PC) system images available for minimal OS + IE installs for IE6, IE7, and IE8, some on both Vista and XP. Download details: IE App Compat VHD (These are timebombed and die after a few months, and look in the ReadMe.txt file for passwords.)

These can be run in VirtualBox on Windows, Mac OS X, Linux and Solaris hosts. The initial boot is a little ugly as Windows gropes for drivers, but once you get the VirtualBox guest additions installed it is smooth.

On my 12+ month old iMac booting an XP machine with IE takes about 22 seconds (10 seconds in BIOS, 10 booting XP, 2 logging in), restarting one from saved state takes about 6 seconds. Once running they are snappy. They don’t feel any different from native applications.

You can find excellent instructions for running these under VirtualBox at zytzagoo’s den. These are written for linux users. I used linux for the unrar step but used my Mac for the VirtualBox machine.

If you want to test with more than one version of IE you will discover that Microsoft used the same UUID for all of the disk images (challenging the meaning of unique) and that VirtualBox is offended by that. You can read the also good instructions at Shape Shed and look at the Fixing Microsoft’s Duplicate Identifiers section for details on converting the image to a raw image and back to a VDI to get a new UUID.

My EEE PC is nearly a 900A, it was a bit crippled to be a super lower than low end Best Buy machine.

First I will create a nilfs2 rooted system on an SD card to verify the steps, then I will migrate that to the internal flash. I am running 2.6.30 with no init ramdisk. Most of the important bits are compiled in, some fringe stuff is a module.

  1. Read about aligning filesystems to flash erase boundaries. I have no idea what my device’s erase block size is, but surely it is a power of two and less than 128k, so I will use 128k. I can conceive of a test I could write to establish this, but will not do it.  Go read Aligning filesystems to an SSD’s erase block size | Thoughts by Ted to learn what I know.
  2. For some silly reason, my internal drive is sdb and my SD reader is sda. Keep that in mind, don’t trash your system if yours is different.
  3. Per Ted’s thoughts (see above) I did an fdisk -H 224 -S 56 /dev/sda and then created three partitions. A /boot at the front, this will be ext3 for grub’s sake, a single track partition 4 typed as 0xef for the BIOS quick boot, and the rest in the middle as my nilfs2 root. (I am willing to believe that this is a bad idea and that the GC of nilfs2 might be happier if I put my log files and such in a different place from my static files, but oh well.)
  4. mkfs -t nilfs2 /dev/sda2 is amusingly fast.
  5. Mount the new root on /mnt and the new boot on /mnt/boot
  6. debootstrap –arch i386 lenny /mnt YOUR-PACKAGE-SOURCE (find that from your /etc/apt/sources file) (I have to do this twice, the first time it complains that Packages.gz is corrupt.)
  7. chroot /mnt  this moves you to the new system. I “touch” a file at the root to identify it so I can tell where I am later… touch /SDCARD
  8. exit to leave the chroot.
  9. cp /boot/*2.6.30 /mnt/boot/  – you’ll want your kernel
  10. cp -arv /lib/modules/2.6.30 /mnt/lib/modules/2.6.30 – and it will want its modules.
  11. cp /etc/apt/sources.list /mnt/etc/apt/sources.list
  12. chroot /mnt
  13. aptitude update
  14. aptitude install locales  (we need to fix that storm of locale errors pending)
  15. dpkg-reconfigure locales (I choose nothing.)
  16. aptitude full-upgrade
  17. aptitude install openssh-server
  18. aptitude install nilfs2-tools (sad, 100MB of crap to install this)
  19. aptitude install grub
  20. mkdir /boot/grub
  21. leave the chroot and get some config files
  22. cp /etc/network/interfaces /mnt/etc/network/
  23. cp /etc/hostname /mnt/etc/
  24. cp /etc/hosts /mnt/etc/
  25. reboot, catch the boot at grub and change to the new root
  26. grub-install /dev/sda  (DANGER! This make break going back to the internal, since I used the internal grub to get here. Maybe manually make the /dev/sda* nodes so grub will work before the reboot?)
  27. Here goes… time to repeat in reverse to install on the internal flash.
  28. All is good. I am confused why my menu.lst file needs root to be (hd0,0) when I am on sdb, but I swapped the SD card for a blank one and I can still boot, so I’m not getting grub bits from there. Probably some BIOS stunt.
  29. Get the nilfs2-tools from squeeze, the one in lenny is too old to work.
  30. The kernel command line option root=UUID=xxxx or root-LABEL=xxxx don’t work because they are not kernel options, they only look like it and are handled in some common initrd programs.

After several days of use I can add:

  1. It feels better than the old ext3 install. That is a terrible metric, I’ll have to do something more rigorous when I get home.
  2. As installed it doesn’t reclaim disk space, it just fills up. If I manually run the nilfs cleanerd then it does reclaim space. For some reason the one Debian starts doesn’t work.

After 25000km of travel with the a nilfs2 root I have to say I like it a lot. Now to figure out why the Debian start of the cleanerd doesn’t reclaim space.

Hi Jim,

I noticed the same problem with the nilfs_cleanerd. Upgrading (from source, in my case) to nilfs-utils 2.0.13 solved the problem for me.

Niek
Flash erase block sizes are typically 4MB or a near power of two these days - pretty large.

Newer, more advanced SSD controllers such as those on the Intel SSDs make this irrelevant by being intelligent about small writes, but with SSDs like those on the Eee PC, you are stuck with erasing and rewriting entire 4MB or so block for small writes.  Hence why Flash writes are only high performing when writing 4MB or more.

Benchmarking a machine with a surplus of RAM introduces a difference between the first run and subsequent runs when any disk blocks needed are already cached. Fortunately, since 2.6.16 there is a mechanism to discard the caches, /proc/sys/vm/drop_caches.

I use this command to drop my caches between benchmark runs.

sync ; echo 3 > /proc/sys/vm/drop_caches

Note: that command was simplified thanks to anonymous’ comment.

As an example, building femtodns currently takes 2.1 seconds with flushed caches and 0.9 seconds on subsequent runs.

You can read more about /proc/sys/vm/drop_caches at Drop Caches - linux-mm.org Wiki

You don't need to echo 1, 2, and 3.  As the page you link to makes clear, it's a bit-mask.  Echoing 3 alone is succifient after the sync.

I’ve installed clicktoflash which stops Flash™ from running in Safari. The web is a much nicer place as a result. I detest things moving in my field of vision while I read.

Flash elements are rendered as gray rectangles, if you click on the rectangle it can run. If you Option+click, then it is whitelisted and can always run.

It could do with a little more user interface, there is really nothing visible now, but if you remember the Option+click and you never accidentally whitelist something you will be fine.

Note: If you want to remove it later, go to ~/Library/Internet Plug-Ins/ and take it out.

Attachments

Aw nuts, now I need to implement "delete attachment". The 1.3 version adds a little 'flash' badge instead of just a grey box and a way to edit your whitelist.

I've had no problems with this over the weeks I've been using it, in fact it has saved me from canceling my American Express card because their commercial no longer tries to play in my browser when I go to pay the bill.

propecia germany ??? I just turned 39 so the clock is ticking

Google watches me. Now I watch google. You will see a tiny google icon in the title bar of articles which have been scanned by the mighty G.

Following are my notes as I enable IPv6 on my servers.

  • The formatting of addresses changes. My lighttpd logs now start with addresses like ::ffff:1.2.3.3.  That ::ffff: is IPv6 speak for “an ipv4 address”. PHP5 also returns this new format when you as for \$_SERVER[‘REMOTE_ADDR’]. This has broken several bits of software that parsed addresses.

There will be more.

On the Google Finance pages you can get graphs of stocks, which if you mess with the “settings” tab, you can also display after hours trading. After hours trading is generally much lower volume and less volatile compared to normal hours. 

Notice on the image that the 7 normal hours seem rather large compared to the 17 off hours. The X axis is a nonuniform time axis, during normal hours it is 12 pixels/hour (a very programmery value to pick) but the off hours are about 7.6 pixels/hour (not a very programmery value, but perhaps it is really 23 of 12).

The end result is a harmonious display but with greater resolution in the more important data. Very nice.

(The sample graph is from the day Steve Jobs announced his medical leave from AAPL. Usually after hours is quite boring.)

Attachments

goog.gif 28691 bytes

Web surfing with U-Verse was getting annoying. I was regularly getting pages that would mostly load, but were delayed from 5 to 20 or more seconds in rendering because some elements failed to load. Noticing that the worst pages were ones with large numbers of DNS names to resolve I swapped my U-Verse supplied DNS server for OpenDNS and things became much faster. (I since swapped that to my own local bind9 because OpenDNS kept hijacking my web sites, this is also fast.)

You can see on my “time to ping google” network check exactly where I changed DNS away from AT&T’s servers.

Odd points to ponder: the DNS for www.google.com has a 5 minute life, short enough to expire between tests, but you’d think have it in cache from other client use once in a while. There is an odd quantitization in the earlier data for which I have no explanation. The other ping test running at the same time, by IP directly, does not show this effect and does not show a change at the DNS change.

******Moral:** Don’t trust your ISP for anything but packets in and out, and suspect they will screw that up too.

Note: This may or may not affect your U-Verse. I suspect they have many DNS servers and perhaps they aren’t all lame, or perhaps they have a throttling policy or something and they are all lame. Only you will know.

Attachments

dsn-change.png 20340 bytes

Today I challenge Google. I have placed a pair of google ads in the right hand column. Let’s see if Google can figure out what my depository is about. If Google chooses a coherent category for ads, I’ll replace the page subtitle with their impression of this site.

So far I’m a little insulted. They are pushing… how to say without using the word… “spectacles to protect your vision organs”, and “graphic designers”. I don’t think they care for my look.

Ack! Google is giving me annoying animated graphic ads. I signed up for "text and image" ads, apparently they consider distracting animations to be an image.
Those google ads are nice. I almost never get enticed by an ad, but two of the google ads on this site have lured me into visiting the advertiser. (Google's terms forbid me from clicking, so I have to type in the URL.)

Virtually 100% of the writing on this site is mine, so they have their little demographic cross hairs right on my brain, and it works.

I find myself missing a flow of control construct in C. Let’s say I want to locate a value which might come from a number of sources then do something with it.

if ( code == 36) value = 99; else { // a bunch of code to see if it is in the cache if ( code_in_cache(code)) value = code_from_cache(code); else { // notice how each place I have to look is  //accumulating nesting?
… }
}

If I were willing to split the code into a separate function I could just use return e.g.

int gratuitous_function( int code) { if ( code == 36) return 99;
// a bunch of code to see if it is the cache
if ( code_in_cache(code)) return code_from_cache(code);
// notice how I am not accumulating nesting?

}

That is better, but I don’t like breaking the linear flow of the program and it is likely that the function will require access to many of my local variables making a complicated interface. Worse, I may be setting several values and that gets ugly.

I generally try to cope like this…

do {

if ( code == 36) { value = 99; break; }
// a bunch of code to see if it is in the cache
if ( code_in_cache(code)) {  value = code_from_cache(code);  break;  } // notice how I am not accumulating nesting? … } while(0);

That works fine until I locate the value inside a for loop, then the break will take it out of the for loop.

I think what I really want is a named block…

block foo {

if ( code == 36) { value = 99; break foo; }
// a bunch of code to see if it is in the cache
if ( code_in_cache(code)) {  value = code_from_cache(code);  break foo;  } // notice how I am not accumulating nesting? … }

I guess I could always be a barbarian just use a goto and a label.

Why not simply:

if (code == 36) {
   value = 99;
} else if (code_in_cache(code)) {
   value = code_from_cache(code);
} else if (...) {
   // Notice how there is no nesting?
}

Oh, I neglected the "// a bunch of code to see if it is in the cache" part.  Yeah, don't be afraid of using goto-s.  There's nothing wrong with them when used properly.
Yes, it is that bit of logic that makes the } else if { not work.
more articles