Entenda o systemd vs upstart

Originalmente publicado no PoliGNU.

Por quê mudar?

Recentemente o projeto Debian passou por um intenso debate para decidir que sistema de inicialização deveria substituir o venerável (porém antiquado) system v como padrão do sistema para a próxima release, codename jessie.
A razão para mudar pode não parecer óbvia, especialmente para os muito apegados à ideia de “UNIX” ou que simplesmente estão acostumados a como as coisas funcionam hoje, mas fica clara quando se analisa os principais problemas enfrentados por sistemas que ainda usam sistemas de init system v. Pra começo de conversa, o init não conhece muitas das novidades tecnológicas que apareceram nas últimas décadas.
Peguemos como exemplo o controle de hardware: um daemon que precise ser iniciado quando um determinado tipo de hardware é plugado não será executado automaticamente pelo init se for plugado, o que exige que além de ter lógica para tratar o caso no boot, também se tenha que ter outros mecanismos para reagir ao hot-plugging.
Ser um conjunto de scripts shell também causa uma infinidade de problemas. Como cada script deve reinventar a inicialização do daemon que controla, é bastante comum que eles não sejam 100% resilientes a problemas como deixar processos (principais ou filhos) para trás quando quem administra o servidor pede que o serviço seja parado. Isso acaba exigindo intervenção de quem administra, matando manualmente os processos.
O desempenho também é um problema que passou muito tempo sem solução. Com o aparecimento de computadores com múltiplas CPUs e com espera de rede se tornando um problema foi inventado um sistema de paralelizar a execução dos scripts de inicialização, o que trouxe consigo a enorme complexidade de ter que estabelecer dependências entre os scripts, para garantir que só sejam executados em paralelo scripts que possam sê-lo. Mas isso também é muito mais complexo do que parece – as dependências em sistemas modernos são muito mais sutis e variáveis do que pode parecer em primeira análise. Além disso, executar cada script desse gera um overhead não desprezível.
Por último, o diagnóstico de falhas de inicialização de serviços é absurdamente complexo; raramente se sabe em que arquivo de log estarão as mensagens relevantes e com alguma frequência sequer haverá logs da falha propriamente dita em algum lugar, restando a quem administra executar o serviço manualmente e ver o que acontece.
Para resolver alguns ou todos esses problemas vieram os novos sistemas de init. Na verdade o Mac OS X saiu na frente com o launchd, mas essa é história pra uma outra oportunidade, comecemos pelo upstart, que nasceu no Ubuntu há alguns anos atrás.

Upstart

O upstart surgiu quando a principal preocupação das pessoas estava em melhorar o desempenho do boot através de paralelismo. A ideia é substituir a necessidade de estabelecer dependência entre os serviços de forma declarativa e ao invés disso estabelecer condições para que um serviço esteja “pronto” para ser executado.
No sistema de dependências inventado para o system v começa pelo objetivo: preciso rodar rodar o procedimento que monta sistemas de arquivo remotos, pra isso preciso rodar as dependências dele que são montar os sistemas de arquivo locais e estabelecer conexão de rede. O upstart inverte essa lógica e começa dos procedimentos que tem nenhuma dependência, o que vai tornando outros procedimentos “prontos” e os executa a partir daí.
A ideia é que o sistema de init reage a eventos, que podem ser um serviço estar estabelecido mas também podem ser de outra natureza: um hardware ser plugado, por exemplo. Isso resolve o problema do desempenho, em certa medida e cria um framework que permite ao sistema de init continuar cuidando do sistema enquanto ele estiver ligado, iniciando e parando serviços conforme as condições do sistema mudam.
Há alguns poréns a respeito dessa estratégia, que quem tiver curiosidade achará com facilidade nos frequentes debates travados entre Lennart Poettering e os proponentes do upstart, mas eu queria chamar a atenção para um em particular: usando eventos não existe garantia de que um serviço esteja de fato em execução plena quando o seu procedimento de inicialização conhecido pelo upstart termina – anote isso mentalmente.
Finalmente, o upstart acaba não resolvendo os problemas de diagnóstico, nem de processos perdidos sendo deixados pelo sistema (embora uma solução que adota a ideia do systemd para isso esteja sendo criada), principalmente por as receitas de init usadas pelo upstart serem ainda scripts shell customizados.

Systemd

