jun
13
2010

Licenças para módulos no Linux

O arquivo /usr/src/linux/include/linux/module.h define as licenças aceitáveis para um módulo (ou driver) seja reconhecido como software livre.

  • GPLGNU Public License v2 or later
  • GPL v2GNU Public License v2
  • GPL and additional rightsGNU Public License v2 rights and more
  • Dual BSD/GPLGNU Public License v2  or BSD license choice
  • Dual MIT/GPLGNU Public License v2 or MIT license choice
  • Dual MPL/GPL - GNU Public License v2 or Mozilla license choice
Também há um espaço (infelizmente) para licenças proprietárias:
  • Proprietary - Non free products

Como vocês podem notar, há componentes que podem ser definidos com licenças duplas, contudo quando executado no Linux apenas a GPL é relevante. Algumas razões para definir a licença:

  1. O modinfo pode mostrar informações para usuários que desejam avaliar as licenças dos módulos sua instalação.
  2. A comunidade pode ignorar relatórios de bugs dos módulos proprietários.
  3. Os fabricantes podem fazer o mesmo com suas próprias políticas.

Para inserir a licença, basta colocar no seu código-fonte a macro  ”MODULE_LICENCE”. Exemplo:

  MODULE_LICENCE("GPL");

Lembre-se que alguns recursos do kernel são disponíveis apenas se seu código é livre.

Um exemplo é o sysfs (através da macro EXPORT_SYMBOL_GPL) que por questões de manutenção e consistência exige que você licencie seu módulo em alguma licença compatível com a GPL.

jun
08
2010

NFS errors

If you use NFS to mount your root filesystem you should probably faced with this problem:

Root-NFS: Unable to get mountd port number from server, using default
Root-NFS: Server returned error -5 while mounting /my/nfs/server/path/
VFS: Unable to mount root fs via NFS, trying floppy.

The -5 and -13 are the most common on my daily usage, but I always forgot what this number means… So, I decided to get it from source by checking nfs-utils package. The following values where extracted  from utils/mount/error.c.

EPERM  ........................................ -1

ENOENT ........................................ -2

EIO ........................................... -3

ENXIO ......................................... -4

EACCESS ....................................... -5 

EEXIST ........................................ -6

ENODEV ........................................ -7

ENOTDIR ....................................... -8

EISDIR ........................................ -9

EINVAL ........................................ -10

EFBIG ......................................... -11

ENOSPC  ....................................... -12

EROFS ......................................... -13

ENAMETOOLONG .................................. -14

ENOTEMPTY ..................................... -15

EDQUOT ........................................ -16

ESTALE ........................................ -17

EWFLUSH ....................................... -18

Knowing what each error status means allow you quick fix the problems.

jun
06
2010

idéia inspiradas por applescript, kde e d-bus

Tudo começou numa tentativa que fiz para automatizar uma tarefa - reiniciar o AirPort no MacOSX - em 10 minutos no Google consegui as informações necessárias para fazer um script na linguagem AppleScript. Isso me fez pensar em algumas coisas sobre a interatividade que obtemos nos ambientes atuais e as possibilidades nos ambientes livres.

Veja um exemplo feito no AppleScript simples para mostrar a janela com as preferências de rede (System Preferences -> Network).

Nota: (1) se o você for testar e seu sistema estiver em Português, lembre-se de traduzir os nomes entre aspas.  (2) Para rodar os scripts é preciso marcar a opção Enable access for assistive Devices em System Preferences -> Universal Access
tell application "System Preferences"
	activate
	set current pane to pane "com.apple.preference.network"
end tell

Para desligar/ligar o AirPort:

tell application "System Events"
	tell process "System Preferences"
		tell window "Network"
			tell group 1
				if (exists button "Turn Airport Off") then
					click button "Turn AirPort Off"
					delay 3
				end if
				if (exists button "Turn Airport On") then
					click button "Turn AirPort On"
				end if
			end tell
		end tell
	end tell
end tell

Veja que é uma tradução em palavras (praticamente verbos no imperativo) do que seria o processo feito no modo gráfico. Se você programa em Python, existe um comparativo.

Ambientes livres

E é justamente com Python que vejo uma alternativa interessante para controlar as aplicações como o System Settings. Talvez o jeito mais fácil de fazer isso seria através de uma comunicação IPC como o D-BUS . Inclusive o system settings é exportado em org.kde.systemsettings.

$ qdbus org.kde.systemsettings

Resumindo, o acesso pode não ser tão fácil quanto no AppleScript mas o “meio” já existe em ambiente gráficos tal como KDE e  GNOME. O Python lida muito bem com este tipo de comunicação e é uma saída para quem está procurando um jeito para controlar seu ambiente de forma automatizada.

