2015년 10월 11일 일요일

Emacs with racket-mode as a replacement for DrRacket

Recently I've been taking the UBC course Systematic Program Design (SPD) Part 2 on edX. The language used in the course is Basic Student Language (BSL) from the well-known How to Design Programs (HtDP 2nd Edition) curriculum. The DrRacket IDE used in the course is a very convenient tool containing an editor, REPL, stepper and even allows you to copy-and-paste images directly into the editor window after which they can be manipulated in programs.

In Part 1 of the course, I stuck with DrRacket despite being an Emacs user. Later when searching Google for info on using Emacs for HtDP languages and Racket, many Emacs users suggested Geiser mode, but recently a Racket-specific major mode called racket-mode has been developed and is available through the melpa package repository. If you are running Emacs 24+ you can enable melpa with the following line in your .emacs file:

(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)

Then M-x package-list-packages and C-s for racket-mode.

racket-mode works great and can even render images in the REPL:


One thing to watch out for when saving code that includes copy-and-pasted images in the DrRacket editor window, however, is that the saved file will be in a special binary format that is not version control friendly. If you want to use git to track changes in your BSL / Racket code, for example, your code needs to be in text format.

A DrRacket binary file will have a header that looks like the following:

#reader(lib"read.ss""wxme")WXME0108 ## 
#|
   This file uses the GRacket editor format.
   Open this file in DrRacket version 5.3 or later to read it.

   Most likely, it was created by saving a program in DrRacket,
   and it probably contains a program with non-text elements
   (such as images or comment boxes).

            http://racket-lang.org/
|#

In the starter files provided by the instructors, all the comment boxes are graphical; this will also cause your BSL source files to be saved in binary format. To avoid this, you can convert graphical comment boxes to pure text comments by clicking anywhere inside the comment box, opening the Racket menu and selecting Comment Out with Semicolons:



Note you can also create block comments in BSL or Racket with #| some text |# (hash+pipe some text pipe+hash). Regular line comments are denoted by semicolon(s).

In the programs you have to write for HtDP and the SPD edX course, images will be frequently incorporated into your programs. The best way to avoid having your source files become binaries is to not cut-and-paste images directly into the DrRacket editor window. There is a function called (bitmap ...) that is part of the 2htdp/image library that allows you to refer to an image in a file other than your source file.

For example:

(require 2htdp/image)
(define test-image (bitmap "images/cloud.png"))
test-image
(flip-vertical test-image)
(scale 0.5 test-image)

The path to cloud.png is relative to the location of the current open file. Since the image file is not contained in the source, it will not become a big ugly binary when saved.

The results of the code above in the racket-mode REPL window:


Now all you have to do is tell your version control system to ignore all files in the images folder. Since I use git, I added the following file formats to .gitignore in my repo directory:

#Tell git to ignore image files
*.jpeg
*.jpg
*.bmp
*.png
*.gif
#ignore temp files
*~

Now you should be all set to use Emacs as your development environment for HtDP 2e and the UBC Systematic Program Design courses!

References:

http://stackoverflow.com/questions/17895038/best-way-to-define-an-image-variable-in-racket

http://stackoverflow.com/questions/12674288/how-to-run-racket-in-emacs/12675896#12675896


2015년 10월 4일 일요일

Disappearing evalauation period days on Win7 trial VM's from Modern.ie

I use Win7 VM's from modern.ie on both a Linux machine (running Archlinux 4.2.2 kernel) and a Win10 machine. The Win7 VM's are very convenient because they give you an evaluation period of 90 days and the trial can be rearmed up to 3 times for a total of 360 days of use. This is irrespective of whether you have saved a snapshot of your VM; once the snapshot is restored, the number of days that have elapsed since the first installation will be used to calculate how many evaluation days you have remaining.

I installed a Win7 VM for a Linux host just 30 days ago, but when I resumed from a save state, the VM told me my evaluation had expired! I thus rearmed the evaluation period using slmgr/rearm from the windows command prompt cmd.exe (which must be run as Administrator). I expected to see that I would be given 90 additional days of use, but I got the following:



From the screenshot (click above to expand) you can see that after the rearm, only 10 days are remaining (although 90 should be granted) and that there are 4 rearms remaining...