O systemd é criação de Lennart Poettering, que é funcionário da Red Hat e contribuidor do Fedora. Daí muita gente atribuir o systemd à Red Hat, no que se enganam: embora hoje a Red Hat tenha inúmeros projetos com o systemd no centro, a ideia original e o esforço original foram feitos por Lennart em seu próprio tempo e não como um projeto da empresa.
A motivação para sua criação é bem mais ambiciosa que a que originou o upstart: a ideia é que há inúmeras funcionalidades que o kernel Linux que são incríveis e extremamente avançadas e que acabam não sendo usadas a não ser em ambientes muito específicos, porque não há infra-estrutura comum no espaço de usuário para fazer uso da funcionalidade e disponibilizá-la para o resto do sistema.
Um exemplo: cgroups. Os Control Groups são formas de juntar processos em uma embalagem que permite tratar esse grupo de processos como um todo. Esses grupos podem ser usados por exemplo para limitar que partes do sistema os processos que o compõe podem ver, criando uma visão virtual mais limitada do sistema de arquivos, por exemplo, ou limitando as interfaces de rede que os processos podem ver. Também podem ser usados para tornar o agendamento de tempo das tarefas no processador mais adequado ao sistema, ou impor limites de uso de memória, de operações de I/O e assim por diante.
Uma das primeiras funcionalidades trazidas pelo systemd foi exatamente o uso de Control Groups. Cada serviço iniciado pelo systemd o é dentro de um cgroup próprio, o que significa por exemplo que todos os processos criados por aquele serviço podem ser – com certeza – terminados quando o serviço é parado. Também significa que apesar de seu apache estar consumindo muito CPU ou memória, seu servidor SSH ainda tem um naco suficiente do tempo de CPU para aceitar sua conexão que será usada para tratar do problema, já que o Linux tenta ser justo com os diferentes cgroups.
Além de tudo isso, o uso de cgroups ainda dá ao systemd a capacidade de garantir que não fiquem processos pra trás quando um serviço é parada: como processos criados por processos que foram colocados num control group também são colocados nesse control group, basta terminar todos os processos do control group para que não sobre nenhum. O pessoal do upstart pensou em adotar essa ideia.
Mas o systemd também atacou o problema do desempenho, de duas formas: a primeira foi a ideia de remover completamente scripts shell da jogada. Cada serviço é especificados num arquivo de configuração chamado “unit”, que descreve todas as informações que o init precisa para iniciar e cuidar do processo. Isso retira da equação a necessidade de iniciar um interpretador shell e de executar os complexos scripts usados atualmente com system v.
A segunda foi dando uma solução um pouco mais inusitada à questão das dependências. A ideia é simples: a maioria dos serviços abre sockets de algum tipo para receber pedidos de seus clientes. O X, por exemplo, cria um socket UNIX em forma de arquivo no /tmp. O que o systemd faz é criar todos os sockets dos serviços que controla (eles estão descritos nos arquivos unit) e, quando recebe uma conexão, inicia o serviço e passa pra ele o socket.
O interessante dessa solução é que ela 1) estabelece a relação de dependência na vida real: o serviço é iniciado quando alguém pede e 2) garante que os clientes que forem iniciados vão ter seu primeiro request atendido, não há mais o problema de não saber quando o serviço está plenamente ativo (lembra da nota mental no caso do upstart?).
Para completar, o systemd controla as saídas padrão e de erro dos serviços que inicia e pode facilmente mostrar as últimas linhas de log de um serviço quando sua execução falha, tornando muito simples o diagnóstico:
kov@melancia ~> systemctl status mariadb.service
mariadb.service - MariaDB database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled)
Active: active (running) since Seg 2014-02-03 23:00:59 BRST; 1 weeks 3 days ago
Process: 6461 ExecStartPost=/usr/libexec/mariadb-wait-ready $MAINPID (code=exited, status=0/SUCCESS)
Process: 6431 ExecStartPre=/usr/libexec/mariadb-prepare-db-dir %n (code=exited, status=0/SUCCESS)
Main PID: 6460 (mysqld_safe)
CGroup: /system.slice/mariadb.service
        ├─6460 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
        └─6650 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plug...
	Fev 03 23:00:57 melancia mysqld_safe[6460]: 140203 23:00:57 mysqld_safe Logging to /var/log/mariadb/mariadb.log.
	Fev 03 23:00:57 melancia mysqld_safe[6460]: 140203 23:00:57 mysqld_safe Starting mysqld daemon with databas...mysql
	Fev 03 23:00:59 melancia systemd[1]: Started MariaDB database server.
	Hint: Some lines were ellipsized, use -l to show in full.

