Sunday, July 25, 2010

KDE suspend, hibernate workaround for Gentoo on Lenovo U150

Hello, recently I upgraded my Gentoo packages to the following:


sys-auth/consolekit-0.4.1

sys-auth/policykit-0.9-r1

sys-apps/hal-0.5.14-r2

kde-base/powerdevil-4.4.5

kde-base/policykit-kde-4.4.5
With these, I lost the ability to suspend the laptop. I trield by directly communicating with HAL:

dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Suspend int32:0
The program answered:

Error org.freedesktop.Hal.Device.UnknownError: error: org.freedesktop.Hal.Error: Could not determine whether caller is privileged

org.freedesktop.Hal.Device.Error
I don't have the clue why this is happening, so I found a workaround by adding the following to the local_start() function of /etc/conf.d/local:

sleep 3s && /etc/init.d/hald restart
I also had to make sure the suspension policies were enabled for the relevant users in PolicyKit through KDE's System Settings.

Update Oct 13, 2010 - Thanks to Motosauro's comments, I checked for the workaround in my current setup:

sys-auth/consolekit-0.4.1

sys-auth/policykit-0.9-r1

sys-apps/hal-0.5.14-r3 -apm

kde-base/powerdevil-4.5.2
The workaround is no longer needed.

Monday, July 19, 2010

Printing useful STL container information with GDB

GDB's "p variable-name" is the Swiss Army knife of the programmer, except when it comes to examine the contents of STL containers.

(gdb) p fieldInd
$110 = {
  <std::_Vector_base<unsigned long, std::allocator<unsigned long> >> = {
    _M_impl = {
      <std::allocator<unsigned long>> = {
        <__gnu_cxx::new_allocator<unsigned long>> = {<No data fields>}, <No data fields>}, 
      members of std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_impl: 
      _M_start = 0x646c60, 
      _M_finish = 0x646cc8, 
      _M_end_of_storage = 0x646d20
    }
  }, <No data fields>}

This tutorial gives you useful information to have GDB print useful STL container information for you.
(gdb) pvector perm
elem[0]: $111 = 4
elem[1]: $112 = 2
elem[2]: $113 = 0
elem[3]: $114 = 3
elem[4]: $115 = 1
elem[5]: $116 = 5
Vector size = 6
Vector capacity = 6
Element type = unsigned long *

Wednesday, July 07, 2010

CAcert y Certicamara en Google Chrome / Chromium - Linux

Hola, hace algunos días no podía usar Google Chromium para ingresar a miplanilla.com, CAcert y otros servicios debido a que no contaba con los certificados digitales adecuados. Por el consejo de un amigo, e investigando una serie de sitios web, he compilado las siguientes instrucciones para agregar los certificados a Chrome:
wget http://www.cacert.org/certs/root.crt
wget http://www.cacert.org/certs/class3.crt
wget http://www.certicamara.com/downloads/safelayer/certicamara.crt
wget http://web.certicamara.com/media/69784/ac_offline_raiz_certicamara.crt
wget http://www.certicamara.com/ac_online_subordinada_certicamara.crt
certutil -d sql:$HOME/.pki/nssdb -A -t TC -n "CAcert.org" -i root.crt
certutil -d sql:$HOME/.pki/nssdb -A -t TC -n "CAcert.org Class 3" -i class3.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "TCu,Cu,Tuw" -n "Certicamara" -i certicamara.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "TCu,Cu,Tuw" -n "Certicamara CA Raiz SafeLayer 3" -i ac_offline_raiz_certicamara.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "TCu,Cu,Tuw" -n "Certicamara CA Subordinada SafeLayer 3" -i ac_online_subordinada_certicamara.crt
Para usar la herramienta certutil en Gentoo Linux, es necesario tener instalado el paquete nss con la opción utils. Para Ubuntu y otras distribuciones basadas en Debian, se debe tener instalado el paquete libnss3-tools. Más información en este blog.
Después de agregar los certificados, se pueden borrar los archivos crt.

Wednesday, March 31, 2010

Gentoo Linux on Lenovo u150

Hello, I just bought a Lenovo u150 with the following specs:

Intel CPU SU7300 @ 1.30GHz, 1300 Mhz, Core 2 Duo
RAM: 2GB
Video: 1366x768x60Hz, 11.6inches
Wireless: Intel WiFi Link 5100 AGN
LAN: Broadcom NetLink Gigabit Ethernet
Hard disk: 300 GB (320GB they say)
Bluetooth
Lenovo EasyCamera3

Here a summary of the steps I took to install Gentoo Linux on it.

I used UNetbootin to load the Gentoo Minimal Installation (amd64) iso image into a USB key, and booted the laptop with it. The first thing I noticed is the lack of the wired network interface, so I used the net-setup script to activate the wlan0 interface and connect to Internet without wires.

After creating partitions, compiling the kernel with this configuration and installing the basic packages as described in the Gentoo Handbook, the system rebooted smoothly.

Brightness

