technology
2009-08-02
Oral examinations — C/Unix
In the process of sorting through archives and old stuff, I found a collection of sticky notes that colleagues and I used five years ago to evaluate students at EPITA. These were oral examinations with no computer, only pen and paper or whiteboard. As I am recycling the paper, here is the transcript for archival.
- each page of the Unix User Manual belongs to one of its sections. Give the title of each of the first three sections.
- given two C++ strings
s1ands2representing two large numbers expressed in baseb(each character is a digit), write an algorithm that returns the sum (as a C++ string of digits) expressed also in baseb. - what is the canonical mode for a terminal? Explain.
SIGKILLandSIGSEGVexcluded, give the name of 5 signals, their meaning and their use(s).%d,%iand%xexcluded, give 5 distinctprintfformat conversion specifiers.- give 6
gccoptions and explain them. Only the options properly explained are accepted. - give the library function names and data types involved in reading a Unix directory.
- given a
makemacro named SRC defined to an arbitrary list of Texinfo file names (e.g.SRC = foo.texi bar.texi ...), write aMakefilewhich creates PostScript and PDF output for these sources, using commandstexi2dvi,texi2pdfanddvips. - given a 2D character array (dimensions
WandH) with each cell set toXorO, representing respectively ground and water (it's a map), write an algorithm which takes the coordinates of two points and which returns true if and only if one can swim from one point to the other. - write an algorithm which takes two strings as input and returns true/false according to whether the two strings are anagrams of each other (e.g.
abc/bca -> true,aab/bba -> false). - given an array of zeros and ones, write an algorithm that returns the index in the array which maximizes the sum of the number of zeros on the left and the number of ones on the right (e.g.
001101 -> 2). - given the expression
printf(1["foo"]), comment. - given a sorted integer sequence
sand an integern, write an algorithm which returns the value inswhich is closest ton. - write an algorithm which takes a string representing an arithmetic expression as input and which returns true if and only if parentheses are properly balanced.
- write an algorithm which takes a character string as input and returns the character with the most occurrences.
- given a 2D character array (dimensions
WandH) with each cell set toXorO, representing respectively ground and water (it's a map), write an algorithm which returns the sum of the lengths of the coasts. Each cell side counts for 1. - given a directed graph structure
G, an operatorVwhich for a given graph returns the set of nodes, and an operatorTwhich for a given nodenreturns the set of nodes accessible fromn, write an algorithm which takes a graph as input and returns true if and only if the graph contains cycles. - to establish a connection with a client, a TCP server on Unix must call four library functions; give their name and the call order.
2007-06-02
Using the Brother printer drivers with FreeBSD
It is possible to use the Linux printers provided by Brother with CUPS on FreeBSD, instead of the generic ghostscript-based equivalents.
A while ago I acquired a Brother laser printer, model HL-2030. This is a cheap printer with excellent printing quality (up to 1200dpi) and power saving features. Moreover, it supports the standard printer language PCL-5 which makes it “polite” to free and open operating systems — such as, GNU/Linux and FreeBSD.
On Linux, the Brother printers are fairly well supported. There is a lot of information on what drivers to use on LinuxPrinting.org and several good hints for the printer HL-2030 are hinted there as well. Brother also provides official Linux drivers that give access to all the printer features.
Using the generic driver
Unfortunately, Brother “officially” indicates that they do not have specific drivers for FreeBSD, and that FreeBSD users should use the generic drivers. Of course, using this printer (as well as many others from Brother) with FreeBSD is possible using CUPS and the generic printer drivers provided in the packages Gutenprint and/or Foomatic. For example, with my HL-2030 printer I proceeded as follows to use the generic driver:
- install and setup CUPS (not covered here, there is a section for it in the FreeBSD documentation)
- setup appropriate permissions on /dev/unlpt0 (USB device for the printer) — I used root:cups 0664
- generate and download the PPD file for HL-2060, (HL-2060 is a compatible printer)
- setup CUPS to use this PPD file and the USB device (use device "no-reset") to reach the printer.
That works very well, but I wasn't satisfied because it supports only resolutions up to 600dpi, and the paper margins are not well defined.
Using the Brother driver
Hopefully, I found possible to use the official Linux drivers provided by Brother on FreeBSD. This is made possible by the Linux emulation layer on FreeBSD.
Note the following:
- CUPS should already be installed and running, and the printer should have been tested first using the generic driver as described above. Rationale: if the printer or the USB device somehow don't work, the official driver can't do anything about it.
- This has been tested on FreeBSD 7.0 for i386 (32bit). See notes below for some hints for the x86_64 architecture (64bit) and other versions of FreeBSD.
Here are the steps:
- install the Linux compatibility libraries through port emulators/linux_base-fc7. Likely you need to set the Linux kernel version high enough prior to installing the port, using for example
sysctl -w compat.linux.osrelease=2.6.9(save to /etc/sysctl.conf to make the setting persistent). - install print/psutils which contains
pstopsrequired by the Brother drivers. - download the LPR driver and CUPS driver for your printer from Brother. Download specifically the Debian .deb files.
- extract manually the contents from the .deb files. They are .tar.bz2 files in disguise: use the command
tar -xjf - place manually the files in the appropriate FreeBSD directories:
- .so in /compat/linux/usr/lib
- bins in /usr/local/bin
- Brother-specific files in /usr/local/Brother
- CUPS data+filter in /usr/local/share/cups and /usr/local/libexec/cups
- edit all the script files included in the .deb and change the following:
- all references to files included in the .deb should be modified to point to their new FreeBSD location
- references to other tools (gs, pstops...) should be modified to point to /usr/local/bin instead of /usr/bin
- use path to USB device /dev/unlpt0 instead of /dev/usb/...
- the LPR installation script may contain commands to change the owner/group of files in /var/spool/lpd. Replace with user "root" and group "daemon" instead of the default "lp".
- open the "postinst" scripts from both .debs and read what commands they use to setup the printer, and execute them manually (LPR driver first, then CUPS driver). This should register the Brother PPD file into CUPS and create the printer configuration.
Et voilà!
If anyone volunteers to create a FreeBSD port, that would be great.
Special Notes
Users of FreeBSD x86_64: the binaries and libraries provided by Brother are compiled for Linux 32-bit. You need to ensure that your linux_compat package supports running 32-bit binaries.
Previous versions of FreeBSD: you are on your own. The steps above are untested. It may be that the USB stack in previous versions of FreeBSD (than 7.0) cannot send data to Brother printers.
USB device: the standard USB printer device file on FreeBSD (/dev/ulpt0) fails with (some) Brother printers. Use the non-reset /dev/unlpt0 instead. This works. The drawback is that the printer needs to be switched off and on when an error occurs (the driver cannot reset the printer using this device).
2007-04-26
FreeBSD 7, ZFS, GEOM, USB, don't panic!
A new computer at home was the occasion to experiment with FreeBSD. Eventually, I gave up — for now.
Last week my company sold old hardware for a bargain price. I got one, a dull Dell machine self-named "Optiplex GX 260". It gained a place in my home next to Albert — my plant — and also a new name: "fungus".
Fungus was the occasion to refresh my experience with FreeBSD. I have very fond memories of this operating system, which I used in the past for network services; this week, I wanted to extend my knowledge of the system by trying out the new features and checking its compatibility with various pieces of hardware which prove burdensome to use with Vodka-Pomme, my iBook.
Suffice to say, I am not too proud with the results.
It did begin quite well. Well, not that well. The system fails to boot with the default settings, due to a faulty hardware feature (broken ACPI) which is not (yet) worked around by software. Only some research brought me the magic string required to move to the next step: hint.apic.0.disabled=1
Damn the bogus Dell hardware.
For the installation I used the April snapshot of the 7.0-CURRENT branch, the brand new stuff scheduled to be released later this year. My purpose in using the latest and greatest (and I had to expect, also unstable) was to benefit from the recent inclusion of the ZFS filesystem into FreeBSD.
Installation went smoothly, and I could perform the following operations with much success and pleasure — pleasure to feel in known territory, pleasure to discover the changes since the last time I used the same steps:
- load updated system sources from CVS
- rebuild and install the world and a custom kernel
- install some shells and utilities
- configure some networking and connect to IPv6
Everything went smoothly so far and I could nearly believe that I was on the road to success for all my plans with Fungus: file server, webcam controller, ip6 gateway, scanner controller, and maybe some more! Spare time allowing, of course.
Before going to work last morning, I plugged in the USB flatbed scanner — CanoScan Lide 500F, based on chipset GL841 — and decided to give a try at SANE using a remote access to Fungus during the day.
It turned out that:
- the scanner is not supported by SANE (bad)
- it disconnects itself from the USB bus when it receives data it does not like from the driver (good)
- my first attempt at hacking some SANE parameters to forcibly attach the closest matching driver (sane-genesys) to the scanner caused the scanner to disconnect (bad, I was 10km away)
- my second attempt (back home in the evening) involved actually changing the source code of the driver to extend its compatibility to the model of my scanner. It was met with the scanner disconnecting again (bad) and a kernel panic. (doubleplus bad bad)
No amount of quick-'n-dirty hacking would avoid me doing the work of the developers of sane-genesys. Since I did not have either time nor knowledge to proceed, I decided that my scanner would keep its place somewhere next to Vodka-Pomme.
Next attempt was plugging in an USB Creative WebCam which I sometime use to capture short movies or interact visually with friends over the internet.
It turned out that:
- there is no infrastructure for video capture on FreeBSD, like V4L on Linux - therefore, no standard driver interface (kinda bad, mostly inconvenient since no generic capture program is thus available)
- the only existing driver, a port from the Linux driver using a system glue adapter, does not compile out of the box — I had to manually tweak the sources to workaround some incompatible definitions of the system call "msleep" (some time wasted, bad)
- the driver triggers a storm of kernel messages upon load (bad)
- no data is actually returned by the driver upon request of a picture from the camera (very bad)
- unloading the driver after the tests causes a very verbose kernel panic (doubleplus bad bad)
At this point I decided that my webcam would also keep its place somewhere next to Vodka-Pomme, and I abandoned any hope of using FreeBSD for multimedia purposes.
It was therefore obvious that I should focus back on my main project, which was setting up a file server.
That was easier said than done. Most of the data I want to serve is stored on two mirrored hard disks connected via USB. My primary goal is ensuring redundancy at all times, so that loss of one disk does not cause loss of all the data (sorry for stating the obvious). The secondary goal is to be able to take away one of the disk at any time to access the data using a different computer if needed, and still be able to plug it back into the main system afterwards and synchronize with the first disk. This later “feature” seems simple enough to me, and this is already what I am doing with the software RAID driver of MacOS X.
For this purpose, four different mirroring systems as available on FreeBSD:
- the plain CCD driver, quite simple and basic
- GEOM vinum, “traditional” way of doing things
- GEOM mirrors (gmirror), the recommended way with FreeBSD 5 and later
- ZFS mirrors, the latest and greatest.
All four work quite well and are (in my opinion) fairly easy to implement, although I am not yet sure whether I want to go for ZFS or if gmirror is good enough for me...
At this point my primary goal was within reach with no hassle, and I could focus more seriously on the secondary goal, the ability to take one disk away while the system is running.
Interestingly enough, it works quite well if you instruct the system to “say goodbye” to the disk before it is unplugged, by means of "unmount", "gmirror detach", "zpool detach" and so on. However, that is too much of a hassle. The point of USB is precisely to be able to unplug devices and expecting the system to recover gracefully whenever possible — and disk mirroring should make this possible if the other disk is left plugged.
Unfortunately my tests exposed the final blow to my efforts: FreeBSD cannot deal with disconnects of USB mass storage devices while the devices are in use. “The full fix will require a fair amount of rearchitecting.” Yeah, right, I don't really have that time to wait.
Now, I'll let Fungus rest in peace for a while, and I'll try reviving it later and see what good can come out of it. If none, I'll go for OpenSolaris instead.