A questão de licenciamento

De extrema importância quando falamos de Software Livre são a questão de licença e de copyright do código. O systemd é licenciado sob a LGPL versão 2.1 ou superior, o que permite que programas proprietários sejam linkados com suas bibliotecas. O copyright das contribuições feitas ao código é mantido pelos colaboradores. Um projeto de software livre bastante comum desse ponto de vista.
Já o Upstart, sendo criação da Canonical segue o que tem sido sua política há algum tempo: usa uma licença GPL (versão 2) e exige que contribuidores assinem um Contributor License Agreement compartilhando os direitos de copyright com a Canonical. Com isso, a Canonical fica sendo a única dona do copyright do conjunto e pode fazer por exemplo alterações de licença, ou lançar uma versão proprietária se entender que deve.
Em primeira análise isso não parece ser um problema: de fato, há várias licenças mais permissivas usadas por outros softwares, como as licenças BSD, que permitem às pessoas fecharem o código. A grande questão aqui é que com esse modelo não é qualquer pessoa que pode fazer isso, só a Canonical pode. Essa acaba sendo uma forma de desnivelar as oportunidades artificialmente, criando um monopólio do privilégio de lançar versões proprietárias.

Futuro

Atualmente dois sistemas importantes usam upstart: Ubuntu e Red Hat Enterprise Linux 6, que é a versão atual suportada da Red Hat. O systemd foi adotado inicialmente pelo Fedora, o que significa que a futura RHEL 7 também estará usando systemd. Algumas outras distribuições passaram a usar systemd ou como padrão ou como opção bem suportada, como o SuSE e o Arch Linux, por exemplo.
Com a adoção dele pelo Debian como padrão, todas as grandes distribuições base passarão a ser baseadas no systemd. Para surpresa de muitos (minha inclusive), Mark Shuttleworth anunciou que dada a decisão do projeto Debian, o Ubuntu também passaria a adotar systemd por padrão, aceitando graciosamente a derrota, em suas próprias palavras.
Com essa mudança é muito improvável que o upstart tenha um futuro depois de sua aposentadoria nas versões estáveis do RHEL e Ubuntu LTS, a menos que alguma outra distribuição se apresente para assumir sua manutenção.
Vida longa ao systemd!

 

Nota: ao tratar do CLA exigido pela Canonical o texto anteriormente usava a expressão “transferindo o copyright” , que dá a entender que o autor original da contribuição perdia os direitos, o que não é verdade e foi corrigido.

WebKitGTK+ Debian packaging repository changes

For a while now the git repository used for packaging WebKitGTK+ has been broken. Broken as in nobody was able to clone it. In addition to that, the packaging workflow had been changing over time, from a track-upstream-git/patches applied one to a import-orig-only/patches-not-applied one.

After spending some more time trying to unbreak the repository for the third time I decided it might be a good time for a clean up. I created a new repository, imported all upstream versions for series 1.2.x (which is in squeeze), 1.6.x (unstable), and 1.7.x (experimental). I also imported packaging-related commis for those versions using git format-patch and black magic.

One of the good things about doing this move, and which should make hacking the WebKitGTK+ debian package more pleasant and accessible can be seen here:


kov@goiaba ~/s/debian-webkit> du -sh webkit/.git webkit.old/.git
27M webkit/.git
1.6G webkit.old/.git

If you care about the old repository, it’s on git.debian.org still, named old-webkit.git. Enjoy!

GNOME Shell for Debian

Over the last few days I have worked for some hours on packaging the last dependency of GNOME Shell that was missing in Debian: gjs. That work has been sponsored by Collabora, along with the work required to package GNOME Shell itself. I was very impressed by the time it took for FTP Masters and Assistants to deal with the new packages – it only took a couple days for each; kudos!

What this all means is that you can now easily test GNOME Shell, and even make it your default environment on a Debian unstable system, by just installing the ‘gnome-shell’ package. As I expected, some people have been having trouble with the new package, but the general feedback has been fairly positive. If the README.Debian package doesn’t help you with your specific issue, do take the time to file a bug report!