On a laptop running Windows 10 (host), the Win7 VM (guest) from modern.ie runs just fine in Virtualbox and the evaluation period counts down correctly. You can see that I have 54 days remaining on this VM:



I wonder what happened to the Win7 VM on the Linux host that caused the evaluation period timer to get messed up...

Postscript Dec. 20, 2015

The first time you boot your new Win7 VM, you will be asked whether you would like to go online to validate your installation (connect to the licensing server). If you don't connect to the licensing server at least once, your VM will only be valid for 10 days. Although it is possible to reset the counter 3 times, unless you validate online you will only be given 10 days of usage at most. After running slmgr/rearm  if you still only have 10 days, run slmgr -ato for activation.

2015년 9월 27일 일요일

Living life in the tty

I have a an old Acer Aspire One D257 with 2GB of RAM which I purchased back in 2011 and have happily run a succession of Linux distro's like Debian, Ubuntu, and Archlinux on it. On purpose, I have only used lightweight Desktop Environments like LXDE and Openbox on this netbook to keep the system resources used to a minimum.

Unfortunately, In the past year or two, everyday browsing on the netbook has become too slow, with modern browsers easily taking up more than 1 GB of RAM with just a few tabs open (Chrome/Chromium is a memory hog). For example, if I have gmail, Trello, Slack, and a Google Drive document open in separate tabs, the Intel Atom processor has a hard time keeping up. This doesn't even take into account non-browser apps I might be running, like QuodLibet music player or daemons for Dropbox and SpiderOakONE. Due to sluggish performance, I decided to say get rid of the overhead for an X11 graphical desktop.

My Acer D257 has found a new lease on life as a tty-only machine which I ssh into from my primary notebook. I was partly inspired by reading K. Mandla's blog which chronicles his adventures testing command line apps on obsolete hardware. After connecting over ssh, I launch a GNU Screen session with the following script:


I then connect to the detached session with screen -r (you can see a list of detached sessions with screen -ls)


In the screenshot, you can see several GNU Screen tabs created by the script above. cmus is playing Internet radio, htop monitors CPU and memory for each process, and irssi with bitlbee daemon allows me to use irc to connect to Google Chat. In addition, I have the dropboxd and SpiderOakONE daemons running in headless mode so that my files on Dropbox and Spideroak get synced even when I'm not in a graphical session. Dropbox offers a script, dropbox.py for running dropboxd from the command line. This script has been packaged in AUR for Archlinux in the dropbox-cli package. In the case of SpiderOakONE, you can launch the daemon from the command line using the --headless option.

Here is a simple script that launches both daemons in the background when in a tty session:


In addition, I am running an NFS server for my LAN from this netbook -- all of this within 376 MB! In the screenshot above, the GNU Screen caption line shows the time, DoW, month, date, hostname, and a list of tabs that will expand to the right while properly reflowing even if the number of tabs goes off the right edge. You can find this caption setting in my .screenrc file from my dotfiles repo on Github.

In a series of posts I will talk more about cmus command line music player (that also supports Internet radio) and setting up irssi + bitlbee so you can connect to instant messaging services using an IRC client.

2015년 9월 20일 일요일

Using xml software lists in sdlmame 0.165

In May 2015, mamedev finally decided to merge MAME and MESS into one monolithic build. Now if you install sdlmame through your Linux distro's package manager, you can emulate arcade hardware (MAME) as well as hundreds of home computer systems and consoles (MESS) including the c64, apple2, amiga, original macintosh, etc.

One oddity is that in Archlinux, at least, the installation of sdlmame does not include hashes for using software lists, which contain lists of known software for each hardware platform in MESS (note that software lists for many platforms like apple2 are not yet complete). The path for software lists is $HOME/.mame/hash/ which contains xml files using the schema defined below:

http://www.mess.org/mess/swlist_format

After installing the sdlmame binary package, you can find the xml software lists from the mamedev/mame repo on github at the following link:

https://github.com/mamedev/mame/tree/master/hash

You can right-click to save the software list .xml file you are interested in, or if you want to download all lists, you can just download a .zip of the entire tree from the main project page:

https://github.com/mamedev/mame/archive/master.zip

After extracting the archive to your hard drive, navigate to the location of mame-master and copy all the contents of the hash subfolder to $HOME/.mame/hash