Brightness fixes have been published by zaius; based on his explanations I wrote this C++ program (just because I love C++), which just does the same but in a logarithmic fashion, which I find more appropriate for handling low levels of brightness.

Thanks to zaius for his research and ideas; I just hope the fix will be made at the kernel level very soon.

Earphone plug


The speakers do not mute when you plug your earphones in the laptop. I found a workaround by adding the following kernel parameter to grub.conf:

snd-hda-intel.model=olpc-xo-1_5

It may not look nice, you may loose access to the internal microphone, but the parameter works in keeping your music private for you. Keep up to date with information on these issue by subscribing to the Ubuntu Bug.

Update: linux-2.6.35 does not need the kernel parameter.

Thanks for reading.

I do not have any relationship with Lenovo or its trademarks.

Tuesday, March 09, 2010

C++0x tips: improve performance in code using STL containers

Hello, I am hungry for code performance, specially in my simulations involving entire cities full with people, mosquitoes, viruses, homes, flower vases, etc. So it has been frustrating to interrupt the code execution just to realize all it has been doing for hours is creating the cities. Let us examine how the preparation phase takes place:
class houseCls;
class personCls;
//...

class cityCls {
    private:
        vector<houseCls> houses;
        vector<personCls> pedestrians;
    public:
        //...
}

vector<cityCls> country;

int main() {
    for (int i=0; i<nCities; i++)
        country.push_back(cityCls(/* City construction arguments */));
}
On execution, a city is created in the stack, then it is copied into the country vector and then the city in the stack is destroyed. So most runtime is employed in getting the vector ready for simulation. Using an aggregate (array) is out of the question, because things must be dynamic and safety must be ensured in all aspects.
How about just creating the new city in the new space inside the vector? Previously the vector::swap() function helped accomplish this task, but implementation became confuse sometimes for the client programmer.

I took the opportunity to study the improvements of the newest C++ standard, C++0x. I learned about a great STL improvement in terms of memory management, performance, and overall, getting things done. It is the emplace_back() function, which does just what the above question was about.

Use the new C++ standard, at your own risk, taking into account it is evolving.
g++ --pedantic-errors -Wall -Wextra -std=gnu++0x source.cc
Make the following changes to your code:
int main(){
 ///Always reserve memory before starting
 country.reserve(nCities);
 for (int i=0; i<nCities; i++)
  country.emplace_back(/** City construction arguments, which do not need the explicit class name anymore */);
}
You can use explicit copy constructors and gdb to benchmark your code.

Thursday, February 25, 2010

SSH access to the computer at your office

There can be different ways to get connected to the computer at your office; most are grouped as VPN or VNC techniques; but they are quite a bloat when all you want to do is get connected to check how things are going up with that program you are running; under Windows you might get a crashed computer at the office, and that is bad thing if the program was running overnight.

You can use SSH alone to get connected from home, provided you have good knowledge of how SSH works (public key authentication and port forwarding), you have administrative access to the external computer and the router/modem, and your company firewall is not too restrictive. This post is about settings in which external computers cannot get connected to the computer at the office because the company firewall masquerades its IP address, or blocks external access to port 22 of the office computer. In these cases, the connection to the computer at the office needs a previously-set connection with port forwarding, as illustrated next:


The external computer must be configured to be visible from Internet. Configure it to have a static IP address and put it in the demilitarized zone (DMZ) of the router/modem, or at least as a virtual server. Refer to the router guide for instructions.

Let us use the name aaron for the external computer. For security, disable non-essential services (portmap, nfs, ftp) from aaron, and enable sshd so it accepts a reduced number of users (namely you and you alone); ensure strong passwords for these users, because Linux viruses are real; I have had the experience of being target of brute force attacks on my SSH servers all the time.
Insecurity in Linux comes from incompetent administrators. I definitely take measures to ensure the privacy and security of my computer, which is all open to Internet. For example,  besides the normal user account facorread, I created an unprivileged user account fabio, which will accept the incoming connection at aaron. The computer at the office will automatically try to connect to aaron as user fabio, so you need to set up public key authentication for this task. The following commands are what you need this set up, as user fabio:
fabio@aaron ~ $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fabio/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/facorread/none.id_rsa.
The key fingerprint is: cc:dd:ff:3d fabio@aaron
fabio@aaron ~ $
cat .ssh/id_rsa.pub >> .ssh/authorized_keys
Save the public key in your USB memory stick:
fabio@aaron ~ $ cp .ssh/id_rsa.pub /media/usb1/fabio.pub
As root, improve security by disabling the shell for user fabio:
root@aaron ~ # usermod -s /sbin/nologin fabio
Configure aaron to listen at both the secure SSH port (22) and an insecure one (my favorite one is 11111), so you can test both connections from the office. In summary of all the above, add the following lines to your sshd_config file:
# Listening on two ports
Port 22

Port 11111
# Only allowed users
AllowUsers facorread fabio
# Restrictions for fabio
Match User fabio
    KbdInteractiveAuthentication no
    PasswordAuthentication no