By the way, thanks go to Joss, for his work on dh_girepository, and for him, and Sebastian Dröge for their work on creating the new GObject Introspection policy.

Epiphany/WebKitGTK+ in Debian unstable

I have prepared an epiphany-webkit source package some time ago, and it has finally got out of NEW, thanks to the work Ganeff did this weekend on processing the queue =).

The good thing about those packages is I have patched them heavily to allow for easy parallel installation with Epiphany/Gecko, so you don’t need to give up your current browser to experiment and test Epiphany with the WebKitGTK+ backend. The gconf tree used for this package is /apps/epiphany-webkit, separate from the normal /apps/epiphany, for extra safety, but notice that your ~/.gnome2/epiphany will be shared between the Gecko and WebKit versions, even though the files used by each of them are different most of the time.

Go ahead and install the epiphany-webkit package, and have fun. Notice that if you have an already running session of Epiphany/Gecko, running epiphany-webkit will not be enough to launch Epiphany/Webkit, since Epiphany will just request that a new window be opened through D-Bus. The easiest way to test, if you just want a quick peek, is to run epiphany-webkit -p; this will run a ‘private’ instance of Epiphany/WebKit, which doesn’t touch your history, bookmarks, and passwords.

If you are feeling adventurous and want to make Epiphany/WebKit your default Epiphany you can do so using the following command, and selecting epiphany-webkit:

# update-alternatives --config epiphany-browser

Mais uma (semi-)boa notícia

Atualizado 3: eu testei o Linux Educacional versão 1.0; a instalação é a de um Debian normal, e o desktop normal é um KDE normal; o sistema conta com APT e tudo mais; por mais que eu ache a interface ruim, os menus desorganizados e as opções estranhas e complicadas, não me pareceu que os problemas que foram citados anteriormente vêm da customização do sistema, e sim da forma como ele foi instalado, nesse caso.

Pelo que li no Planet KDE hoje, escolas públicas ganharam de novo laboratórios de computadores, mas dessa vez com GNU/Linux. Uma ótima notícia, e uma ótima idéia, mas também me parece mais um caso de boas intenções com péssima qualidade técnica por trás. Citação do que foi dito pela entrevistada do post original:

about the machines: to be fair, this was not so nice… the machines are a modification of Debian linux, named Educacional Linux ( linux for education), running 2.6.18 kernel and KDE 3.5.5, the /etc/apt/sources.lst was empty, and the aptitude and apt commands removed. I don’t know why the government did that, since the hability to upgarde is good in any system. But it’s really great to see that the government is doing what they promissed: digital inclusion in every school.

Muito bacana, né? Tem toda a cara de ser uma distribuição capada, customizada de um jeito tosco e com a habilidade de ser mantida corrompida pela brilhante idéia que os criadores dela tiveram. Fazem sucesso por aqui idéias desse tipo. Parece que alguns dos desenvolvedores do KDE acharam muito bacana a notícia e estão tentando se aproximar para dar um apoio maior, e integrar novidades do KDE4. Quem sabe eles não ajudam a dar um mínimo de sanidade técnica ao projeto? Dou a maior força!

Atualizado: o Maurício apontou em um comentário que eu fui precipitado em dizer que a distribuição é customizada de um jeito tosco; como eu de fato não olhei a distribuição de perto ainda, preferi dizer somente que a informação me leva a crer que ela seja. Eu vou sinceramente adorar se alguém me provar que eu estou errado.

Atualizado 2: o projeto aparentemente não disponibiliza fontes; somente ISOs dos binários. Isso é cartão amarelo se houver algum software GPL no CD (já que tem Linux, pelo menos 1 tem =D).

Mais uma outra coisa que eu acho que merece destaque: diferentemente de outras ações de ‘computadores na escola’ que aconteceram no passado, essa iniciativa parece ser bem estruturada. Eles têm um fórum que parece bastante ativo, inclusive.

Um post prático e rápido

Eu estou no processo de escrever um post longo e chato em celebração aos meus 10 anos de Software Livre, mas enquanto ele não fica pronto, uma dica debiânica que pode ser útil!

Se você é como eu que mantém um sistema com Debian unstable e alguns pacotes da Debian experimental e está sempre chateado porque tem que ficar atualizando os pacotes na mão, e às vezes se esquece, aqui está a solução:

