Archive for Free software and related beasts

Vista vs Mepis

Wanna see how a humble GNU/Linux distro such as Mepis compares to Windows Vista? We are not talking of Ubuntu, Debian, Mandriva or SuSE Enterprise Edition here. No big-fat distros. Just Mepis, a distro that fits in a single CD that can be used to install it, or run it as a LiveCD.

You can read a throughout article at DesktopLinux.com. Enjoy!

Comments

Bandwidth shaping made easy with Trickle

I have recently downgraded the bandwidth of my internet connection, switching to a flat rate (previously I had a monthly traffic limit, albeit with a wider bandwidth). This means that now I can download to my heart’s content, but it also means that when doing things like upgrading my Debian OS with aptitude, it eats all of my bandwidth, and I can barely do anything else in the Internet, untill all packages are upgraded.

A similar effect can happen when using p2p software like aMule or KTorrent, but these programs have options to throttle down their bandwidth usage (e.g., set maximum download and upload rates).

When dealing with programs that do not have this facility, we can always resort to Trickle, which can set arbitrary limits to any program it is used with. For example:

% trickle -d 20 aptitude upgrade

will run aptitude upgrade as usual, but with a maximum download rate of 20 kB/s. Note: aptitude usually spawns two processes (downloads files in couples, not one by one), and the limit imposed by trickle is applied to each process, so the used download bandwidth will be double that specified in the command line. Or, in other words, if you want aptitude to use X bandwidth, execute:

% trickle -d X/2 aptitude upgrade

Comments (2)

WiFi with WPA under Ubuntu/Debian

I finally made my new laptop connect with WPA encryption to my WiFi router!!

I could already connect it to WiFi networks with WEP encryption (or no encription at all), but WPA proved harder.

Mini HowTo

1) My setup is the following:

WiFi router: SMC Barricade WBR14-G2
WiFi card in laptop: Intel PRO/Wireles 3945
OS: Ubuntu 6.06 LTS (Dapper Drake)

2) The router settings:

Wireless encryption: WPA/WPA2 Only
Cipher suit: TKIP+AES (WPA/WPA2)
Authentication: Pre-shared Key (yes, I know 802.1X would be more secure… sue me)
Pre-shared key type: Passphrase (8~63 characters)

3) The package one needs to install:

# aptitude install wpasupplicant

4) Making WPA supplicant run:

First, create a config file, by the name /etc/wpa_supplicant.conf, and inside it, write:

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1

network={
  ssid="your_ssid_name"
  scan_ssid=0
  proto=WPA RSN
  key_mgmt=WPA-PSK
  pairwise=TKIP CCMP
  group=TKIP CCMP
  psk="your_preshared_key"
  priority=5
}

At that point, you should make sure that the WiFi is turned on, and that the correct driver is loaded. In my case:

# modprobe ipw3945

Then, to test the WPA supplicant, run:

# wpa_supplicant -Dwext -ieth1 -c /etc/wpa_supplicant.conf

Recall I have used the wext device, instead of the ipw one, that would seem the appropriate one. Well, I read somewhere, that with 2.6.16 kernels and newer, this should be the case. Now I recall that my kernel is 2.6.15… nevermind, it works that way, and not the other (with -Dipw).

Recall also that my wireless device is eth1. Your mileage may vary (but each wireless card model gives rise to a precise device name, don’t worry).

If everything went fine, the output for the above command should be something like:


# wpa_supplicant -Dwext -ieth1 -c /etc/wpa_supplicant.conf
Trying to associate with xx:xx:xx:xx:xx:xx (SSID='xxxxxxxx' freq=0 MHz)
CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
Authentication with 00:00:00:00:00:00 timed out.
Associated with xx:xx:xx:xx:xx:xx
WPA: Key negotiation completed with xx:xx:xx:xx:xx:xx [PTK=CCMP GTK=TKIP]
CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed (auth)

If you see that “negotiation completed”, it worked (Ctr-C to exit the above).

5) Automating the WPA connection when bringing wireless interface up

Next, I’ll explain the small changes one has to make to /etc/network/interfaces to correctly bring up the interface. As I said, my wireless interface is eth1, so, I added the lines below to the aforementioned config file:


iface eth1 inet dhcp
wireless-essid my_wireless_essid
pre-up wpa_supplicant -Bw -Dwext -ieth1 -c /etc/wpa_supplicant.conf
post-down killall -q wpa_supplicant

And that’s all! Whenever you ifup eth1, you’ll bring up the wireless interface, with WPA encryption working.