When you restart your sshd service, you must notice the following when running netstat -tenpl as root:
tcp    127.0.0.1:22     0.0.0.0:*    LISTEN      sshd
tcp    127.0.0.1:11111  0.0.0.0:*    LISTEN      sshd
After this, you can check that ports 22 and 11111 are open to the Internet using a port scanner.
It is advisable to register your home computer with a free DNS service so you and the office computer always know the IP address of aaron through a host name of the likes of aaron.dyndns.org.  Modern modems/routers can connect to these services and keep them up to date about the IP address of your home. My modem is quite old, so I have created a script which uses ez-ipupdate to keep reporting the IP address to the dyndns service. Please adapt it to your needs and the particular modem you use at home:
#!/bin/bash


# Ensure only one instance of this script
[[ $(pgrep -o tellip) != $BASHPID ]] && exit 0


unset oldAddress
while true; do
newAddress=`curl -s --user admin:modemPassword http://modem/wancfg.cmd | grep isolate the IP address as reported by the port scanner`
if ! netstat -ei | egrep --quiet "addr:static address of aaron "; then
    echo "No interface has the static address to act as server. Waiting 1 minute."
elif [[ ( -z "$newAddress" ) || ( "$newAddress" == 0.0.0.0 ) ]]; then
    echo Waiting one minute before getting a valid address
elif [[ ( $newAddress != $oldAddress ) ]]; then
    echo "${oldAddress} -> ${newAddress} $(date)" &&
    oldAddress="${newAddress}" &&
    echo "address=${newAddress}
host=aaron.dyndns.org The host name you chose at the dyndns website
service-type=dyndns
user=dyndnsUser:dyndnsPassword" | /usr/sbin/ez-ipupdate -c - 2>&1
fi
sleep 1m
done
Ensure this script runs at all times; you might add this script to the list of local scripts you computer runs when you turn it on. Also, set good power management schemes, save on your energy bill when you leave the computer running alone at home.
Back at the office computer (name ezra), you must test both ssh connections and the public key you copied above:
facorread@ezra ~ $ cp /media/usb1/fabio.pub .ssh/
facorread@ezra ~ $ ssh -p11111 -i .ssh/fabio.pub fabio@aaron.dyndns.org
The authenticity of host 'aaron.dyndns.org' can't be established.
RSA key fingerprint is f6:7b:b5:07:43.
Are you sure you want to continue connecting (yes/no)? yes
Last login: Thu Jun 12 08:24:25 COT 2007
This account is currently not available.
Connection to aaron.dyndns.org closed.
facorread@ezra ~ $ ssh -i .ssh/fabio.pub aaron.dyndns.org
The authenticity of host 'aaron.dyndns.org' can't be established.
RSA key fingerprint is f6:7b:b5:07:43.
Are you sure you want to continue connecting (yes/no)? yes
Last login: Thu Jun 12 08:24:25 COT 2007
This account is currently not available.
Connection to aaron.dyndns.org closed.
"This account is currently not available" is the expected answer from the computer at home, because of the hardened security on the fabio account. If you succeed in the first attempt, you can connect to home using the insecure port. If you succeed in the second attempt, you will be able to connect using the secure SSH port, so you should configure the SSH server at aaron to listen only to port 22 as intended.
Use the following script to tell the computer at the office to connect to the computer at home and forward local port 22 to remote port 2222. This script uses the resolveip utility of the mysql package. By the way, if you find a better tool, please tell me. Installing mysql to use resolveip is like buying a hammer to kill a flea.
#!/bin/bash


remotehost=aaron.dyndns.org


while true; do
    echo $(date) $(resolveip "${remotehost}" 2>&1 ) &&
   
# This line renews the home IP address at the known host list.
    sed -i "s/^${remotehost},[^ ]\\+/${remotehost},$(resolveip -s ${remotehost})/" .ssh/known_hosts 2>&1 &&
    ssh -i ~/.ssh/fabio.rsa -o "BatchMode yes" -R '*:2222:localhost:22' "fabio@${remotehost}" -N 2>&1
    sleep 1m
done
Also ensure this script runs at all times as the normal user facorread, even thought there might be a power outage at the company. Include it in the list of local scripts to run at startup (or as a startup cron job).
Go home and try to connect to the office through the forwarded port using the command:
facorread@aaron ~ $ ssh -p2222 localhost
This is the only command you will need from now on to connect to the computer at the office. Most of the time the connection is straightforward; sometimes you will get Connection refused notices, due to the IP address of aaron being changed and the automatic connection being renewed. Wait a minute and try again. For the impatient, the following command helps check whether the tunnel is open.
tcp    127.0.0.1:22     0.0.0.0:*    LISTEN      sshd
tcp    127.0.0.1:2222   0.0.0.0:*    LISTEN      sshd
tcp    127.0.0.1:11111  0.0.0.0:*    LISTEN      sshd
This set up takes time and some effort on your part; please comment on your success stories. I hope it is useful.
For convenience, I recommend using connection sharing and public key authentication for the normal user facorread as instructed in the SSH man page.