If you are using a GUI frontend to sdlmame (I recommend QMC2) don't forget to specify the path to the hash directory in the global configuration. Now if you select a certain HW platform, say apple2 you should see a list of all known software for that platform:


Let's say I want to play Archon for the apple2 -- if I have the necessary floppy disk image(s) in my ROM directory (this path must be configured in $HOME/.mame/mame.ini), I can launch it from the software list on the right of the QMC2 screen by highlighting the program and pressing ENTER or double-clicking it.

The problem I encountered, however, is that launching programs from the MESS software list requires that the name of the local disk image file exactly match the one specified in the xml file. If you have downloaded apple2 disk images from ROM sites, you will know that for any given program, there is rarely just one canonical file; instead there are often several different images available in differing formats like .do .dsk .nib etc. In addition, the CRC32 and SHA1 hash values for downloaded disk images are often different from the those specified in apple2.xml

When invoking sdlmame from the command line, it is able to recognize disk images stored inside .zip archives, but when trying to launch programs from the software list in QMC2, .zip archives are not recognized (you will get file not found errors). If the compressed disk images are extracted and renamed to exactly match the name of the rom/images specified in the xml file, you will be able to launch the program in QMC2 even if the CRC's and SHA1 hashes don't match, although you will get a warning in the Emulator Log tab.

In contrast, when launching some floppy images using sdlmame from the command line, images within .zip archives launch just fine:

[archjun@latitude630 apple2]$ sdlmame apple2e -flop1 /MULTIMEDIA/ROMs/apple2/"Empire - Wargame of The Century (1987)(Interstel)(Disk 1 of 2 Side A).zip"
Value 1 not supported for option sound - falling back to auto
Average speed: 98.29% (239 seconds)

It would be much more convenient to launch disk/cart/rom images through the QMC2 GUI, but unless I am using the exact same image specified in the software list xml file, I will get a file not found error.

We can easily add a new entry to the apple2.xml software list, however. Let's take a look at an existing entry for archon2:

We can copy this template and change the fields software name, description, year, publisher, size (in bytes), rom name, crc, and sha1. As an example, I will create an entry for Snooper Troops Case of the Granite Point Ghost.

I originally used cksum from GNU coreutils to calculate the CRC32:

[archjun@latitude630 apple2]$ cksum "Snooper Troops and the Case of- The Granit Point Ghost (1982)(Spinmaker Software Corp).dsk" 
20123348 143360 Snooper Troops and the Case of- The Granit Point Ghost (1982)(Spinmaker Software Corp).dsk

The highlighted value is in decimal, but sdlmame expects the checksum to be in hex:

[archjun@latitude630 apple2]$ printf '%x\n' $(cksum "Snooper Troops and the Case of- The Granit Point Ghost (1982)(Spinmaker Software Corp).dsk" | awk '{ print $1 }')
1330ed4

I was mystified when QMC2 kept complaining that the expected crc in the xml file failed to match the calculated checksum. Reading this post from 2011 by Box.com engineers, I learned that cksum has a strange way of calculating crc32 compared to other implementations:

We discovered that Unix cksum differs from other CRC generators because it uses the polynomial table twice; it puts the file's bytes through the polynomial, but then also puts the length of the file through the polynomial as well, which is not mentioned anywhere in any documentation.

I tried another command line crc32 utility called crctk which generated a proper checksum:

[archjun@latitude630 apple2]$ crctk -c "Snooper Troops and the Case of- The Granit Point Ghost (1982)(Spinmaker Software Corp).dsk"
[Snooper Troops and the Case of- The Granit Point Ghost (1982)(Spinmaker Software Corp).dsk] 1EE9FEC2 (note this crc32 differs from 20123348 returned by cksum from coreutils)

I want the hex crc32 to be in lowercase, however, so I first pipe it to awk to print the last column and then pipe to tr from GNU coreutils to convert from upper to lowercase:

[archjun@latitude630 apple2]$ crctk -c "Snooper Troops and the Case of- The Granit Point Ghost (1982)(Spinmaker Software Corp).dsk" | awk '{ print $NF }' | tr [:upper:] [:lower:]
1ee9fec2

Now I will add the following entry to apple2.xml using a text editor:

From the QMC2 menu, Tools -> Clean Up -> Clear Software List Cache, and then click Reload all information from the software list buttons on the right to apply changes to the apple2.xml file.