Comments (5)

My backups with rsync

In previous posts I have introduced the use of rsync for making incremental backups, and then mentioned an event of making use of such backups. However, I have realized that I haven’t actually explained my backup scheme! Let’s go for it:

Backup plan

I make a backup of my $home directory, say /home/isilanes. Each “backup” will be a set of 18 directories:

  • Current (last day)
  • 7 daily
  • 4 weekly
  • 6 monthly

Each such dir has an apparent complete copy of how /home/isilanes looked like at the moment of making the backup. However, making use of hard links, only the new bits of info are actually written. All the parts that are redundant are written once on disk, and then linked from all the places referring to it.

Result: a 18 copies of a $home of 3.8 GB in a total of 8.7 GB (14% of the apparent size of 63 GB, and 13% of 18x the info size, 68,4 GB).

Perl script for making the backup

Update (Jun 5, 2008): You can find a much refined version of the script here. It no longer requires certain auxiliary script to be installed in the remote machine, and is “better” in general (or it should be!)

Below is the commented Perl script I use. Machine names, directories and IPs are invented. Bart is the name of my computer.


#!/usr/bin/perl -w

use strict;

my $rsync = "rsync -a -e ssh --delete --delete-excluded";
my $home = "/home/isilanes";
my $logfile = "$home/.LOGs/backup_log";

#
# $where -> where to make the backup
#
# $often -> whether this is a daily, weekly or monthly backup
#
my $where = $ARGV[0] || 'none';
my $often = $ARGV[1] || 'none';

my ($source,$remote,$destdir,$excluded,$to,$from);

# Possible "$where"s:
my @wheres = qw /machine1 machine2/;

# Possible "$often"s:
my @oftens = qw /daily weekly monthly/;

# Check remote machine:
my $pass = 0;
foreach my $w (@whats) { $pass = 1 if ($what eq $w) };
die "$what is an incorrect option for \"what\"!\n" unless $pass;

# Check how-often:
$pass = 0;
foreach my $o (@oftens) { $pass = 1 if ($often eq $o) };
die "$often is an incorrect option for \"often\"!\n" unless $pass;

# Set variables:
if ($what eq 'machine1')
{
# Defaults:
$source = $home;
$remote = '0.0.0.1';
$destdir = '/disk2/backup/isilanes/bart.home.current';
$excluded = "--exclude-from $home/.LOGs/excludes_backup.dat";
$to = 'machine1';
$from = 'bart';
}
elsif ($what eq 'machine2')
{
# Defaults:
$source = $home;
$remote = '0.0.0.2';
$destdir = '/scratch/backup/isilanes/bart.home.current';
$excluded = "--exclude-from $home/.LOGs/excludes_backup.dat";
$to = 'machine2';
$from = 'bart';
}

# Do the job:
unless ($what eq 'none')
{
unless ($often eq 'none')
{
# Connect to the remote machine, and run ANOTHER script there, making a rotation
# of the backup dirs:
system "ssh $remote \"/home/isilanes/MyTools/rotate_backups.pl $often\"";

# Actually make the backup:
system "$rsync $excluded $source/ $remote:$destdir/";

# "touch" the backup dir, to give it present timestamp:
system "ssh $remote \"touch $destdir\"";

# Enter a line in the log file defined above ($logfile):
&writelog($from,$often,$to);
};
};

sub writelog
{
my $from = ucfirst($_[0]);
my $often = $_[1];
my $to = uc($_[2]);
my $date = `date`;

open(LOG,">>$logfile");
printf LOG "home@%-10s %-7s backup at %-10s on %1s",$from,$often,$to,$date;
close(LOG);
};

As can be seen, this script relies on the remote machine having a rotate_backups.pl Perl script, located at /home/isilanes/MyTools/. That script makes the rotation of the 18 backups (moving current to yesterday, yesterday to 2-days-ago, 2-days-ago to 3-days-ago and so on). The code for that:


#!/usr/bin/perl -w

use strict;

# Whether daily, weekly or monthly:
my $type = $ARGV[0] || 'daily';

# Backup directory:
my $bdir = '/disk4/backup/isilanes/bart.home';

# Max number of copies:
my %nmax = ( 'daily' => 7,
'weekly' => 4,
'monthly' => 6 );

# Choose one of the above:
my $nmax = $nmax{$type} || 7;

# Rotate N->tmp, N-1->N, ..., 1->2, current->1:
system "mv $bdir.$type.$nmax $bdir.tmp" if (-d "$bdir.$type.$nmax");