Futuro

Na minha opinião há uma deficiência para (A) pessoas leigas, se quiserem, controlar seus aplicativos de forma automatizada e (B) melhorar as formas de usabilidade nas interfaces existentes.

Fico imaginando se não seria interessante um investimento (e pesquisa) para criar linguagens de programação que herdem construções da “fala” para acessar aplicativos, para no futuro utilizar da “voz” humana para controlar o computador.

O software livre é um terreno vasto para esse tipo de experiência. Cito algumas tecnologias que tornaria isso possível:

  • D-bus para comunicação entre os aplicativos
  • Python como linguagem de programação para construir as “amarras”
  • NTLK (Natural Language Toolkit) para processar a linguagem

Se você trabalhar com algum tipo de pesquisa na área ou tem experiência, por favor, deixe um comentário.

Bom começo de semana a todos.

mai
31
2010

Básico de passagem de parâmetros em C++

para não acontecer certos erros que vi por aí…

Em C++ há três maneiras de passar um parâmetro para uma função, as tradicionais herdadas da linguagem C: valor e ponteiro; além da novidade: a passagem por referência. Para ilustrar veja o seguinte exemplo, passar uma estrutura de dados “grande” (neste caso aproximadamente 10 kilobytes) para uma função:

#include<iostream>
#include <string.h>

using namespace std;

struct Big {
char text[10000];
int id;
};

void f1( Big v ) {
cout << v.text << endl;
cout << “Ox” << hex << v.id << endl;
}

void f2( const Big *v ) {
cout << v->text << endl;
cout << “Ox” << hex << v->id << endl;
}

void f3( const Big &v ) {
cout << v.text << endl;
cout << “Ox” << hex << v.id << endl;
}

int main(int /*argc*/, char * /*argv*/[]) {

Big *b0 = new Big;
Big b1;
Big &b2 = b1;

strcpy(b0->text,“asdfg asdfg asdf asdf asdf asdf”);
strcpy(b1.text,“azsxd azsxd azsxd azsxd azsxd azsxd”);

b0->id = 0xbc;
b1.id = 0xde;

f2( b0 ); /* pointer */
f1( b1 ); /* value */
f3( b2 ); /* reference */
}


Veja o código assembly gerado pelo compilador (g++) para cada um dos três casos:

1) Ponteiro

mov    -0xc(%ebp),%eax
mov    %eax,(%esp)
call   0x8048885

2) Valor

movl   $0x0,-0x2728(%ebp)
lea    -0x2720(%ebp),%eax
mov    %eax,-0x272c(%ebp)
jmp    0x8048a36
mov    -0x272c(%ebp),%ecx
mov    -0x2728(%ebp),%edx
movzbl (%ecx,%edx,1),%eax
mov    -0x2728(%ebp),%edx
mov    %al,(%esp,%edx,1)
addl   $0x1,-0x2728(%ebp)
cmpl   $0x2714,-0x2728(%ebp)
jb     0x8048a16
call   0x80488fe

3) Referência

mov    -0x8(%ebp),%eax
mov    %eax,(%esp)
call   0x804880c