Note that the software name must be at most 8 letters as well as unique within the xml file. Now launching the new disk image snptrpgp from the software list works. Note that the rom name field must be populated by a non-archived disk/cartridge image, meaning you cannot use a .zip file here. This is odd, because when launching MESS-supported systems from sdlmame on the command line, it is possible to specify a disk image that is located inside a zip archive.

There are perhaps hundreds of software titles for the apple2 and c64 which are absent from the MESS software lists, so I inquired in the #messdev IRC channel on EFNET about the possibility of adding titles to the apple2.xml software list and submitting a pull request to the mamedev/mame github repo. I was told that mame developer R. Belmont is responsible for adding titles to the list for apple2, and that he would populate the xml file soon.

Until then, it is probably better for me to launch random MESS roms and disk images from the command line instead of tediously creating software entries in the xml software lists.

2015년 9월 13일 일요일

Truncating a file when the noclobber option is set

On a recent service call, a client asked me if there was a way to get rid of an enormous log file (> 10 gigabytes) without using rm which would cause high I/O load on a production system. I told the client to use the redirect operator to truncate the file to an empty file.

In normal cases, simply doing

> fileName

which is equivalent to

cat /dev/null > fileName

will do the trick.

When the client tried this, however, he got the following error message:

File exists

A quick google search revealed that this error is returned when the noclobber option is set in .bashrc or the configuration file for your shell of choice (ksh, csh, etc).

To override noclobber just once, you would use the >| operator in bash:

>| fileName

The server in question happened to be using C-shell, however, so the noclobber redirect override should be >!

>! fileName


References:

http://www.linuxhowtos.org/Tips%20and%20Tricks/Protecting%20files%20with%20noclobber.htm

http://stackoverflow.com/questions/2423281/how-to-empty-truncate-a-file-on-linux-that-already-exists-and-is-protected-i

2015년 8월 23일 일요일

Administering a Linux system through HP integrated Lights Out (iLO) port

I recently had to work on some HP Proliant BL460c Gen 8 blade servers contained in a 7000c chassis. It is interesting to note that each blade does not have its own network ports; all the ports are provided by the 7000c chassis. Here is what 16 blades installed into a 7000c chassis look like (front view, rear view):



There was a KVM switch connected to the chassis, but for some reason keyboard input wasn't being properly passed on to the machines. Fortunately, an HP hardware engineer was on hand to show me how to connect to individual blades using the iLO port on the 7000c chassis.

The HP iLO port on Proliant servers looks just like a regular Ethernet port but is always labeled iLO to distinguish it from a other network ports. You can assign a fixed IP to the iLO port in the BIOS or even assign an IP if you are running a DHCP server on your laptop which is connected to the iLO port. In this particular case, the HP engineer had already entered BIOS and assigned the IP 192.168.0.100 to the iLO port, so I simply connected my laptop to the iLO port with a cat6 Ethernet cable.

The default iLO user:pass was admin:hpinvent and connection to iLO can be made via telnet, ssh, and http. I connected via ssh as follows:

[archjun@lenovoS310 ~]$ ssh admin@192.168.0.100

-----------------------------------------------------------------------------
WARNING: This is a private system.  Do not attempt to login unless you are an
authorized user.  Any authorized or unauthorized access and use may be moni-
tored and can result in criminal or civil prosecution under applicable law.
-----------------------------------------------------------------------------
Firmware Version: 3.71
Built: 12/07/2012 @ 13:26
OA Bay Number:  1 
OA Role:        Active 
admin@192.168.0.100's password: 






HP BladeSystem Onboard Administrator
(C) Copyright 2006-2012 Hewlett-Packard Development Company, L.P.


Type 'HELP' to display a list of valid commands.
Type 'HELP ' to display detailed information about a specific command.

Type 'HELP HELP' to display more detailed information about the help system.

As this was my first time working with HP iLO, I referred to the HP BladeSystem Onboard Administrator Command Line Interface User Guide. The chassis had 16 BL460c servers installed, so I first needed to obtain a list of machines to connect to.

OA-10604BA59737> SHOW SERVER LIST