my $i;
for ($i=$nmax-1;$i>0;$i--)
{
my $j = $i+1;
system "mv $bdir.$type.$i $bdir.$type.$j" if (-d "$bdir.$type.$i");
};

system "mv $bdir.current $bdir.$type.1" if (-d "$bdir.current");

# Restore last (tmp) backup, and then refresh it:
system "mv $bdir.tmp $bdir.current" if (-d "$bdir.tmp");
system "cp -alf --reply=yes $bdir.$type.1/. $bdir.current/" if (-d "$bdir.$type.1");

Comments

Beware of new UDEV rules!

As some of you might know, udev is a nice program that gives the user the possibility of giving persistent names to hotplugged items (e.g. USB devices), in GNU/Linux systems.

When a USB device is plugged, the kernel “finds” it, and gives it a device name. This “name” is a special file (located at the /dev directory), with which the communication with the USB device is done. For example, this is the name that has to be used for mounting the device:

# mount /dev/devicename /mnt/mountpoint

Now, the old devfs (superceded by udev) gave subsequently plugged USB devices sequential names (e.g., the first one sda, the second one sdb…). So, the device name would not correspond to the physical device you were plugging: an external HD and a portable music player would be given devices sda and sdb respectively, or the opposite, depending on the plugging order!

To fix this, udev allows for creating rules, so that a device matching this rules will always be given the same device name. Each USB device passes some info to the kernel at plugtime, so udev can use that info to identify the device. For example, an excerpt of dmesg in my Debian box, when I connect my external HD:

scsi6 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 9
usb-storage: waiting for device to settle before scanning
Vendor: FUJITSU Model: MHT2080AT Rev: 0811
Type: Direct-Access ANSI SCSI revision: 00
SCSI device sda: 156301488 512-byte hdwr sectors (80026 MB)

The relevant points are that the HD identifies itself as a FUJITSU product, with the model name MHT2080AT. I can now tell udev to create a /dev/woxter device node, each time I plug in a device made by “FUJITSU”, and by the model name of “MHT2080AT”. To do so, I can create a file /etc/udev/rules.d/myrules.rules, with content:

# My Woxter disk:
BUS=="scsi", SYSFS{vendor}=="FUJITSU", SYSFS{model}=="MHT2080AT", NAME="woxter"

Now, the original reason to write this post was that… do you see the '=='? behind 'BUS' and 'SYSFS'? Well, they have the usual meaning of ‘BUS==”scsi”‘ means ‘if BUS equals “scsi”‘, whereas ‘NAME=”woxter”‘ means ‘assign the value “woxter” to “name”‘.

However, in previous versions of udev (I don’t know when they changed), all equal signs in the udev rules were single ‘=’s, and that is the way I had them.

Now, all of a sudden, I update udev, and my USB devices do not get the name they should, according to my rules, because my rules are wrong! Man, they should give a warning or something! Something like:

Warning: file X, line Y. Use of '=' where '==' is expected!

Oh, well. In the end I found out by myself.

Comments

Don’t try this with Windows

I found out in FayerWayer about the things you can do with the Wiimonte (the remote of the console) and a GNU/Linux computer with Beryl.