Talvez seja importante:

  • Se você prefere a sintaxe da intel? Mude no GDB: set disassembly-flavor intel
  • Não precisa ser muito esperto para ver que a passagem por valor é a pior de todas, veja quanto código assembly foi gerado [#fail]
  • A passagem por referência é inclusive mais eficiente pois aloca no %ebp (base pointer) [8 bytes ao invés de 12 bytes do ponteiro].
  • A passagem por referência provê a eficiência da passagem por ponteiros com a clareza da passagem por valor.
mai
10
2010

td

Estou utilizando o Vim et all, para escrever o texto do meu trabalho de conclusão de curso (conhecido também como trabalho de diploma, td), são basicamente as ferramentas:

  1. vim – editor
  2. aspell – correção ortográfica
  3. bibtex – referencias textuais
  4. latex – processador de texto
  5. abntex – padrão do documento

A norma (!) diz que as palavras estrangeiras devem ser escritas em itálico. Como é um texto técnico, há o uso frequente de palavras in english e o risco de deixar uma para trás é grande. Como a motivação para não escrever é maior, dispersei e acabei fazendo um programa que a partir de uma entrada (CSV) varre o texto e insere o itálico quando for necessário. O protótipo até agora esta assim:

O código ainda não está limpo para torná-lo acessível num repositório on-line. Além disso, acho que há outras maneiras mais eficazes: sed, python, etc. Como não sei quando vou ter tempo para torná-lo útil de verdade, vou colar aqui as duas partes do código que achei interessante.

A alteração no texto é simples: primeiro varremos o texto procurando pelo termo (*palavra é um iteraror da QStringList) e associamos um índice para cada ocorrência (indexOf) adicionando em uma lista (pos é um QList<int>). Antes de fazermos a troca (replace) comparamos com outra lista (blacklist) se essa inserção já não está dentro de um \textit. Se isso não acontecer, pode existir casos do tipo: \textit{\textit{itálico}}.

while ((i=s.indexOf(*palavra,i+1)) != -1)
	pos << i;

for (index=0, offset=0; index < pos.length() ; index++)
	if (blacklist.contains(pos.at(index)) == false) {
		str = "\\textit{" + *palavra + "}";
		s.replace(pos.at(index)+offset,(*palavra).length(),str);
		offset += 9;
	}

A construção da blacklist pode também ser aproveitada para evitar outros contextos, como notas de rodapé. Apenas trocar o \\textit pelo \\footnote.

while ((a=s.indexOf("\\textit{",b+1)) != -1) {
	b = s.indexOf("}",a);
	if ((c=s.indexOf(*palavra,a)) < b)
		blacklist << s.indexOf(*palavra,a);
}

Conclusão: esse post nem era para existir, mas quem sabe eu não invento algum programa que escreva o texto sozinho :P

Até mais!

abr
29
2010

latex + abntex

Estou fazendo uma série de experimentos com um conceito novo para apresentações, já refiz uma palestra apresentada no Calourada Livre e agora um teste em forma de tutorial. Penso que boa parte do sucesso deste tipo de abordagem é a busca contemporânea por informação rápida. Note, tudo que fiz está disponível na documentação. Entretanto, a estética como é apresentado facilita a compreensão. Esta apresentação mostra uma maneira independente de instalar o pacote abntex utilizado para contruir documentos em conformidade com o padrão definido pela ABNT.

http://prezi.com/aum-fzbgnkyl/latex-abntex/

abr
26
2010

kthreads (1)

Creating a thread at kernel-space

Now that I know that somebody at Academia reads my posts :-) I’ll put code with a _little_ documentation information together. Today we will do a quick review about kernel threads or to be more precisely, a way to perform some operations in the background. Kernel threads are standard process that:

  1. Exist solely in kernel-space.
  2. Don’t have an address space.
  3. Don’t context switch to user-space.
  4. Are schedulable and preemptable as normal process.

And let’s see an example:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/delay.h>

static int thread3(void *unused) {

	int count3 = 0;
	while (count3 < 1000) {
		msleep(100);
		printk("Thread 3: %d\n", count3++);
	}
	return 0;
} 

static int thread2(void *unused) {

	int count2 = 0;
	while (count2 < 1000) {
		msleep(10);
		printk("Thread 2: %d\n", count2++);
	}
	return 0;
}

static int __init threads_init(void)
{
	int count1;
	int ret1, ret2;

	count1 = 0;
	ret1 = kernel_thread(thread2, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD );
	ret2 = kernel_thread(thread3, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD );

	printk("-- kernel thread: module init\n");
	printk("-- kernel thread: spawning thread 1 ret=%d\n", ret1);
	printk("-- kernel thread: spawning thread 2 ret=%d\n", ret2);	

	/*
	   Don't use "long" loops on init().
	   If you uncomment the snippet below the insmod will lock until while finishes
	*/ 

	/*
	while (count1 < 1000) {
		msleep(10);
		printk("Thread 1: %d\n", count1++);
     	}
	*/

    return 0;
}

static void __exit threads_exit(void)
{
    printk("-- kernel thread: module removed\n");
}

module_init(threads_init);
module_exit(threads_exit);

MODULE_AUTHOR("Tiago Maluta <maluta@unifei.edu.br");
MODULE_DESCRIPTION("kthreads examples");
MODULE_LICENSE("GPL");

Things from code that are found in docs…

  • CLONE_FS means that parent and child share filesystem information.
  • CLONE_FILES means that parent and child open files.
  • CLONE_SIGHAND means that parent and child share signal handlers.

I use arbitrarily msleep() just to allow user “see” what is happening when dumping kernel ring buffer.

abr
21
2010

latex + bibtex

Tá tudo certo e nada funciona?

Supondo que você tenha dois arquivos.

  1. artigo.tex
  2. biblio.bbl

E está tendo erros quando tenta fazer uma citação (\cite{Autor}), tipo:

  • LaTeX Warning: There were undefined references.
  • LaTeX Warning: Citation `XXXX’ on page n undefined on input line N.

Isso acontece pois alguns arquivos precisam ser gerados (basicamente o aux, bbl e blg) e há uma dependência circular. A solução é simples:

pdflatex artigo.tex
bibtex all
pdflatex artigo.tex
pdflatex artigo.tex