Bay iLO Name                      iLO IP Address  Status   Power   UID Partner
--- ----------------------------- --------------- -------- ------- --- -------
  1 ILOSGH3280A6K                 192.168.0.200   OK       On      Off 
  2 ILOSGH3280A66                 192.168.0.201   OK       On      Off 
  3 ILOTW36NP1543                 192.168.0.202   OK       On      Off 
  4 ILOSGH3280A5V                 192.168.0.203   OK       On      Off 
  5 ILOSGH3280A6P                 192.168.0.204   OK       On      Off 
  6 ILOSGH3280A5P                 192.168.0.205   OK       On      Off 
  7 ILOSGH3280A6V                 192.168.0.206   OK       On      Off 
  8 ILOSGH33013W5                 192.168.0.207   OK       On      Off 
  9 ILOSGH3280A5H                 192.168.0.208   OK       On      Off 
 10 ILOSGH33013W7                 192.168.0.209   OK       On      Off 
 11 ILOSGH3280A7C                 192.168.0.210   OK       On      Off 
 12 ILOSGH3280A5C                 192.168.0.211   OK       On       *  
 13 ILOSGH3280A6S                 192.168.0.212   OK       On      Off 
 14 ILOSGH3280A7A                 192.168.0.213   OK       On      Off 
 15 ILOSGH3280A5X                 192.168.0.214   OK       On      Off 
 16 ILOSGH3280A62                 192.168.0.215   OK       On      Off 
Totals: 16 server blades installed, 16 powered on.

 * = Blade UID is blinking and a critical operation is being performed on the blade (firmware update in progress or remote console in use).

According to the command reference I linked to above, it is possible to connect to a specific blade using the following command syntax:

CONNECT SERVER [SERIAL] : Opens a Text Console session to the iLO
specified. If the optional argument SERIAL is specified a Virtual Serial Port
session is started.

I wanted to connect to blade #12, so I entered the following:

OA-10604BA59737> connect server 12

Connecting to bay 12 ...
User:OAtmp-admin-55B87738 logged-in to ILOSGH3280A5C.(192.168.0.211 / fe80::da9d:67ff:fe67:6a65)
iLO 4 Standard Blade Edition 1.22 at  Apr 19 2013
Server Name: SLDJ-AGCF_002B
Server Power: On




</>hpiLO->


After typing help from the hpiLO prompt, I noticed the following CLI commands of interest:

...
HP CLI Commands:

POWER    : Control server power.
UID      : Control Unit-ID light.
NMI      : Generate an NMI.
VM       : Virtual media commands.
LANGUAGE : Command to set or get default language
VSP      : Invoke virtual serial port.
TEXTCONS : Invoke Remote Text Console.

TEXTCONS looks promising...

</>hpiLO-> TEXTCONS

status=2
status_tag=COMMAND PROCESSING FAILED
error_tag=COMMAND ERROR-UNSPECIFIED
Wed Jul 29 18:06:07 2015

iLO Advanced License required for this functionality.

This was a disappointment. According to the HP iLO v4 user's guide p.212, it is still possible to get a remote console even if you don't have an iLO Advanced license by using a Virtual Serial Port (VSP) and connecting to a linux installation over serial console. This would require, of course, that you edit the KERNEL= line in /boot/grub/grub.conf and append serial console settings like console=ttyS0,115200 for example.

Fortunately, I learned from the HP hardware engineer that iLO has a nice web management interface. I pointed my browser at the IP address assigned to the iLO port (192.168.0.100) and after entering the login credentials admin:hpinvent, I was able to access individual blades via remote console by clicking the button Integrated Remote Console. The downside is that the Integrated Remote Console only works on Windows clients with Internet Explorer (which supports ActiveX). I had to load a Windows VM with bridged network in order to use the Integrated Remote Console session.

The Integrated Remote Console session for Windows clients also allows you to mount USB sticks or .iso images locally and have them accessible to the remote machine. If you don't have a Windows machine or VM handy, on Linux you can still get a remote terminal through the iLO web management interface by clicking Remote Console (not Integrated Remote Console, which is Windows-only) but this requires that you install the Iced Tea web plugin before hand, as Remote Console requires Java web plugins.