[youtube=http://www.youtube.com/watch?v=ALqduQfm09c&rel=1]

Yes, it seems rather useless… but I looks great! Besides, think of the possibilities. And still some people will keep on saying that Mac and Windows lead the desktop innovation!

Comments

French National Assembly Embraces Open Source

Finishing my Ph.D. Thesis really hindered my touch with news, so here it goes, with 2 months’ delay: The French National Assembly switched to GNU/Linux. I read about it in Menéame.net, referring to Barrapunto, referring to Slashdot, referring to PC Advisor, who covers the new (usual cycle of news for the Spanish audience, reading mostly Menéame.net).

The French Goverment also said that all Gov. documents should be available in ODF. This nicely relates to the shameful case of the UPV/EHU (my University).

The Spanish Congress, meanwhile, is still hooked to Windows XP.

Comments

Sometimes too many distros is bad

Oh my God! (pun intended). Where are we heading?

I just read at DistroWatch that there is a GNU/Linux distro for Christians! According to DistroWatch:

Ubuntu Christian Edition is a free, open source operating system geared towards Christians. Along with the standard Ubuntu applications, Ubuntu Christian Edition includes the best available Christian software. The latest release contains GnomeSword, a top of the line Bible study program for Linux based on the Sword Project.

I might understand that people with different religious beliefs has different needs in terms of software, like the GnomeSword program, for studying the Bible. However… a whole distribution!?

This is getting silly, with people making a fork of Ubuntu “for the left-handed”, “for people with cold feet” or “for people who prefer emacs over vi”. All this is what the friggin’ package manager is for: installing the programs you like!

Comments

Parsing command line arguments

In UNIX-like environments, such as GNU/Linux, command line is often used to operate on a bunch of files, such as:

rm -f *.dat

In the command above, “*.dat” is expanded by the shell (the command interpreter), to all matching files in the present directory (e.g.: “file1.dat file2.dat dont_delete_me.dat this_file_is_rubbish.dat“). However, this expansion is performed as a first step, and then the expanded command line is executed, e.g.:

rm -f file1.dat file2.dat dont_delete_me.dat this_file_is_rubbish.dat

This behaviour can potentially fail if a lot of files match the *.dat, because there is an upper limit to how wide a command line can be (brutally high, but finite). This can happen, for example, if you try to delete the contents of a directory with 100,000 files, and use rm -f * (yes, this can happen). For example, a ls in a directory with 100,000 files works fine, but an rm * does not:

Bart[~/kk]: rm *
/bin/rm: Argument list too long.

To avoid this problem, we can make use of xargs and echo (since echo does not seem to suffer from this argument number limitation), in the following way:

echo * | xargs rm -f

Now, xargs takes care of the argument list, and processes it so that rm does not see an endless argument list.

xargs can also be given other uses. For example, consider the following example: We want to convert some OGG files to MP2 (I won’t be caught dead near an MP3, due to its patent issues), so that a Windows luser can hear them. We can use oggdec to convert OGG to WAV, then toolame to convert WAV to MP2. Now, oggdec accepts multiple arguments as input files to convert, so the following works:

oggdec *.ogg

The above generates a .wav for each .ogg in the argument list. However, toolame does not work like that; it expects a single argument, or, if it finds two, the second one is interpreted as the desired output file, so the following fails (too many arguments):

toolame *.wav

This is where xargs can come in handy, with its -n option (see the xargs man page). This option tells xargs how many arguments to process at the same time. If we want each single argument to be processed separately, the following will do the trick:

echo *.wav | xargs -n 1 toolame

In the above example, toolame is called once per WAV file, and sees a single WAV file as argument each time, so it generates a .mp2 file per .wav file, as we wanted.

Comments

¿Popularización de Software Libre acentúa explotación de bugs?

[This entry is also available in English|English PDF|PDF en castellano]

Los excépticos del movimiento FLOSS suelen decir que el Software Libre tiene, en general, menos bugs explotados que el software privativo, solamente porque es menos popular que este. Argumentan que, como el FLOSS tiene menos usuarios, los crackers estarán menos interesados en malgastar su tiempo intentando explotar los bugs que pudiera tener. La mayor base de usuarios del software privativo daría además, según ellos, una mayor publicidad a sus bugs, y sus modos de explotación se difundirían más rápido. El corolario a esta teoría sería que la popularización de aplicaciones FLOSS (p.e. Firefox), llevería a un incremento en el número de bugs descubiertos y explotados, llegando eventualmente a un estado similar al del software privativo actual (p.e. “Cuando Firefox sea tan popular como Internet Explorer, tendrá tantos bugs como Internet Explorer.”).

El objetivo de este artículo es demostrar matemáticamente la total insensatez de tal teoría. Específicamente, argumentaré que un aumento en el tamaño de la comunidad de un proyecto FLOSS lo mejora de al menos 3 formas:

  1. Desarrollo acelerado
  2. Menor vida media de bugs abiertos
  3. Menor vida media de bugs explotados

Una explicación más extensa está disponible en formato PDF. Lamento que las fórmulas matemáticas en HTML sean de calidad francamente pobre, pero no tengo ni tiempo ni habilidad para mejorarlas. Si el lector está interesado en fórmulas bonitas, recomiendo acudir al PDF.

Este blog, y el PDF que enlazo, están liberados bajo la siguiente licencia:


Creative Commons License

Esta obra está bajo una licencia de Creative Commons.

Lo que esto significa, básicamente, es que eres libre para copiar y/o modificar este trabajo como gustes, y redistribuirlo cuanto quieras, con dos únicas limitaciones: que no le des uso comercial, y que cites a su autor (o al menos enlaces a este blog).

1 – Proposiciones y derivación

Tenemos un proyecto FLOSS P, nuevas versiones del cual se liberan cada T tiempo. Cada versión se asume que incorpora G nuevos bugs, y las sucesivas versiones serán liberadas cuando todos los bugs de la anterior sean parcheados. En un momento determinado habrá B bugs abiertos (de los G originales).

Asumo que la velocidad de parcheo es proporcional al tamaño de la comunidad de usuarios (U):

dB/dt=-KpU

1.1 – Desarrollo acelerado

De arriba, la dependencia temporal del número de bugs abiertos:

B = G – Kp U t

El tiempo entre versiones (T), de B = 0:

T = G/KpU

De manera que el tiempo entre versiones se acorta para U creciente.

1.2 – Menor vida media de bugs abiertos

En un período de tiempo dt, se parchean (-dB/dt)dt bugs, siendo su edad t. Si llamamos τ a la vida media de los bugs, tenemos la definición:

τ = (∫t(-dB/dt)dt)/(∫dB)

De ahí se deduce:

Ï„ = T/2

Esto es: la vida media de los bugs es siempre la mitad del tiempo entre versiones, el cual (como se ha mencionado) tiene una proporcionalidad inversa con U.

1.3 – Fracción de bugs explotados antes de ser parcheados

Definimos la siguiente velocidad de explotación de bugs, donde Bx es el total de bugs explotados, Kx es la “eficiencia de explotación” de los crackers (cuya cantidad se asume proporcional a U), y Bou es la cantidad de bugs abiertos y sin explotar:

dBx/dt = Kx U Bou

También definimos α = Box/B, donde Box es la cantidad de bugs abiertos y explotados.

Se puede derivar la evolución temporal de α:

α(t) = 1 – exp(-Kx U t)

Tras ello definimos γ = Kp/KxG, y derivamos la fracción de los bugs G que terminan siendo explotados para un tiempo t:

Bx(t)/G = 1 – γ + (γ – 1 + t/T)exp(-Kx U t)

Resolviendo para t=T, y tomando en cuenta que T=G/KpU, obtenemos la fracción de los bugs totales que son explotados en algún momento durante el período entre versiones (Fx):

Fx = 1 – γ + γ exp(-1/γ)

Nótese que Fx es independiente de U, esto es, aunque aumente el tamaño de la comunidad de usuarios, no aumenta la fracción del total de bugs que acaban siendo explotados (aunque un crecimiento de la comunidad traiga asociado un aumento colateral del número de crackers).

1.4 – Menor vida media de bugs explotados

Deseamos saber cuánto tiempo permanecen sin parchear los bug explotados, y llamamos a este tiempo τx. Tras un desarrollo ligeramente complejo, pero derivando siempre de equaciones previamente definidas (ver la versión PDF), obtenemos una expresión realmente simple para τx:

τx = Fxτ

Esto es, el tiempo medio de explotación de los bugs explotados es proporcional a τ, el cual a su vez es proporcional a T, o inversamente proporcional a U.

2 – Conclusiones

El eslogan “Más popularidad = más bugs” es un non sequitur. De acuerdo con el simple modelo que bosquejo aquí, cuanto más amplia sea la comunidad de usuarios de un programa FLOSS, más rápido serán parcheados los bugs, incluso admitiendo que a más usuarios, más crackers entre ellos, dispuestos a acabar con él. Incluso para crackers que sean más efectivos en su desempeño que los usarios de buena fe en su trabajo de parcheo (Kx >>> Kp), aumentar el tamaño de la comunidad reduce el tiempo que los bugs permanecen abiertos y también cuánto tiempo tardan en parchearse los bugs ya explotados. No importa cuán torpes sean los usuarios, y cuán rapaces los crackers, el modelo libre (por medio del cual se da acceso al código a los usuarios, dándoles así poder para contribuir al programa) asegura que la popularización es positiva, tanto para el programa como para la propia comunidad.

Comparemos esto con un modelo cerrado, en el que una base de usuarios mayor puede incrementar el número de crackers atacando a un programa, pero ciertamente añade poco o nada a la velocidad con que el código es parcheado y corregido. Es de hecho el software privativo el que debe temer su popularización. Es fácil de ver que cuando una pieza determinada de software privativo alcanza una cierta “masa crítica” de usuarios, los crackers pueden potencialmente desmoronar su evolución (digamos, haciendo Ï„x = T, Fx = 1), porque (a diferencia del FLOSS), G, P, y por lo tanto T, son constantes (ya que dependen únicamente de los vendedores del software).

Comments (1)

« Previous Page« Previous entries « Previous Page · Next Page » Next entries »Next Page »