* instale o pacote apt-show-versions
* rode o script abaixo
* profit!

O script, versão fish:


for package in (apt-show-versions | grep /experimental | cut -d / -f 1); echo -e "Package: $package\nPin: release a=experimental\nPin-Priority: 500\n" >> /etc/apt/preferences; end

O script, versão bash:


for package in $(apt-show-versions | grep /experimental | cut -d / -f 1); do echo -e "Package: $package\nPin: release a=experimental\nPin-Priority: 500\n" >> /etc/apt/preferences; done

Nota: o script só adiciona a nova configuração ao final do arquivo de configuração; adapte para fazer o que você quer, e lembre de apagar as entradas antigas se for rodar de novo =)

O repositório experimental tem uma prioridade menor que um repositório normal, por padrão, e é por isso (e não por tratamento especial) que o APT prefere não atualizar para os pacotes que estão lá automaticamente. O que esse script faz é criar um arquivo de configuração de políticas do APT para que os pacotes que você tem instalados da experimental tenham uma prioridade igual a de um repositório comum, levando à atualização automática. Verifique com o comando apt-cache policy:

kov@abacate ~> apt-cache policy xserver-xorg-video-intel
xserver-xorg-video-intel:
  Installed: 2:2.5.1-1
  Candidate: 2:2.5.1-1
  Package pin: 2:2.5.1-1
  Version table:
 *** 2:2.5.1-1 500
          1 http://http.us.debian.org experimental/main Packages
          1 http://ftp.br.debian.org experimental/main Packages
        100 /var/lib/dpkg/status
     2:2.3.2-2+lenny5 500
        500 http://http.us.debian.org lenny/main Packages
        500 http://http.us.debian.org sid/main Packages
        500 http://ftp.br.debian.org lenny/main Packages
        500 http://ftp.br.debian.org sid/main Packages

Mozilla Corp e suas idéias sem noção…

Há algum tempo atrás a Mozilla Corp decidiu obrigar o Debian a parar de usar as brands Mozilla nos pacotes que distribui. O problema é que o Debian não quis aceitar o acordo de receber uma ‘licença’ especial para usar as marcas com a condição de que devia informar aos usuários que se modificassem o Firefox deveriam trocar o nome. O Debian normalmente não aceita tratamento especial, portanto acabou trocando o nome do Firefox pra Iceweasel.

Agora parece que a Mozilla Corp resolveu atrapalhar ainda mais as distribuições GNU/Linux. Ou elas mostram uma EULA ou tem de mudar o nome. Eu recomendo fortemente à Canonical mudar logo o nome e, como disse alguém, virar as costas pro Firefox. Ou, melhor ainda, trabalhar no Epiphany e no WebKit e esquecer a Mozilla Corp.

gksu-policykit progressing

So it is currently possible to use simple library calls in glib-based code to run something as root, by taking advantage of the gksu policykit mechanism:

GksuProcess* gksu_process_new(const gchar *working_directory, const gchar **arguments);
gboolean gksu_process_spawn_async(GksuProcess *process, GError **error);

The DBus service already works; it is able to setup the environment and X authorization correctly. There is still lots to do; startup notification is still not handled, and dealing with the application’s stdandard output and error messages, as well as providing a way for the caller to send stuff into the processe’s standard input. It is already possible to start an application and know that it has been finished, though.

As for the code:

$ git clone git://kov.eti.br/srv/git/gksu-polkit.git/

Criticism is welcome!

In other news… I’d like to ask our dear lazy web if anyone is using some nice way of providing only posts tagged in specific categories in a feed in wordpress. I’d like to use that to provide my posts to planet debian from my wordpress install.

Primeiro dia de debcamp!

Cheguei aqui… algumas coisas deram errado, outras certo, já deu pra me divertir um pouquinho e gastei um tempo preparando minha agenda pessoal. Eu fiz um arquivo ical com o que já planejei assistir, se alguém quiser acompanhar: http://people.debian.org/~kov/kov_debconf8.ical. Na porcaria bugada do Evolution você precisa criar um calendário ‘Na web’ e colocar webcal://people.debian.org/~kov/kov_debconf8.ical como endereço.

Agora é me preparar pra hackear bastante o gksu policykit durante os próximos dias! See you at debconf!