One thing that is inconvenient about both types of remote consoles accessible through the iLO web interface is that the sessions are not text-based TTY or PTY sessions, but emulated graphical sessions! This means that you cannot copy-and-paste anything to and from these screens, which is a big inconvenience. If you absolutely need a pure text remote console, you will either have to buy an iLO Advanced License or enable the Virtual Serial Port so you can connect to your Linux installation over serial console through the iLO port.

2015년 8월 16일 일요일

Using Systemrescuecd LiveUSB over serial console

Recently I found myself without any RHEL DVD's or liveUSB's when encountering a server that failed with disk errors on reboot. At work I mostly deal with servers using Redhat Enterprise Linux versions anywhere from 4.X(!!) to 7.X, so I used to carry around a CD case containing RHEL v.4~7 DVD's. This is a hassle because some servers don't have optical drives and it's inconvenient to carry around a bunch of CD/DVD's.

I therefore thought it would be a good idea to create liveUSB's of RHEL so I could boot into Redhat rescue mode when servers fail to boot or have disk errors, but creating live USB media from RHEL iso images isn't straightforward.

For RHEL 7.X, Redhat recommends using dd to write the iso file onto a USB memory stick, but this method doesn't seem to work when used with DVD iso files for RHEL5. Unfortunately, the server that failed to boot was running RHEL 5.8. Luckily, I happened to have a 2GB USB stick in my backpack that had SystemRescueCD v. 4.5.1 installed as a liveUSB (as of Aug 2015, the most recent version is 4.5.4).

SystemRescueCD is a very handy liveCD/USB distro for repairing filesystems, editing partitions, recovering MS Windows passwords, etc. on host systems with boot, storage, or other problems.

I had used this utility distro on personal machines (netbooks, laptops, desktop) at home, but on this particular day, I was working on an ATCA MPCBL0030 (Intel) blade with no separate video output. Also no KVM switch was available on the rack, so the only way to interact with the server was over serial console.

In order to boot Linux and see all output over serial console instead of on a monitor, it is necessary to edit the kernel parameters in the boot loader. In the case of RHEL, you would press 'e' at the GRUB menu on the selected kernel and then add the following at the end of the line kernel= (assuming a baud rate of 57600 bps):

console=tty0 console=ttyS0,57600

Since SystemRescueCD version 0.26, serial console support is compiled into the linux kernel, so adding serial console options to the end of the kernel line in the bootloader works just fine. The kernel parameter syntax will differ slightly from that used above for RHEL, however.

Once the server booted into the SystemRescueCD liveUSB menu, I selected option C) Standard 64-bit kernel (rescue64) with more choice which is the 5th from bottom:



I then highlighted option 5. SystemRescueCd with a console in 800x600 and pressed [TAB] to edit the kernel parameters:



At the bottom in white text, you can see the kernel parameters

.linux rescue64 video=800x600 initrd=initram.igz

Note: the _ in the screenshot above is the cursor, not an underbar character!

Remove the parameter video=800x600 and append console=ttyS0,baudRate text to the kernel line so that it looks like the following:

.linux rescue64 initrd=initram.igz console=ttyS0,115200 text

After editing the kernel parameters, press [ENTER] and SysRecCd will boot the Linux kernel with the options specified. You should be able to observe the boot messages over serial console using your communication program of choice (i.e. screen, putty, minicom).

You can see that the serial console kernel parameters used for SystemRescueCD differ from those used in RHEL. RHEL requires two consoles to be specified, console=tty0 console=ttyS0,baudRate but I couldn't get serial console output working in SysRecCD when using the RHEL syntax.

I used a serial console baud rate of 115200 bps because that's what the MPCBL0030 supports.

SystemRescueCD includes almost all the CLI disk utilities you can think of as well as GUI tools like gparted. Of course, since I was working over serial console, I didn't want to enter runlevel 5 and launch X11.

From the command line, I then checked if the server's disks and partitions were being recognized with fdisk and tried to repair the ext3 filesystem using fsck. As the liveUSB was detected as /dev/sda, the local disk on the server appeared as /dev/sdb. Inititally fsck -a /dev/sdb1(2,3...) failed, but e2fsck -f -y /dev/sdb1(2,3 ...) succeeded in correcting the errors in the ext3 filesystem caused by inode corruption.

After a reboot, the GRUB menu finally appeared and RHEL 5.8 booted without any problems. I highly-recommend carrying around a liveUSB containing SysRecCD instead of RHEL media for rescue mode!