Archivo

Entradas Etiquetadas ‘kernel’

Buscando un proceso en C

Martes, 4 de Octubre de 2011 Gaspar Fernández 2 comentarios

Comando topEn ocasiones, nuestros programas requieren que un servicio o un programa esté en ejecución. Algunos servicios los podemos ubicar fácilmente, ya que /var/run ,  /dev/shm u otra ruta contienen un archivo con su PID (Identificador de proceso), otras servicios no figuran en ningún lado. También puede ser que estemos esperando que otro proceso termine y necesitamos averiguar su PID.

Para todo ello, debemos echar un ojo al contenido de /proc/, ahí encontramos, entre otras cosas, información sobre los procesos en ejecución del sistema. En principio lo que nos interesa es el nombre del ejecutable (es lo que estamos buscando), para ello, vamos a buscar dentro del directorio /proc/ todos los directorios que sean numéricos (esos que contendrán un PID), y leeremos el fichero /proc/[pid]/comm, que contiene la información del nombre del ejecutable. Eso sí, ese nombre tendrá una longitud limitada (marcada por la constante del kernel TASK_COMM_LEN, que suele valer 16 (con lo que los nombres tendrán como máximo 15 caracteres):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>

void tareaProceso(char *nombre, int pid);

void buscaProceso(char *nombre);

void error(char *error);

/* Una función lo más general posible */
void getProcName(char *dest, int pid);

int main(int argc, char *argv[])
{
  buscaProceso("firefox-bin");
  return EXIT_SUCCESS;
}

void tareaProceso(char *nombre, int pid)
{
  printf("Encontrado proceso %-16s con PID: %d\n", nombre, pid);
  /* Aquí ya puedo matarlo, mandarle señales o hacer lo que quiera */
  /* con el proceso en cuestión */
}

void buscaProceso(char *nombre)
{
  DIR *proc;
  struct dirent *proceso;
  char procname[16];        /* Nombre del proceso */
  int pid;

  proc=opendir("/proc");

  if (proc==NULL)
    error("No puedo acceder al directorio /proc");

  while ((proceso=readdir(proc)) != NULL)
    {
      /* En /proc hay más cosas además de los PIDs, debemos asegurarnos de que */
      /* lo que hemos visto es un ID de proceso, lo demás no nos interesa */
      if ( (*proceso->d_name>'0') && (*proceso->d_name<='9') )
    {
      /* Convertimos el PID a número para la llamada a la función */
      pid=strtol(proceso->d_name, NULL, 10);
      getProcName(procname, pid);
      if (strncmp(nombre,procname,15)==0)
        tareaProceso(procname, pid);
    }
    }
}

void error(char *error)
{
  fprintf(stderr, "Error: %s (%d, %s)\n", error, errno, strerror(errno));
  exit(EXIT_FAILURE);
}

void getProcName(char *dest, int pid)
{
  FILE *fcomm;
  char filename[20];        /* /proc/[PID] (5 chars)/comm : total 16 chars */

  sprintf(filename,"/proc/%d/comm", pid);

  fcomm=fopen(filename, "r");
  if (!fcomm)
    error("No existe el fichero");
  /* A veces fgets() coge un salto de línea extra */
  /* fgets(dest, 16, fcomm); */
  fscanf(fcomm, "%s", dest);
  close(fcomm);
}

En este ejemplo si comentamos la línea 52 y en la línea 53 ponemos:

1
tareaProceso(nombre, pid);

podemos obtener un listado completo de las tareas en ejecución (sólo por curiosear un poco). Aunque en este ejemplo tenemos un problema, mencionado antes, el número de caracteres del ejecutable, es decir, hay ejecutables con más de 15 caracteres, y tal vez queramos buscarlos. Con la solución actual estamos cortando los nombres (con strncmp()), es decir, sería lo mismo aplicacionconnombrelargo que aplicacionconnombrecorto, ya que sólo tenemos en cuenta los primeros 15 caracteres. Tiene que haber otra forma de sacar el nombre completo, y es a través del archivo /proc/[PID]/cmdline, es más, desde aquí podemos sacar la ruta del ejecutable y los parámetros con los que se llamó, tal y como vemos cuando ejecutamos:

$ ps x

Vamos a ver cómo podemos adaptar el código de antes para poder sacar toda esa información.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <libgen.h>     /* basename */

enum pnametype
  {
    SHORT,
    LONG,
    WPATH
  };

/* Realiza una tarea con el proceso encontrado */
void tareaProceso(char *nombre, int pid);

/* Busca un proceso determinado */
void buscaProceso(char *nombre);

/* Sale del programa emitiendo un error */
void error(char *error);

/* Obtiene el nombre de un proceso */
void getProcName(char *dest, int pid, enum pnametype outtype);

/* Lee los contenidos de un archivo */
int getFileContents(char *dest, char *fname);

int main(int argc, char *argv[])
{
  buscaProceso("plugin-container");
  return EXIT_SUCCESS;
}

void tareaProceso(char *nombre, int pid)
{
  printf("Encontrado proceso %-16s con PID: %d\n", nombre, pid);
  /* Aquí ya puedo matarlo, mandarle señales o hacer lo que quiera */
  /* con el proceso en cuestión */
}

void buscaProceso(char *nombre)
{
  DIR *proc;
  struct dirent *proceso;
  char procname[255];       /* Como getProcName necesita una variable grande, se la damos */
  int pid;

  proc=opendir("/proc");

  if (proc==NULL)
    error("No puedo acceder al directorio /proc");

  while ((proceso=readdir(proc)) != NULL)
    {
      /* En /proc hay más cosas además de los PIDs, debemos asegurarnos de que */
      /* lo que hemos visto es un ID de proceso, lo demás no nos interesa */
      if ( (*proceso->d_name>'0') && (*proceso->d_name<='9') )
    {
      /* Convertimos el PID a número para la llamada a la función */
      pid=strtol(proceso->d_name, NULL, 10);
      getProcName(procname, pid, LONG);
      if (strcmp(nombre,procname)==0)
        tareaProceso(procname, pid);
    }
    }
}

void error(char *error)
{
  fprintf(stderr, "Error: %s (%d, %s)\n", error, errno, strerror(errno));
  exit(EXIT_FAILURE);
}

int getFileContents(char *dest, char *fname)
{
  FILE *fdata;
  int res;

  fdata=fopen(fname, "r");
  if (!fdata)
    error("No existe el fichero");
 
  res=fscanf(fdata, "%s", dest);
  if (res==EOF)         /* Si no hemos leído nada,  */
    *dest='\0';         /* nos aseguramos de vaciar la cadena */

  fclose(fdata);

  /* Devolvemos un error si, por ejemplo el fichero está vacío */
  return (res!=EOF);
}
/* dest tiene que ser grande, en un proyecto real, reservamos memoria desde */
/* getProcName, no nos arriesgamos a que falle algo de fuera */
void getProcName(char *dest, int pid, enum pnametype outtype)
{
  char filename[20];        /* /proc/[PID] (5 chars)/cmdline : total 19 chars */
  char *tmp;
  char *newfile;
  if (outtype==SHORT)
    sprintf(filename,"/proc/%d/comm", pid);
  else
    sprintf(filename,"/proc/%d/cmdline", pid);

  if (!getFileContents(dest, filename))
    {
      /* Si no hemos podido obtener nada */
      if (outtype!=SHORT)
    {
      /* probamos desde comm */
      sprintf(filename,"/proc/%d/comm", pid);
      getFileContents(dest, filename);
    }
    }

  if (outtype!=SHORT)
    {
      /* Si queremos un tipo de salida que no sea el corto, tendremos que transformar esta cadena */
      tmp=dest;
      while ((*tmp!=' ') && (*tmp!='\0')) ++tmp;
      tmp='\0';
      if (outtype==LONG)
    {
      tmp=basename(dest);
      strcpy(dest, tmp);
    }
    }
}

Ahora, obtenemos la información dependiendo del tipo especificado por outtype de tipo enum pnametype, e incluso si especificamos LONG, este tipo extraerá el nombre del archivo ejecutable despreciando la ruta del mismo. Para descargar los archivos de código, click aquí (2.3Kb)

Solución temporal al problema con udev 171

Jueves, 8 de Septiembre de 2011 Gaspar Fernández Sin comentarios

Desde Mayo de 2011 tenemos a nuestra disposición una de las versiones con más bugs de udev, este gestor de dispositivos de Linux. En concreto, el bug del que hablo está apareciendo desde Julio/Agosto de este año. La forma de reproducirlo es muy fácil, tenemos que tener el servidor X con la configuración automática (en muchas distribuciones) o utilizando dispositivos de eventos, desde el arranque, ni el teclado ni el ratón funcionan.

tecladosLa primera vez que me pasó pensé en el servidor X, de hecho, como no funcionaba el teclado, no se podía cambiar a consola con Ctrl+Alt+Fn (n=1,2,3,4,….) ; por lo que fue necesario pulsar Alt+Sysrq+R antes de poder cambiar a la consola con Alt+Fn.

Dicho esto, había que trastear un poco, y es que la culpa no es de las X, éstas estaban bien configuradas, aprovechando que utilizo una de las últimas versiones, está configurada para no utilizar HAL a la hora de detectar dispositivos de entrada, y apoyarse directamente en lo que udev le dice.

Si el sistema está recién instalado, podemos ver que la configuración sí que funcionaba perfectamente nada más arrancar, es a la segunda vez cuando ya no hace las cosas bien, esto nos da una pista de que puede haber algún archivo que se escribe y puede estar metiendo la pata… ¡ lo borramos y ya está ! Aunque tendremos que hacerlo cada vez que arrancamos el ordenador. Por otra parte, si enchufamos el teclado o ratón de nuevas, el sistema hace las cosas bien, es decir, podemos desenchufar y enchufar el ratón y no pasaría nada (sería un “problema menor” aunque incómodo), lo malo es si trabajamos desde un portátil.

Dado que la versión 171 de udev es una de las más actuales, y que para la 172 (aún experimental) hay que instalar muchos otros componentes también experimentales, no estaría mal aplicar un pequeño parche antes de actualizar nuestro sistema con componentes que a lo mejor luego nos dan algún problema, además de que para muchas distribuciones aún no están disponibles los paquetes.

Podemos optar por varias soluciones:

Eliminar archivos al apagar el ordenador automáticamente

Consiste en hacer rm -rf /var/run/udev al apagar el ordenador (más adelante pondré un ejemplo parecido, junto con otra solución).

Configurar el servidor X a la antigua usanza

Es decir, configurarlo con la ubicación exacta de los dispositivo. En un portátil no pasa nada, casi siempre vamos a tener los dispositivos en el mismo orden (el teclado, el touchpad, etc), aunque no seremos tan “modernos”, y puede que alguna vez sí que tengamos algún problema si se nos ocurre enchufar un teclado externo o varios dispositivos apuntadores o algo así, de esas veces que a udev se le ocurre asignar nombres diferentes a los dispositivos (eso, cuando todo funciona, no es un problema.

La forma de configurar los dispositivos a la antigua usanza es la siguiente (modificanfo /etc/X11/xorg.conf):

Section "InputDevice"
    Identifier     "Configured Mouse"
    Driver         "evdev"
    Option         "CorePointer"
    Option         "Device" "/dev/input/event1"
EndSection

Section "InputDevice"
    Identifier     "Configured Keyboard"
    Driver         "evdev"
    Option         "CoreKeyboard"
    Option         "Device" "/dev/input/event0"
EndSection

Suponiendo que el teclado está en /dev/input/event0 y el ratón (o touchpad) en /dev/input/event1 . Una forma de averiguarlo rápida y sencilla (ya que evdev no funciona bien) es hacer un cat…

$ ls /dev/input/
by-id  by-path  event0  event1  event2  event3  event4  mice  mouse0
$ cat /dev/input/event0

# Tocar las teclas Control, Mayúscula, Alt y alguna de esas que no imprimen caracteres y ver si sale algo por pantalla. Si vemos que sí, ese dispositivo será nuestro teclado. Si movemos el ratón y sale algo, ese dispositivo será el ratón.

# Control +C para salir, puede que cuando terminemos tengamos que hacer reset en la terminal.

$ cat /dev/input/event1

$ reset

Para saber más acerca de configurar los dispositivos para Xorg de esta forma, se pueden visitar las wikis de Gentoo o de Arch Linux, por poner dos ejemplos.

Desactivar AutoAddDevices en Xorg

Lo podemos hacer añadiendo en /etc/X11/xorg.conf las siguentes líneas:

Section "ServerFlags"
   Option "AutoAddDevices" "false"
EndSection

Esto hará que no se usen los drivers de dispositivos de eventos, sino los tradicionales “kbd” y “mouse”, y en algunas distribuciones tendremos que instalarlos a mano, ya que no vienen.

Hacer como que desenchufamos y enchufamos los dispositivos

Y es que en Linux podemos hacerlo de forma muy sencilla, sólo tenemos que descargar un módulo y cargarlo de nuevo. No me extenderé mucho en la explicación, ya que ésta llegará pronto a este blog, e incluso algo más extendida.

Lo malo es que este método está particularizado para los Debian-like (Debian/*Ubuntu/Linux Mint y otros 1000 más, aunque casi casi al 100% funcionarán en otras distribuciones.

Lo primero que tenemos que hacer es añadir el módulo del kernel evdev (sí, al menos tenemos que tenerlo como módulo, si no, debemos elegir una de las otras formas), para ello editamos /etc/modprobe.d/blacklist.conf y añadimos:

blacklist evdev

ahora lo que debemos hacer es cargar automáticamente el módulo de nuevo, así forzamos a udev a releer los nuevos dispositivos /dev/input/event* que se crearán. Para ello, creamos un script de arranque de esos que vemos en /etc/init.d/… y esto es lo que está particularizado para los Debian Like, haré un copia y pega de mi script, ya lo comentaré en profundidad más adelante. llamémoslo evdev_load. NOTA: los comentarios son necesarios :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/sh
#
### BEGIN INIT INFO
# Provides:     evdev_load
# Required-Start:       $dbus
# Required-Stop:
# Default-Start:        2
# Default-Stop:
# X-Interactive:        true
# Short-Description:    Carga el evdev en el arranque
### END INIT INFO

case "$1" in
        start)
                echo "Cargando evdev"
                modprobe evdev
        ;;
esac

Una vez hecho esto, terminamos el proceso de la siguiente manera:

$ sudo update-rc.d evdev_load start 99 2

para que arranque cada vez que arranquemos el sistema.

Foto: JohnJMatlock

C.I. IX: KGPU, M$ Skype, NOSQL, Twitter VS frustración

Viernes, 13 de Mayo de 2011 Gaspar Fernández 2 comentarios

Os dejo algunos enlaces interesantes recopilados estos últimos días:

  • Speeding Up The Linux Kernel With Your GPU. Lo que leéis, hay un proyecto para acelerar el kernel con la ayuda de la GPU. Patrocinado por NVIDIA y la Universidad de Utah, puede hacer las lecturas/escrituras en sistemas de archivos cifrados 3 ó 4 veces más rápidos. En principio sólo vale para cifrado, pero bueno, sólo es cuestión de pensar qué tareas del kernel se podrán paralelizar y compensa hacer en GPU (vamos, que la transmisión de datos de y a la memoria gráfica no sea más lenta que procesar la tarea en CPU; y que la tarea sea paralelizable).
  • Microsoft adquiera Skype, ¡es hora de usar Ekiga! Ha sido la noticia de la semana, y es que no sabemos qué pasará con Skype a partir de ahora, esperemos que los clientes se sigan manteniendo y la forma de funcionar actual. Aunque es un buen momento para que los desarrolladores de proyectos libres de VoIP se pongan las pilas y mejores bastante sus proyectos, para llegar a ser verdaderos rivales para este servicio. Al final del artículo vemos una imagen que me encanta (sky .net).
  • ¿Has leído la licencia de Microsoft Windows? (Esa que todo el mundo acepta con los ojos cerrados) . De vez en cuando aparece algún artículo similar, pero es cierto que el 99% de los usuarios de Windows no lee la licencia y la acepta, aunque los fabricantes nos dan pocas opciones si se da el caso de que no aceptamos la licencia.
  • ¿Qué son las bases de datos NOSQL? Es un artículo muy interesante sobre este tipo de bases de datos, nos puede servir como un buen punto de referencia para empezar a adentrarnos en este nuevo mundo (muchos enlaces para devorar información).
  • Samsung libera código fuente del software usado en el Galaxy S II . Enhorabuena a Samsung por este movimiento, animará a muchos a tunear el sistema libremente y seguro que se promociona este modelo (y modelos futuros y derivados).
  • Las estrategias de Twitter para minimizar la frustración de los usuarios . Cualquiera diría que Twitter está reduciendo la desesperación de los usuarios, son algunos detalles subliminales curiosos.

WiFi USB Conceptronic C150RUSM (RT3070) Editando el módulo para que funcione

Lunes, 7 de Marzo de 2011 Gaspar Fernández 11 comentarios

c150rusm_prodpiczm_1Si habéis adquirido este adaptador Wifi USB, veréis que Linux, al menos hasta la fecha, no lo detecta, es más, pasa de nosotros, y aunque carguemos el driver a mano con modprobe; seguirá sin pasar.

Afortunadamente, no es nada difícil, y es algo que me hace estar un poco más feliz por utilizar software libre, y es que si el driver no reconoce el dispositivo como suyo, voy a presentárselo.

En principio, no sabía qué driver utilizaba el dispositivo. Busqué en los drivers para Windows, y se instalaba el rt2870, por lo que todo el proceso que diré a continuación lo hice con dicho driver, y no conseguí resultados, así que envié un e-mail a Conceptronics, que afortunadamente tardaron menos de 10h en contestar donde me dijeron que el driver era ralink 3070. Así que fui a la página de descarga de drivers para Linux de Ralink. Una vez ahí descargué el driver correspondiente.

Ahora tenemos que descomprimirlo y buscar en qué archivo están la asociación de dispositivos. (Tendremos que buscar la macro USB_DEVICE):

~/temporal/ $ tar xvjf 2011_0107_RT3070_RT3370_Linux_STA_v2.5.0.1_DPO.tar.bz2
$/temporal/ $ cd 2011_0107_RT3070_RT3370_Linux_STA_v2.5.0.1_DPO/ # Para qué está el tabulador!
~/temporal/2011_0107_RT3070_RT3370_Linux_STA_v2.5.0.1_DPO $ egrep -R ‘USB_DEVICE’ *

Vemos que es el archivo common/rtusb_dev_id.c el que tiene todos los dispositivos.

Ahora, con lsusb miramos cuál es el dispositivo USB que tenemos. En algunas versiones no da descripción del dispositivo, o puede que tengamos demasiados dispositivos conectados, podemos probar ejecutar el comando con el dispositivo enchufado y desenchufado, y comparar, así vemos cuál falta.

A mí me detectaba el dispositivo como un Edimax, en la dirección 7392:3734.

En el archivo common/rtusb_dev_id.c, no encontramos ese dispositivo. Tendremos que buscar la línea {USB_DEVICE(0x7392,0x3734)} y dado que no la encontramos, la creamos, al final de todos los dispositivos.

Sólo queda hacer un make && make install y ya tenemos el módulo funcionando. Antes de trabajar con este dispositivo es necesario levantarlo:

$ ifconfig ra0 up

Aunque la mayoría de los gestores de red lo harán bien. El driver no está del todo completo para este dispositivo, pero nos puede hacer el apaño mientras sale un driver mejor. Y así, le vamos perdiendo un poco de miedo al kernel.

Curioso e interesante VI: Microsoft y los tablets en Francia; La felicidad, una decisión, desarrolladores de Linux, Errores MYSQL por PHPeros, y más

Sábado, 8 de Enero de 2011 Gaspar Fernández Sin comentarios

Llevo mucho tiempo sin publicar, pero quiero dejar aquí algunos links que he visto interesantes estos días:

Instalando el parche milagroso para linux [ SCHED_AUTOGROUP ]

Jueves, 18 de Noviembre de 2010 Gaspar Fernández 3 comentarios

Hace unos días se publicó la noticia de un parche milagroso que aumentaba el rendimiento de Linux en el escritorio en varios medios. Este parche mejoraba el planificador de tareas haciendo que nuestra experiencia de usuario sea más fluida, especialmente cuando estamos ejecutando muchas cosas al mismo tiempo.

Bien, he querido hacer una pequeña guía de instalación del parche. Aunque está hecha en Arch Linux es fácilmente adaptable a cualquier distribución:

Descargar y preparar un kernel actualizado

El parche está pensado para la versión 2.6.36 y aunque seguro que es posible instalarlo en una versión más antigua (en mi ordenador principal tengo una 2.6.25 y hay que liarla, ya que el parche necesita muchas características  de versiones más nuevas)

Lo primero es crear en nuestro home (~) un directorio para hacer todo el proceso, por ejemplo linuxplay (muchos prefieren descargar y compilar en kernel en /usr/src (y también es la Gentoo way), pero vamos a intentar pasar el mayor tiempo posible como usuario y el menor tiempo como root:

~$ mkdir linuxplay

Para descargar la última versión (Noviembre 2010), la 2.6.36:

~$ cd linuxplay

~/linuxplay $ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.36.tar.bz2

Cuando terminemos de descargarlo, lo descomprimimos:

~/linuxplay $ tar xvjf  linux-2.6.36.tar.bz2

Ya tenemos el código fuente de Linux descomprimido y ahora tenemos que crear una configuración similar a la que tenemos, pero en el nuevo kernel:

# Entramos en el directorio donde se ha descomprimido el kernel

~/linuxplay $ cd linux-2.6.36

# Hacemos limpieza de configuraciones anteriores, si acabamos de descargar el kernel no hace

# falta, pero más vale prevenir.

~/linuxplay/linux-2.6.36 $ make mrpropper

# Copiamos la configuración anterior del kernel… puede que algunas distribuciones no nos

# dejen hacer esto, debemos mirar en el manual, o buscar el archivo de configuración, tal vez en /boot/

~/linuxplay/linux-2.6.36 $ zcat /proc/config.gz > .config

Descargar, adaptar y parchear el kernel

Primero bajamos el parche desde aquí: Versión 3 Nov 2010 y lo copiamos en ~/linuxplay/linux-2.6.36/ (el archivo se llama RFC-RFT-v3-sched-automated-per-tty-task-groups.patch).

Esto depende del kernel y además es optativo. El parche debe modificar el archivo drivers/tty/tty_io.c y, por ejemplo, yo lo tengo en drivers/char/tty_io.c por lo que, aunque al aplicar el parche nos iba a preguntar dónde está el archivo, podemos, con sed, decírselo desde ahora.

~/linuxplay/linux-2.6.36 $ sed -i ’s/drivers\/tty\/tty_io/drivers\/char\/tty_io/p’ RFC-RFT-v3-sched-automated-per-tty-task-groups.patch

Ok, vamos a aplicar el parche:

~/linuxplay/linux-2.6.36 $ patch -p1 < RFC-RFT-v3-sched-automated-per-tty-task-groups.patch

Configurar el nuevo kernel

~/linuxplay/linux-2.6.36/ $ make localmodconfig

Esta línea configurará el nuevo kernel como el que ya tenemos, y nos preguntará por novedades optativas que podemos instalar, cuando veamos SCHED_AUTOGROUP decimos que sí, o Y.

También podemos hacerlo de forma más artesana:

~/linuxplay/linux-2.6.36/ $ make oldconfig

~/linuxplay/linux-2.6.36/ $ make menuconfig

Pero de esta forma, tendremos que buscar las novedades a mano, SCHED_AUTOGROUP estará en General.

Compilar el kernel

~/linuxplay/linux-2.6.36/ $ make

# y como root (en Ubuntu o derivadas, podemos usar sudo)

~/linuxplay/linux-2.6.36/ $ make modules_install

Instalar el kernel

Para instalarlo podemos hacerlo de varias maneras, a veces con make install nos vale, pero si queremos controlar el proceso, lo hacemos a mano como dice a continuación (los nombres de archivos pueden variar)

# Donde pone x86 lo mismo puede ser x86_64 dependiendo de vuestra arquitectura

~/linuxplay/linux-2.6.36/ $ cp arch/x86/boot/bzImage /boot/vmlinuz-2.6.36

~/linuxplay/linux-2.6.36/ $ cp System.map /boot/System.map-2.6.36

# Donde pone 2.6.36-ARCH es la versión de vuestro kernel, depende también de la distribución.

# pero una forma fácil de sacarla es hacer: ls /lib/modules/

~/linuxplay/linux-2.6.36/ $ mkinitcpio -k 2.6.36-ARCH -g /boot/kernel26-2.6.36.img

Ok, sólo falta hacer una entrada en vuestro gestor de arranque, aquí muestro un ejemplo para Grub 0.97:

# Como root (o con sudo), y con vuestro editor favorito: nano, emacs, gedit, vi…

~/linuxplay/linux-2.6.36/ $ nano /boot/grub/menu.lst

Necesitamos añadir estar líneas, antes del primer title que encontramos, pero lo mejor que podemos hacer es copiar exactamente las líneas de un kernel que funcione ahora mismo, por ejemplo:

# For booting GNU/Linux
title  GNU/Linux (2.6.35)
root (hd0,0)
kernel /boot/vmlinuz-2.6.35 root=/dev/disk/by-uuid/12345678-9abc-def0-1234-56789abc123456 ro
initrd /kernel26-2.6.35.img

Bien, tenemos que añadir un bloque parecido, y cambiar los datos que vienen por los nuevos; manteniendo el anterior en una línea más abajo podemos cargar el kernel antiguo si algo va mal.

# For booting GNU/Linux
title  GNU/Linux (2.6.36) Parche SCHED_AUTOGROUP
root (hd0,0)
kernel /boot/vmlinuz-2.6.36 root=/dev/disk/by-uuid/12345678-9abc-def0-1234-56789abc123456 ro
initrd /kernel26-2.6.36.img

Guardamos los cambios, reiniciamos y a correr… a reproducir  películas y compilar programas al mismo tiempo que movemos las ventanas sin sentido :)

Curioso e interesante IV: El miedo a emprender, un profesor curioso, redimensionado de imágenes, módulos del kernel

Jueves, 11 de Noviembre de 2010 Gaspar Fernández 4 comentarios

Hace casi 4 meses que no publico una recopilación de links interesantes, y creo que es constructivo compartir con los demás mis descubrimientos de blogs y webs que me han llamado la atención; e intentaré hacerlo más a menudo:

El miedo a emprender

Es el blog de un amigo, y ha sido retomado con fuerza y artículos interesantes. Aquí os dejo los links de tres de sus últimos artículos:

El miedo a Emprender (I): El origen (post-1)

El miedo a emprender (II): Consejos para gestionalo (post-2)

El miedo a emprender (III): Herramientas para enfrentarlo (post-3)

Ver para creer

El profesor que a todos nos hubiera encantado tener: Es interesante ver cómo se curra las clases este profesor de matemáticas, y el tiempo que habrá echado para montarlo todo.

Making Of de Sintel: Un documental de una hora del proceso de creación del último de la fundación Blender. Es un corto hecho exclusivamente con herramientas libres.

Redimensionar imágenes al vuelo: Desde Pixelco blog nos hablan de un nuevo servicio online (resizer.co), que nos permitirá redimensionar imágenes al vuelo. Es decir, nosotros le pasamos una URL de imagen a este servicio, y las dimensiones con las que queremos la foto, y ellos nos sirven la foto. Lo malo es que las imágenes pueden pesar como máximo 1Mb.

4 Formas de encontrar fotografías con la licencia adecuada para tu blog: El título lo dice todo. En este blog, a veces he utilizado fotos de Flickr Creative Commons o imágenes mías, aquí encontramos más ideas.

Programación

Programar un módulo del kernel simple: El título lo dice todo, es un ejemplo guiado y muy completo. Un poco antiguo el post, pero es algo que nunca pasa de moda :)

Más

¿Dos cabezas piensan mejor que una?: Es lo que se suele decir, ¿cuánto hay de cierto en ello?

Envía un mensaje al congreso contra la Ley Sinde: Si eres ciudadano español te interesa.

REISUB y llamadas remotas a Alt+Sysrq

Domingo, 29 de Agosto de 2010 Gaspar Fernández Sin comentarios

En muchos sitios, podemos ver esta palabra clave, para muchos RESUIB para otros RESIUB y normalmente REISUB. Y sirve para reiniciar el sistema Linux de forma segura después de que el sistema se congele; de la siguiente forma: Alt+Imprimir Pantalla + R,E,I,S,U,B (no hace falta soltar las teclas Alt + Imprimir pantalla). Cada letra representa una acción del kernel:

  • R (Devuelve el control al teclado unRaw)
  • E (Termina todos los procesos tErm)
  • I (Mata los procesos que queden vivos full kIll)
  • S (Sincroniza los discos Sync)
  • U (Monta todos los sistemas de archivos como sólo lectura Umount)
  • B (Reinicia el ordenador Boot)

Bien, si tenemos acceso físico al ordenador, no hay problema, pero y si estamos enchufados en otra máquina ? Todo está en el fichero especial /proc/sysrq-trigger.

Obteniendo información de los procesos

Enviando a /proc/sysrq-trigger (como root) la letra correspondiente a la acción del kernel vale. Empezaremos pidiendo ayuda:

root $ echo “h” > /proc/sysrq-trigger

root $ dmesg | tail

…. # Nos dirá muchas cosas, sólo nos interesa la última línea
SysRq : HELP : loglevel0-8 reBoot tErm Full kIll saK showMem Nice powerOff showPc show-all-timers(Q) unRaw Sync showTasks Unmount shoW-blocked-tasks

Vemos cómo el kernel a través de dmesg se comunicará con nosotros. Cada letra mayúscula nos indicará una acción diferente, empezaremos obteniendo información sobre la memoria:

root $ echo “m” > /proc/sysrq-trigger

root $ dmesg | tail -n 35

O información sobre tareas bloqueadas:

root $ echo “m” > /proc/sysrq-trigger

root $ dmesg

Más acciones

Incluso podemos lanzar el OOM killer con la siguiente línea:

root $ echo “f” > /proc/sysrq-trigger

Terminar todos los procesos (igual que comentábamos arriba del todo):

root $ echo “e” > /proc/sysrq-trigger

Cambia el nivel de información de dmesg (del 0 al 8):

root $ echo 5 > /proc/sysrq-trigger

Para enviar un REISUB es algo más elaborado:

root $ nohup bash -c “for key in s u b; do echo \$key > /proc/sysrq-trigger; sleep 4; done”

Aunque tendremos que asegurarnos de que las tareas estén muertas, ya que, nuestra conexión ssh, o nuestro terminal, o incluso bash, se mueren al mandar un E o un I al kernel (dando igual el nohup). Por otra parte, la R la podemos quitar, ya que vale para devolver el control al teclado, y estamos desde un equipo remoto.

Seguridad

Pero tanto por nosotros mismos (debemos de protegernos de meter la pata), como los posibles usuarios del ordenador, tal vez no nos interese que puedan pulsar en teclado alguna combinación de teclas que comprometa al kernel. Para ello, tenemos  /proc/sys/kernel/sysrq o directamente el comando sysctl del cual modificamos la propiedad kernel.sysrq; lo haremos de la siguiente manera:

root $ sysctl kernel.sysrq=0 # Para desactivar Alt+SysRq

root $ sysctl kernel.sysrq=1 # Para activarlo

Se pueden activar algunos comandos sólo, dependiendo del número que se indique.

Terminal transparente para visualizar logs

Jueves, 5 de Agosto de 2010 Gaspar Fernández Sin comentarios

screenshot-01-08-2010-140805Es muy de 2002/2003, aunque todavía a muchos les gusta tener un pequeño terminal transparente en el fondo para ejecutar comandos o mostrar logs u otra información importante.

Aquí comentaré algunas soluciones que he encontrado y cómo obtenerlas.

xrootconsole

Es muy ligero y rápido. Y vale para mostrar logs en xroot; el fondo es supuestamente transparente, aunque si cambiamos el fondo veremos que no, ya que en la ventana de xrootconsole se mantendrá el fondo anterior. Está bien para hacer el apaño, pero no lo recomiendo. La forma de ejecutar xrootconsole es:

$ xrootconsole [fichero]

donde fichero es el que vamos a vigilar, la visualización se actualiza automáticamente con cada cambio que se observa en el archivo. Es ideal para ver /var/log/messages.

aterm

Muestra un terminal transparente, con muchas opciones, y que podemos ejecutar de la siguiente manera para mostrar las últimas líneas de dmesg en el escritorio:

$ aterm -fg black -geometry 100×10+0+0 -e watch –no-title -n10 -d ‘dmesg | tail’

donde:

-fg Indica el color de las letras
-geometry Indica la posición y dimensiones de la ventana: ancho x alto + x + y
-e Ejecuta el comando que especificamos a continuación (La referencia del comando watch la incluyo al final del post

Por supuesto podemos sustituir el comando que esta en negrita por lo que queramos mostrar.
Aún así, de esta forma aterm nos muestra decoración de ventana, barra de scroll y no es transparente. Esto lo podemos solucionar ejecutando aterm de la siguiente manera:

$ aterm -tr -bl -sb -fg black -geometry 100×10+0+0 -e watch –no-title -n10 -d ‘dmesg | tail’

-tr Ventana transparente
-bl Ventana sin borde
-sb Ventana sin barra de desplazamiento (scrollbar)

O, editando el archivo $HOME/.Xdefaults y añadiendo estas líneas

aterm*transparent:true
aterm*borderLess:true
aterm*scrollBar:false

El problema de aterm es que no admite sombra en las letras, por lo que la lectura sobre algunos fondos es algo complicada.

Eterm

Este emulador de terminal es el más completo y tiene más opciones, y por lo menos es el que soporta poner sombra en las letras, lo que proporciona una mejor visibilidad, y es el que aparece en la captura de pantalla que hay arriba. Para ello, lo podemos ejecutar de la siguiente forma:

Eterm –buttonbar 0 –scrollbar off -f white -n dmessenger -g 211×10+0+0 -O -0 -e watch –no-title -n10 -d ‘dmesg | tail’

–buttonbar 0 Elimina la barra de menú y botones superior
–scrollbar off Elimina la barra de desplazamiento.
-f white Especifica el color de las letras (blanco en este caso)
-n dmessenger Especificamos el nombre de la aplicación, la llamamos dmessenger. Será útil más adelante.
–O (letra o) Hace la ventana transparente
-0 (cero) Activa algunas optimizaciones de transparencia (sobre todo para ventanas que no se moverán demasiado), desactivar esta opción si no funciona correctamente o hay fallos en la ventana.
-x La pondré más adelante, elimina la decoración de la ventana y oculta el terminal de la barra de aplicaciones.
-g Indica la posición y dimensiones de la ventana: ancho x alto + x + y
-e Ejecuta el comando que especificamos a continuación (La referencia del comando watch la incluyo al final del post

Aunque veremos un problema, la decoración de la ventana, para ello hay varias soluciones, dependiendo del sistema en el que trabajemos, para muchos, la solución será incluir el parámetro -x:

$ Eterm -x –buttonbar 0 –scrollbar off -f white -n dmessenger -g 211×10+0+0 -O -0 -e watch –no-title -n10 -d ‘dmesg | tail’

(en negrita aparece el comando, en cursiva un comando opcional), aunque a veces el entorno de ventanas, entre ellos Fluxbox, el que uso actualmente, no se lleva muy bien con ese modo sin decoración de ventanas, y aunque se muestra bien, la ventana aparece sobre todas las demás (on top).
Para solucionar eso, nos vamos a complicar un poco la vida. Para ello, editamos el archivo $HOME/.fluxbox/apps y añadimos las siguientes líneas:

[app] (name=dmessenger)
[Deco] {NONE}
[Sticky] {yes}
[Layer] {10}
[end]

Y a la hora de ejecutar Eterm lo hacemos de la siguiente manera:

Eterm –buttonbar 0 –scrollbar off -f white -n dmessenger -g 211×10+0+0 -O -0 -e watch –no-title -n10 -d ‘dmesg | tail’ & sleep 2 && wmctrl -r dmessenger -b add,skip_taskbar

donde ejecutamos Eterm en segundo plano (al terminar el comando con &) y ejecutamos un sleep 2 (para esperar 2 segundos antes de ejecutar el siguiente comando), a continuación ejecutamos wmctrl donde,

-r dmessenger Especificamos el nombre de la ventana a ocultar; en este caso dmessenger
-b add,skip_taskbar Eliminamos la aplicación Eterm de la barra de aplicaciones, si queremos que la ventana aparezca también por debajo de las demás ventanas, podemos añadir la opción below de la siguiente forma: -b add,skip_taskbar,below

dmesg

En el ejemplo estamos ejecutando dmesg de la siguiente forma (con la ayuda de watch):

watch –no-title -n10 -d ‘dmesg | tail’

donde,

–no-title watch introduce un título donde indica el periodo de actualización, con este modificador lo eliminamos.
-n10 dmesg no está cambiando continuamente, por lo que escogemos un periodo de actualización de 10segundos (podemos modificar este parámetro como queramos)
-d ‘dmesg | tail’ Obtenemos los últimos 10 mensajes del kernel, podemos incluir un modificador -n4 a tail para obtener sólo las últimas 4.

Visita otras webs de la red