image1 image2 image3 image4 image5 image6 image7 image8 image9 image10
Data de criação:
Data de publicado:
Acessos: 350

Vira e mexe aparece esse assunto em algum grupo de discussão, seja no Facebook ou seja no Telegram.  São vários os relatos de instalação de sistemas de 32 bits em máquinas mais modestas, em geral com até 2 GB de RAM, e que ficaram mais rápidas.

Então resolvi passar um tempo fazendo a prova, inclusive da quantidade de memória.

Sistema de testes e validação

Pra validar, instalei em VMs (VirtualBox) dois sistemas Ubuntu baseados no 16.04, Xenial.  Ambos configurados como CPUs de 64 bits, 2 GB de RAM, 128 MB de vídeo com aceleração 3D e 20 GB de disco.

Pra consumir memória, deixei ambos com o navegador firefox rodando no tweetdeck, aplicativo que mostra o fluxo de mensagens do twitter.  Como o mesmo é feito em javascript, vai consumindo a memória conforme o tempo passa.  Ambos começaram com frugais 300 MB de RAM e ao terminar de escrever, depois de mais de 24 horas rodandos, ambos consumiam mais de 1.5 GB da RAM.

Não fiz testes de desempenho pelo motivo óbvio: fiz com meu laptop e ele não é exatamente um tipo de ambiente dos mais robustos pra esse tipo de coisa.  Mas pra finalidade de verificação de tamanho de binários em máquinas virtuais, serve bem.

Controle da missão.

Cada VM recebeu o nome de "UbuntuXX" onde XX é a arquitetura do software, 32 ou 64 bits.

Memória consumida

Logo de início o sistema com 32 bits mostra mais memória que realmente disponível.  Ambas as VMs com 2 GB de RAM, mas com 32 bits ele mostra um pouco mais de 2048 MB.  Bug?  Não sei.

root@ubuntu64:~# head -5 /proc/meminfo
MemTotal:        2048524 kB
MemFree:          102900 kB
MemAvailable:     859980 kB
Buffers:          132452 kB
Cached:           541576 kB
root@ubuntu32:~# head -5 /proc/meminfo 
MemTotal:        2060988 kB
MemFree:          380360 kB
MemAvailable:     507600 kB
Buffers:           58812 kB
Cached:           272512 kB

E na configuração das VMS...

helio@XPS13:VirtualBox VMs$ grep RAMSize Ubuntu\ {32,64}/Ubuntu\ {32,64}.vbox
Ubuntu 32/Ubuntu 32.vbox:      <Memory RAMSize="2048"/>
Ubuntu 32/Ubuntu 32.vbox:      <Display VRAMSize="128" accelerate3D="true"/>
Ubuntu 64/Ubuntu 64.vbox:      <Memory RAMSize="2048"/>
Ubuntu 64/Ubuntu 64.vbox:      <Display VRAMSize="128" accelerate3D="true"/>   

Uma olhada no sistema usando top.

root@ubuntu64:~# top -b -n 1 | head -5
top - 18:42:55 up  2:38,  2 users,  load average: 0,01, 0,02, 0,05
Tasks: 178 total,   1 running, 177 sleeping,   0 stopped,   0 zombie
%Cpu(s):  5,0 us,  0,8 sy,  0,1 ni, 93,8 id,  0,1 wa,  0,0 hi,  0,1 si,  0,0 st
KiB Mem :  2048524 total,    47004 free,  1157408 used,   844112 buff/cache
KiB Swap:  2095100 total,  2082632 free,    12468 used.   842436 avail Mem 
root@ubuntu32:~# top -b -n 1 | head -5
top - 18:42:45 up  2:38,  2 users,  load average: 0,00, 0,00, 0,00
Tasks: 171 total,   1 running, 170 sleeping,   0 stopped,   0 zombie
%Cpu(s):  9,3 us,  3,2 sy,  0,1 ni, 87,1 id,  0,1 wa,  0,0 hi,  0,2 si,  0,0 st
KiB Mem :  2060988 total,   256196 free,  1112400 used,   692392 buff/cache
KiB Swap:  2095100 total,  2089776 free,     5324 used.   681120 avail Mem

Como pode ser visto, o sistema de 32 bits mostra mais memória livre, 256 MB contra 47 MB, menos uso de swap, 5 MB contra 12 MB, mas tem menor memória disponível, 681 MB contra 842 MB.

Outro ponto interessante é que são 177 processos rodando em 64 bits contra 170 em 32.  E antes de perguntarem, não investiguei o motivo e não acho que realmente importe muito.  Mas percebi que por algum motivo acabei com versões de kernel diferentes.

root@ubuntu64:~# uname -a
Linux ubuntu64 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
root@ubuntu32:~# uname -a
Linux ubuntu32 4.8.0-45-generic #48~16.04.1-Ubuntu SMP Fri Mar 24 12:47:29 UTC 2017 i686 i686 i686 GNU/Linux

Isso tem importância na forma em que o kernel reserva a memória mas não usa.  Fora isso, o resto é o mesmo.

Consumo de memória com o comando top ou htop

É bastante comum a verificação de memória utilizada pelo comando top, htop ou mesmo ps.  É possívei ver uma saída mais ou menos como essa com o top.

top - 12:58:22 up 20:54,  2 users,  load average: 1,08, 0,43, 0,19
Tasks: 184 total,   1 running, 183 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3,5 us,  0,5 sy,  0,1 ni, 95,6 id,  0,1 wa,  0,0 hi,  0,1 si,  0,0 st
KiB Mem :  2048524 total,   106008 free,  1134092 used,   808424 buff/cache
KiB Swap:  2095100 total,  2017780 free,    77320 used.   860776 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 1241 helio     20   0 1254076 160784  10380 S 50,0  7,8  30:33.19 compiz
  767 root      20   0  480156  88992   8388 S 25,0  4,3  15:18.11 Xorg
 2272 helio     20   0 1539028 451060  50504 S  6,2 22,0  42:32.37 firefox
    1 root      20   0  185720   5708   3340 S  0,0  0,3   0:03.14 systemd
    2 root      20   0       0      0      0 S  0,0  0,0   0:00.00 kthreadd
    3 root      20   0       0      0      0 S  0,0  0,0   0:01.38 ksoftirqd/0
    5 root       0 -20       0      0      0 S  0,0  0,0   0:00.00 kworker/0:0H
    7 root      20   0       0      0      0 S  0,0  0,0   0:01.65 rcu_sched
    8 root      20   0       0      0      0 S  0,0  0,0   0:00.00 rcu_bh
    9 root      rt   0       0      0      0 S  0,0  0,0   0:00.00 migration/0
   10 root      rt   0       0      0      0 S  0,0  0,0   0:00.38 watchdog/0
   11 root      20   0       0      0      0 S  0,0  0,0   0:00.00 kdevtmpfs

O comando top mostra o consumo de memória em VIRT, RES e SHR.  É possível ver o firefox consumindo 1.54 GB de memória VIRT, 451 MB de memória RES e 50 MB de memória SHR.  Mas o que são?

Atualmente é muito difícil um programa tão grande quanto firefox ter todas as bibliotecas incluídas em seu binário.  Esse formato é chamado estático se usado.  Isso faria com que o executável ficasse gigantesco.  Fora isso, cada executável traria dentro de si a mesma biblioteca com os mesmos conteúdos.  E a cada atualização dessas bibliotecas, seria necessário alterar o executável também.

Pra melhorar a eficiência, binários criados no formato ELF, Executable and Linkable Format, tem uma parte do cabeçalho que informa onde buscar essas bibliotecas de funções, que são os arquivos .so.  São chamadas as bibliotecas dinâmicas, que podem ser atualizadas com o executável rodando.   Quando um binário ELF é executado, o kernel carrega seu código na memória e de suas bibliotecas de funções.  Se outro binário que aponta pra mesma biblioteca é executado, o kernel não carrega novamente a biblioteca, mas aponta pro endereçamento de memória onde essa já existe.

Então a memória VIRT, de virtual, mostra o total que um binário carregou na memória, inclusive com as bibliotecas dinâmicas que são compartilhadas.  Esse tamanho então não é exatamente o que aquele programa sozinho carrega.

A memória RES mostra o quanto de memória está na RAM e não no SWAP.  Mas ela mostra o total, incluindo das bibliotecas dinâmicas que são compartilhadas com outros programas.

A memória SHR é da compartilhada, de quanto de memória é compartilhado com bibliotecas dinâmicas.

O resultado é que pra saber o quanto um programa está consumindo por si só, seria algo como VIRT menos a SHR.  Dai seria possível ver quanto o executável ocupa de memória, mais os stack de dados.  Só que fica a pergunta: e a parte compartilhada?  Não conta?

Conta!  É memória consumida.  É RAM que não pode usar.  Mas como fazer isso?  Se o firefox e o unity, como exemplo, compartilharem uma biblioteca de renderização 3D, então a gente diz que cada um consumiu metade dessa memória alocada?  E se tiver mais um terceiro, ou quarto ou muito mais programas compartilhando essa mesma biblioteca?  A resposta é tão complicada que é esse o motivo que o programa top não tenta resolver isso e mostra o total alocado, mesmo sabendo que boa parte daquilo é compartilhado.

Algumas formas de ver o quanto cada programa ocupa em stack de memória sem as bibliotecas compartilhadas são os comandos pmap e readelf, que serão usados mais adiante.

Uso de memória do firefox

Vamos começar pelo tamanho dos binários.  O binário de 32 bits é muito menor que o de 64 bits?

root@ubuntu64:~# ls -l /usr/lib/firefox/firefox
-rwxr-xr-x 1 root root 125152 mar 29 18:25 /usr/lib/firefox/firefox
root@ubuntu32:~# ls -l /usr/lib/firefox/firefox
-rwxr-xr-x 1 root root 136664 mar 29 18:50 /usr/lib/firefox/firefox

E já de cara as coisas começam a ficar mais interessantes.  O binário do firefox em 32 bits é maior que o de 64 bits.  Usando o comando readelf -S é possível olhar o conteúdo de ambos e quanto de memória ocupa cada parte.  Mas vou evitar colocar aqui o resultado inteiro pois é muito longo e não será fácil visualizar as diferenças.  Então mostro apenas as partes diferentes de ambos.  Os valores estão em hexadecimal.

  32 bits 64 bits
.gnu.hash 04d4 04c4
.dynsym 0ea0 1578
.dynstr 184f 17c8
.gnu.version 01d4 01ca
.gnu.version_r 01a0 0160
.rel.dyn 0468 0cd8
init 0023 001a
.plt.got 02b0 02a0
.text 013b34 0123ff

Não completei a tablet toda, mas já dá pra perceber que os valores em 64 bits são menores em geral.  Antes de uma pergunta sobre o motivo, isso eu não sei.  Talvez algo em relação com compilador.

E quanto estão ocupando de memória rodando?  Isso fica fácil verificar com o comando pmap.

root@ubuntu64:~# pmap  2272  | grep total
  total          1548796K
root@ubuntu32:~# pmap 2334 | grep total
 total   959916K

E o firefox ocupa 1.55 GB de RAM em 64 bits contra 956 MB em 32.  Alguns já começam a se exaltar e gritar "viu! eu falei!" mas... e sempre tem um mas... em 32 bits, não sei a razão disso, o firefox usa um plugin-container junto.  Ao matar esse plugin-container...

então ele tem de contar com o consumo de memória do firefox como um todo.  Sendo assim.

root@ubuntu32:~# ps auxwww | grep -i firefox
helio     2334  1.3 11.5 959920 238924 ?       Sl   apr01  17:44 /usr/lib/firefox/firefox
helio     2490  3.6 19.6 1102860 404644 ?      Sl   apr01  47:30 /usr/lib/firefox/plugin-container -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 2334 true tab
root      9461  0.0  0.0   6644   840 pts/4    S+   13:42   0:00 grep --color=auto -i firefox
root@ubuntu32:~# pmap 2334 | grep total
 total   959916K
root@ubuntu32:~# pmap 2490 | grep total
 total   996360K

O total de uso de memória em 32 bits é na verdade 1956276K, 1.96 GB de RAM.

O consumo de memória é mais otimizado em 64 bits.  O esperado resultado de 32 bits ocupar menos memória não passa de uma lenda urbana.

Fazendo nossos próprios binários

Mas podemos fazer algo mais interessante e olhar à fundo as difrenças de 32 bits e 64 bits em arquiteturas de 64 bits.  Pra isso eu criei um pequeno programa em C que basicamente cria uma string com meu nome e copia pra outra variável.  E fica fazendo isso.  O motivo é apenas fazer análise de uso de memória com readelf e pmap.

testing.c

#include
#include
#include

char nome[] = "Helio Loureiro";

int main() {
    char tmp[sizeof(nome)];
    while(1) {
        sleep(30);
        strcpy(tmp, nome);
   }
}

Compilando e verificando os tamanhos dos binários.

root@ubuntu64:~# vi testing.c
root@ubuntu64:~# gcc -o testing testing.c
root@ubuntu64:~# ls -l testing
-rwxr-xr-x 1 root root 8696 apr  1 18:22 testing
root@ubuntu32:~# vi testing.c
root@ubuntu32:~# gcc -o testing testing.c
root@ubuntu32:~# ls -l testing
-rwxr-xr-x 1 root root 7424 apr  1 18:22 testing

Nesse caso bem simples, com nenhuma biblioteca dinâmica em uso além da própria GNU libc, o executável em 32 bits ficou menor.  Não metade do tamanho, mas 14% menor.  E rodando?

root@ubuntu64:~# ./testing &
[1] 19892
root@ubuntu64:~# pmap -x 19892
19892:   ./testing
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000       4       4       0 r-x-- testing
0000000000400000       0       0       0 r-x-- testing
0000000000600000       4       4       4 r---- testing
0000000000600000       0       0       0 r---- testing
0000000000601000       4       4       4 rw--- testing
0000000000601000       0       0       0 rw--- testing
00007f21a0044000    1788     816       0 r-x-- libc-2.23.so
00007f21a0044000       0       0       0 r-x-- libc-2.23.so
00007f21a0203000    2048       0       0 ----- libc-2.23.so
00007f21a0203000       0       0       0 ----- libc-2.23.so
00007f21a0403000      16      16      16 r---- libc-2.23.so
00007f21a0403000       0       0       0 r---- libc-2.23.so
00007f21a0407000       8       8       8 rw--- libc-2.23.so
00007f21a0407000       0       0       0 rw--- libc-2.23.so
00007f21a0409000      16       8       8 rw---   [ anon ]
00007f21a0409000       0       0       0 rw---   [ anon ]
00007f21a040d000     152     140       0 r-x-- ld-2.23.so
00007f21a040d000       0       0       0 r-x-- ld-2.23.so
00007f21a0615000      12      12      12 rw---   [ anon ]
00007f21a0615000       0       0       0 rw---   [ anon ]
00007f21a0630000       8       8       8 rw---   [ anon ]
00007f21a0630000       0       0       0 rw---   [ anon ]
00007f21a0632000       4       4       4 r---- ld-2.23.so
00007f21a0632000       0       0       0 r---- ld-2.23.so
00007f21a0633000       4       4       4 rw--- ld-2.23.so
00007f21a0633000       0       0       0 rw--- ld-2.23.so
00007f21a0634000       4       4       4 rw---   [ anon ]
00007f21a0634000       0       0       0 rw---   [ anon ]
00007ffd44054000     132      12      12 rw---   [ stack ]
00007ffd44054000       0       0       0 rw---   [ stack ]
00007ffd440e3000       8       0       0 r----   [ anon ]
00007ffd440e3000       0       0       0 r----   [ anon ]
00007ffd440e5000       8       4       0 r-x--   [ anon ]
00007ffd440e5000       0       0       0 r-x--   [ anon ]
ffffffffff600000       4       0       0 r-x--   [ anon ]
ffffffffff600000       0       0       0 r-x--   [ anon ]
---------------- ------- ------- ------- 
total kB            4224    1048      84
root@ubuntu32:~# ./testing &
[1] 9589
root@ubuntu32:~# pmap -x 9589
9589:   ./testing
Address   Kbytes     RSS   Dirty Mode  Mapping
08048000       4       4       0 r-x-- testing
08048000       0       0       0 r-x-- testing
08049000       4       4       4 r---- testing
08049000       0       0       0 r---- testing
0804a000       4       4       4 rw--- testing
0804a000       0       0       0 rw--- testing
b75d7000    1724     732       0 r-x-- libc-2.23.so
b75d7000       0       0       0 r-x-- libc-2.23.so
b7786000       4       0       0 ----- libc-2.23.so
b7786000       0       0       0 ----- libc-2.23.so
b7787000       8       8       8 r---- libc-2.23.so
b7787000       0       0       0 r---- libc-2.23.so
b7789000       4       4       4 rw--- libc-2.23.so
b7789000       0       0       0 rw--- libc-2.23.so
b778a000      12       8       8 rw---   [ anon ]
b778a000       0       0       0 rw---   [ anon ]
b77a5000       8       8       8 rw---   [ anon ]
b77a5000       0       0       0 rw---   [ anon ]
b77a7000       8       0       0 r----   [ anon ]
b77a7000       0       0       0 r----   [ anon ]
b77a9000       8       4       0 r-x--   [ anon ]
b77a9000       0       0       0 r-x--   [ anon ]
b77ab000     136     136       0 r-x-- ld-2.23.so
b77ab000       0       0       0 r-x-- ld-2.23.so
b77cd000       4       4       4 rw---   [ anon ]
b77cd000       0       0       0 rw---   [ anon ]
b77ce000       4       4       4 r---- ld-2.23.so
b77ce000       0       0       0 r---- ld-2.23.so
b77cf000       4       4       4 rw--- ld-2.23.so
b77cf000       0       0       0 rw--- ld-2.23.so
bfe72000     132       8       8 rw---   [ stack ]
bfe72000       0       0       0 rw---   [ stack ]
-------- ------- ------- ------- 
total kB    2068     932      56

É possível ver que em 64 bits o programa ocupa o dobro de memória em RAM que 32 bits.  São 4224 KB contra 2068 KB.  E é possível ver que é causado pela libc em 64 bits.  Essa memória é totalmente usada pelo programa?  Não uma vez que a libc é compartilhada.  Mas em 64 bits ela faz duas chamadas para si.  O restante, como stack, os valores são exatamente os mesmos.

Olhando com readelf pra investigar o tamanho de cada parte do binário.

root@ubuntu64:~# readelf -S -W testing
There are 31 section headers, starting at offset 0x1a40:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000400238 000238 00001c 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            0000000000400254 000254 000020 00   A  0   0  4
  [ 3] .note.gnu.build-id NOTE            0000000000400274 000274 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        0000000000400298 000298 00001c 00   A  5   0  8
  [ 5] .dynsym           DYNSYM          00000000004002b8 0002b8 000078 18   A  6   1  8
  [ 6] .dynstr           STRTAB          0000000000400330 000330 000045 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          0000000000400376 000376 00000a 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         0000000000400380 000380 000020 00   A  6   1  8
  [ 9] .rela.dyn         RELA            00000000004003a0 0003a0 000018 18   A  5   0  8
  [10] .rela.plt         RELA            00000000004003b8 0003b8 000048 18  AI  5  24  8
  [11] .init             PROGBITS        0000000000400400 000400 00001a 00  AX  0   0  4
  [12] .plt              PROGBITS        0000000000400420 000420 000040 10  AX  0   0 16
  [13] .plt.got          PROGBITS        0000000000400460 000460 000008 00  AX  0   0  8
  [14] .text             PROGBITS        0000000000400470 000470 0001a2 00  AX  0   0 16
  [15] .fini             PROGBITS        0000000000400614 000614 000009 00  AX  0   0  4
  [16] .rodata           PROGBITS        0000000000400620 000620 000004 04  AM  0   0  4
  [17] .eh_frame_hdr     PROGBITS        0000000000400624 000624 000034 00   A  0   0  4
  [18] .eh_frame         PROGBITS        0000000000400658 000658 0000f4 00   A  0   0  8
  [19] .init_array       INIT_ARRAY      0000000000600e10 000e10 000008 00  WA  0   0  8
  [20] .fini_array       FINI_ARRAY      0000000000600e18 000e18 000008 00  WA  0   0  8
  [21] .jcr              PROGBITS        0000000000600e20 000e20 000008 00  WA  0   0  8
  [22] .dynamic          DYNAMIC         0000000000600e28 000e28 0001d0 10  WA  6   0  8
  [23] .got              PROGBITS        0000000000600ff8 000ff8 000008 08  WA  0   0  8
  [24] .got.plt          PROGBITS        0000000000601000 001000 000030 08  WA  0   0  8
  [25] .data             PROGBITS        0000000000601030 001030 00001f 00  WA  0   0  8
  [26] .bss              NOBITS          000000000060104f 00104f 000001 00  WA  0   0  1
  [27] .comment          PROGBITS        0000000000000000 00104f 000034 01  MS  0   0  1
  [28] .shstrtab         STRTAB          0000000000000000 001930 00010c 00      0   0  1
  [29] .symtab           SYMTAB          0000000000000000 001088 000678 18     30  47  8
  [30] .strtab           STRTAB          0000000000000000 001700 000230 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
root@ubuntu32:~# readelf -S testing
There are 31 section headers, starting at offset 0x1828:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        08048154 000154 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048168 000168 000020 00   A  0   0  4
  [ 3] .note.gnu.build-i NOTE            08048188 000188 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        080481ac 0001ac 000020 04   A  5   0  4
  [ 5] .dynsym           DYNSYM          080481cc 0001cc 000060 10   A  6   1  4
  [ 6] .dynstr           STRTAB          0804822c 00022c 000052 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          0804827e 00027e 00000c 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         0804828c 00028c 000020 00   A  6   1  4
  [ 9] .rel.dyn          REL             080482ac 0002ac 000008 08   A  5   0  4
  [10] .rel.plt          REL             080482b4 0002b4 000018 08  AI  5  24  4
  [11] .init             PROGBITS        080482cc 0002cc 000023 00  AX  0   0  4
  [12] .plt              PROGBITS        080482f0 0002f0 000040 04  AX  0   0 16
  [13] .plt.got          PROGBITS        08048330 000330 000008 00  AX  0   0  8
  [14] .text             PROGBITS        08048340 000340 0001a2 00  AX  0   0 16
  [15] .fini             PROGBITS        080484e4 0004e4 000014 00  AX  0   0  4
  [16] .rodata           PROGBITS        080484f8 0004f8 000008 00   A  0   0  4
  [17] .eh_frame_hdr     PROGBITS        08048500 000500 00002c 00   A  0   0  4
  [18] .eh_frame         PROGBITS        0804852c 00052c 0000c4 00   A  0   0  4
  [19] .init_array       INIT_ARRAY      08049f08 000f08 000004 00  WA  0   0  4
  [20] .fini_array       FINI_ARRAY      08049f0c 000f0c 000004 00  WA  0   0  4
  [21] .jcr              PROGBITS        08049f10 000f10 000004 00  WA  0   0  4
  [22] .dynamic          DYNAMIC         08049f14 000f14 0000e8 08  WA  6   0  4
  [23] .got              PROGBITS        08049ffc 000ffc 000004 04  WA  0   0  4
  [24] .got.plt          PROGBITS        0804a000 001000 000018 04  WA  0   0  4
  [25] .data             PROGBITS        0804a018 001018 000017 00  WA  0   0  4
  [26] .bss              NOBITS          0804a02f 00102f 000001 00  WA  0   0  1
  [27] .comment          PROGBITS        00000000 00102f 000034 01  MS  0   0  1
  [28] .shstrtab         STRTAB          00000000 00171b 00010a 00      0   0  1
  [29] .symtab           SYMTAB          00000000 001064 000470 10     30  47  4
  [30] .strtab           STRTAB          00000000 0014d4 000247 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Pra facilitar a análise, crie uma tabela com os valores em hexadecimal, em decimal e os valores de 64 bits menos os valores de 32 bits.  Se 64 bits tiver valores maiores, o resultado é positivo.  Do contrário, negativo.  Isso mostra que a quantidade bytes alocados é maior ou menor em cada caso.

 

Name Type Size 64 bits (hexa) Size 32 bits (hexa) 64 bits (dec) 32 bits (dec) Bigger?
NULL 0 0 0 0 0 0
.interp PROGBITS 00001c 154 28 340 -312
.note.ABI-tag NOTE 20 168 32 360 -328
.note.gnu.build-id NOTE 24 188 36 392 -356
.gnu.hash GNU_HASH 00001c 0001ac 28 428 -400
.dynsym DYNSYM 78 0001cc 120 460 -340
.dynstr STRTAB 45 00022c 69 556 -487
.gnu.version VERSYM 00000a 00027e 10 638 -628
.gnu.version_r VERNEED 20 00028c 32 652 -620
.rela.dyn RELA 18 0002ac 24 684 -660
.rela.plt RELA 48 0002b4 72 692 -620
.init PROGBITS 00001a 0002cc 26 716 -690
.plt PROGBITS 40 0002f0 64 752 -688
.plt.got PROGBITS 8 330 8 816 -808
.text PROGBITS 0001a2 340 418 832 -414
.fini PROGBITS 9 4,00E+04 9 262144 -262135
.rodata PROGBITS 4 0004f8 4 1272 -1268
.eh_frame_hdr PROGBITS 34 500 52 1280 -1228
.eh_frame PROGBITS 0000f4 00052c 244 1324 -1080
.init_array INIT_ARRAY 8 000f08 8 3848 -3840
.fini_array FINI_ARRAY 8 000f0c 8 3852 -3844
.jcr PROGBITS 8 000f10 8 3856 -3848
.dynamic DYNAMIC 0001d0 000f14 464 3860 -3396
.got PROGBITS 8 000ffc 8 4092 -4084
.got.plt PROGBITS 30 1000 48 4096 -4048
.data PROGBITS 00001f 1018 31 4120 -4089
.bss NOBITS 1 00102f 1 4143 -4142
.comment PROGBITS 34 00102f 52 4143 -4091
.shstrtab STRTAB 00010c 00171b 268 5915 -5647
.symtab SYMTAB 678 1064 1656 4196 -2540
.strtab STRTAB 230 0014d4 560 5332 -4772

Como pode ser visto na tabela, em todas as partes de cabeçalho ELF do executável, 64 bits é menor.  O resultado é um binário com mais espaço na memória por alguma diferença na GNU libc, que não necessariamente significa que seu programa está ocupando mais memória em 64 bits.  Pelo contrário.  O stack pra dados alocados em geral é o mesmo que em 32 bits, mas o binário criado é mais eficiente com menor uso.

Espero com isso ter mostrado que 32 bits em arquitetura de 64 não traz um benefício real em dados.  O motivo de pessoas dizerem que ficou mais rápido?  Pode ser o resultado de algum outro problema de HD ou coisa do tipo, mas não pela arquitetura da CPU rodar melhor 32 bits em 64 bits, como alguns acham que é.  No fim essa discussão de melhor ou pior fica num campo de sensações.  Então é complicado argumentar contra alguém que acha que ficou mais rápido.

Minha sugestão final: se tem uma CPU que suporta 64 bits, use 64 bits.

Data de criação:
Data de publicado:
Acessos: 861

E começou 2017.  Pra celebrar o ano novo, resolvi entrar com tudo no Ubuntu 16.04, Xenial.

Ubuntu 16.04

Apesar de ser 2017 e o Ubuntu 16.04 ter sido lançado em abril de 2016, a versão que uso é corporativa, o que significa homologada pela empresa.  Então leva um tempo até estar certificado pra uso (o que significam várias adaptações na Intranet também).  O anúncio de sua disponibilidade foi quase no fim de dezembro de 2016 e fiquei feliz de começar 2017 já com um sistema novo.

Eu tinha já atualizado meu desktop pro 16.04, mas eu praticamente nunca o uso.  Está lá o steam instalado, mas eu dificilmente ligo.  Quem me adicionou pra jogar saber disso (spoiler: eu também jogo mal pra caramba).

Mas a instalação no meu laptop seria um passo muito maior, com uso diário e desenfreado do sistema, puxando ao limite.

Uptime 241 days

Nem preciso dizer que até rolou uma lágrima quando rebootei meu Ubuntu 14.04 com 241 dias de uptime pra fazer upgrade.  Foram quase 8 meses de longevidade.  Mas eu precisava desse upgrade.  Um sistema de 2014 estava pra lá de desatualizado.

A instalação foi tranquila e terminou depois de aproximadamente meia hora.  Mesmo sendo um laptop com SSD, o que demorou mesmo foi a recuperação dos dados do meu /home.  E sim, foi preciso reinstalar.  Recomendação da Canonical.

Mas como alguém forjado no fogo do Unix através de décadas, certeza que fiz backup.  Inclusive perdi um certo tempo salvando meus containers preciosos de docker. E... esqueci de fazer backup do diretório onde salvei os containers.  Mas meu /home foi recuperado. .oO(nota mental: salvar os containers num diretório que eu realmente faça backup)

O Ubuntu 16.04 já sai pedido atualizações pra virar 16.04.1.  Sinal do tempo que levou pra ser homologado.  O kernel padrão é o 4.4.x, então não perdi tempo e, enquanto sincronizava o /home, já fui dando git clone no repositório do kernel.  Tentei o kernel 4.9 mas encontrei problemas no suspend e na parte gráfica.  Tentei o 4.10-rcx e também encontrei instabilidade.  Voltei pro 4.7.x.  Fiquei com ele até ontem, quando problemas na placa gráfica da Intel começaram a aparecer (os videos, como efeito colateral, ficavam sempre atrasados em relação ao som).  Então compilei o 4.9.5 que teve release faz 2 dias.  E aparentemente está tudo funcionando melhor.

Linux elxaf7qtt32 4.9.5-helio #7 SMP PREEMPT Sat Jan 21 23:35:49 CET 2017 x86_64 x86_64 x86_64 GNU/Linux

Mesmo rodando systemd, minha decepção ficou por conta do KDE5.  Vários coredumps, travadas em geral, mudança na proteção de tela, que agora é uma insossa tela estática com imagem ao invés de xscreensaver, mundança na UI de configuração e, o que foi o pior, mudança na API de systray do Xprotocol.  Isso significou que programas como pidgin e keepassx simplesmente não voltam mais se são minimizados.  A coisa desandou tanto que tive de sair do KDE5.  Experimentei alguns outros WMs e no fim terminei com o mate.  Não sou fã do Gnome, mas o mate deve servir até eu recompilar o KDE4 inteiro pro Xenial.  Essa é a solução que vi no momento.  Eu estava tão excitado com plasma... decepção... decepção...

Mas fora o KDE5, o sistema roda redondo.  Já gravei 2 webcasts esse ano no Unix Load On e o gerenciamento de dispositivos funcionou lindamente (pavucontrol na veia).  Também já fiz um vídeo com o Kdenlive que se mostrou melhor e até mais rápido que a versão que usava no 14.04.

No geral estou feliz com a versão mais nova do Ubuntu, mas triste em ver que o KDE permitiu um release tão podre da sua versão 5.  E antes que mencionem ser uma versão mais velha e com muitos bugs, eu sincronizei com o ppa do kubuntu pra pegar os releases e updates mais recentes.  Alguns bugs resolvidos mas... coredump em quase tudo.

E vamos ver se chego novamente nos 241 dias de uptime.  Só faltam 240 dias e 6 horas pra chegar lá.

200 dias

Autor:
Data de criação:
Data de publicado:
Acessos: 1354

Faz anos que escrevi sobre um uptime de 100 dias, em guerra dos 100 dias, e agora finalmente bati esse uptime.

No momento o uptime é um pouco maior:

17:42:23 up 212 days,  3:29, 31 users,  load average: 1.54, 1.25, 1.27

mas já vale pra ilustrar o quanto o Linux evoluiu em estabilidade.  Não só ele, mas toda a distro, que no meu caso é Ubuntu.

Anteriormente a maioria de problemas que exigiam o desligamento eram sempre relacionados com driver de vídeo Intel (na época do uptime de 100 dias).  Recentemente eu experimentei alguns congelamentos por falta de memória e até mesmo alguns crashes ao mudar de monitor (altero com bastante frequência entre só a tela do laptop, laptop e um monitor, e laptop e projetor).  Também tive problemas com entrada e saída de áudio com pulseaudio.

Por esse motivo eu sempre tentei compilar uma kernel mais recente e experimentar.  No caso estou 4.5.4.  Nem era dos mais estáveis e ainda está com bug de segurança pra acesso local, como o Dirty COW.  Uma vez que a invasão exige acesso local, estou relativamente seguro (se acessarem meu laptop, provavelmente será mais pelo valor do equipamento que pelos dados).

Mas uso diariamente meu laptop e de forma bastante extensiva.  Uso com docker, compilação de programas em C e C++, VMs com virtualbox e libvirt, edição de vídeo e de fotografia, etc.  É o famoso "pau pra toda obra".  E sem demais problemas.

Encontrei alguns?  Com certeza.  Tive alguns crashes do Xorg.  Mas como tenho habilitado o <ctr>+<alt>+<backspace> pra fechar o X inteiro e forçar um restart, não perdi nada além alguns segundos.

Fico feliz em usar Linux de uma maneira tão útil e que permite ser produtivo, tendo meu desktop pronto somente abrindo a tampa.

E por falar de desktop, fiz recentemente um vídeo pra mostrar o porquê de eu usar KDE, que adoro.

E agora tentar chegar em 365 dias.  Ou mais.

 

Data de criação:
Data de publicado:
Acessos: 3499

O Debian Jessie, última versão estável do sistema operacional universal Debian, foi lançado a quase 1 ano.  Somente agora criei coragem de fazer o upgrade.  Estava rodando Wheezy, a versão anterior que entrou em LTS (Long Term Support ou suporte estendido), que atendia bem o site mas, sempre existe um mas, descobri alguns problemas de limitação do kernel com o greyd.

Alguns sites não estavam sendo marcados corretamente com ipset.  Como o greyd foi criado pra versões mais recentes de kernel (Wheezy rodava com um linux-3.2), a opção era desativar o greyd ou atualizar o sistema.  Então vamos atualizar!

Sem ajuda dos trus La_Sombra e Rootsh nada disso seria possível.  Foi um trabalho de garimpo no passado pra achar como conectar na VM e quem ainda tinha a chave de conexão.  Culpa disso pela estabilidade do sistema.  Obrigado Debian!

Eu já tinha feito o upgrade do Ubuntu LTS, de 14.04 pro 16.04, e esperava alguns problemas que seriam corrigidos com reboot e uns "apt-get -f install", então o acesso ao console era essencial.  Parte dessa espectativa era também o motivo pra ter postergado esse upgrade.  systemd é algo que ainda me dói no alma.

Pra fazer o upgrade?  Do bom e velho jeito do Debian: primeiramente deixando atualizado na versão corrente, Wheezy

# cd /etc/apt
# apt-get update && apt-get upgrade

Em seguida mover a versão pra Jessie e continuar com upgrade.

# cp sources.list sources.list.wheezy
# cat sources.list.wheezy | sed "s/wheezy/jessie/" > sources.list
# apt-get update
# apt-get dist-upgrade

Pronto.  É isso.  Fácil assim.  

Foram uns 500 MB de download, uma vez que é um servidor e roda só o necessário, um reboot e... saiu funcionando de primeira!  Eu achando que o systemd ia encrencar com alguma coisa e... nada!  Claro que nem tudo foi tão bem assim.  Precisei arrumar algumas configurações do servidor web, assim como do mail, mas muita coisa saiu funcionando sem mexer.  Ainda estou com problemas com o dovecot, mas nada que force uma volta ao Wheezy pra corrigir.

Parabéns à equipe do Debian por um sistema tão afinado e redondo assim.  Continua sendo minha distro preferida.

Data de criação:
Data de publicado:
Acessos: 3888

SPAM é uma batalha sem fim. Cria-se uma forma de mitigar ou diminuir e são apenas algumas semanas de sossego.  Logo eles acham uma forma de burlar as barreiras que criamos.  Como faz tempo que não trabalho com mail de larga escala e controlo apenas a da VM do servidor desse domínio aqui, eu não tenho nem idéia do tamanho do problema que grandes empresas como Google têm.  A quantidade de SPAM que tenho de lidar já é mais que suficiente pra eu me aborrecer.

Eu já implementei SPF pra verificação de origem dos mails, mailassassin, white e black list e... o volume continua alto.

Mailassassin era um dos mais promissores mas consome muita CPU a cada verificação.  Além disso ele é um software muito burro (desculpem ao autores e fãs) pois ele recebe o mail pra fazer análise.  Porque não fazer logo na conexão alguma verificação e descartar logo?  No fim gastou banda, CPU e memória pra ver algo óbvio.  Quando recebo um mail vindo de algo como "helio-a414c-loureiro.eng.Este endereço de email está sendo protegido de spambots. Você precisa do JavaScript ativado para vê-lo. é bastante claro que é falso e se destina à SPAM.  Então não seria lógico já matar o mail no momento do recebimento?

Pois o projeto OpenBSD resolveu cuidar disso.  Eles criaram um daemon que enferniza a vida de spammers.  É um verdadeiro saci pererê dos e-mails.  O spamd recebe o mail e funciona de uma forma muuuuuuito lenta, com a conexão bem degradada.  Após terminar a tentativa de envio do mail, ele simplesmente fecha a conexão e pede que tente novamente.  Se o servidor tentar novamente, muito provavelmente não é uma máquina de SPAM.  Como essa tentativa seguida faz parte do protocolo SMTP, servidores legítimos continuaram tentando enquanto spammers vão pra outra pobre vítima.

No último hackathon que participei eu tentei fazer um port desse daemon pro Linux.  Encontrei um port já em andamento chamado obspamd no github, que estava com o build quebrado, e consegui arrumar o que estava com problemas.  Minha idéia era fazer um daemon funcional e completo portado pra Linux, com autoconf e configure.  E foi num dos bug reports que eu estava respondendo que alguém mandou outra mensagem avisando que existia um port já bem funcional do mesmo, o greyd.

Conhecendo o greyd

Fiquei surpreso ao descobrir que até site oficial já tinha, o http://greyd.org, pois eu nunca tinha ouvido falar.  Até onde vi não existem pacotes para ele em Debian ou em Ubuntu.  Então boa parte da instalação foi feita manualmente.

O que eu gostaria de fazer com o obspamd, de criar um sistema de build com autoconfigure, já está pronto no greyd.  Além disso ele já implementa as chamadas de kernel pra adicionar as regras de firewall necessárias pro funcionamento do greyd.  

Por quê do firewall?  Tanto o original, spamd, quanto o greyd funcionam ouvindo na porta 8025.  Então todo pacote que não foi classificado, baseado em IP de origem, ao tentar conectar na porta 25, padrão de mail, é redirecionado à porta 8025.  O greyd segue com a conexão e marca esse tipo de pacote como provável whitelist (lista branca).  Na segunda tentativa de conexão esse pacote já vai direto pro servidor de mail, que no meu caso é um postfix.  Esse controle é feito através do firewall iptables com regras no PREROUTING e ipset do kernel, marcando tipos de pacote com IP de origem.  E precisa do módulo conntrack do kernel.

Baixando e compilando o greyd

Como é um programa bem recente, não existem pacotes pra ele.  Ao menos em Debian/Ubuntu.  Então ele ainda exige a compilação e instalação manual.

Para baixar o greyd diretamente do github:

# git clone https://github.com/mikey-austin/greyd.git

Pra compilação, eu escolhi usar sqlite3 como formato de arquivo de whitelist, então precisei incluir os cabeçalhos e bibliotecas referentes.

# apt-get install libsqlite3-dev libnetfilter-log-dev libnetfilter-conntrack-dev \
libpcap0.8 libspf2-dev # cd greyd # autoreconf -vi # ./configure \ --with-sqlite \ --with-netfilter \ --with-spf \ --bindir=/usr/bin \ --sbindir=/usr/sbin \ --sysconfdir=/etc \ --docdir=/usr/share \ --libdir=/usr/lib \ --localstatedir=/var \ GREYD_PIDFILE=/var/run/greyd.pid \ GREYLOGD_PIDFILE=/var/run/greylogd.pid \ DEFAULT_CONFIG=/etc/default/greyd.conf # make

O greyd também precisa que sejam criados 2 usuários: greyd e greydb, que controlam daemon e base de dados da lista.  No seu repositório existe um diretório que ajuda a criar pacotes.  Nele é possível ver os comandos pra realizar essa tarefa manualmente em greyd/packages/debian/postinst:

# adduser --quiet --system --home /var/run/greyd --group \
    --uid 601 --gecos "greyd"  --shell /bin/false --disabled-login greyd
# adduser --quiet --system --home /var/lib/greyd --group 
    --uid 602 --gecos "greydb" --shell /bin/false --disabled-login greydb

Em seguida é preciso criar o diretório onde a base de dados em squlite3 ou bsddb será escrita.

# mkdir -p /var/greydb
# chown -R greydb:greydb /var/greydb

Com a configuração de compilação, as configuração serão armazenadas em /etc/default/greyd.conf.  O spamd do OpenBSD por padrão roda em um ambiente chroot() pra proteção do sistema.  Eu não consegui fazer o mesmo com o greyd.  As configurações que estou usando no momento são (usando diff pra comparar):

# diff -u ./etc/greyd.conf /etc/default/greyd.conf 
--- ./etc/greyd.conf    2016-07-07 13:47:43.000000000 -0300
+++ /etc/default/greyd.conf     2016-07-08 09:49:28.000000000 -0300
@@ -5,8 +5,8 @@
 #
 # Debugging options and more verbose logs.
 #
-debug = 0
-verbose = 0
+debug = 1
+verbose = 1
 daemonize = 1
 
 #
@@ -17,7 +17,7 @@
 #
 # Address to listen on.
 #
-bind_address = "127.0.0.1"
+bind_address = "200.123.234.321"
 
 #
 # Main greyd port.
@@ -32,7 +32,7 @@
 #
 # Enable listening on IPv6 socket.
 #
-enable_ipv6 = 0
+enable_ipv6 = 1
 bind_address_ipv6 = "::1"
 
 #
@@ -60,7 +60,7 @@
 #
 # Chroot enable & location for main daemon.
 #
-chroot     = 1
+chroot     = 0
 chroot_dir = "/var/empty/greyd"
 
 #
@@ -82,11 +82,13 @@
 # Specify the maximum number of connections.
 #
 # max_cons = 800
+max_cons = 30
 
 #
 # Specify the maximum number of blacklisted connections to tarpit.
 #
 # max_cons_black = 800
+max_cons_black = 30
 
 #
 # The firewall configuration.
@@ -114,8 +116,8 @@
 #
 section database {
     #driver  = "/usr/lib/greyd/greyd_bdb_sql.so"
-    #driver  = "/usr/lib/greyd/greyd_sqlite.so"
-    driver  = "/usr/lib/greyd/greyd_bdb.so"
+    driver  = "/usr/lib/greyd/greyd_sqlite.so"
+    #driver  = "/usr/lib/greyd/greyd_bdb.so"
     path    = "/var/greyd"
     db_name = "greyd.db"

Em geral ele funciona apenas na interface de loopback, mas por usar um Debian mais velho, o Wheezy, precisei ajustar pra ouvir na interface pública, a eth0.

Feito isso, basta iniciar o daemon e o daemon de controle de log:

# /etc/init.d/greylogd start
# /etc/init.d/greyd start

Para quem já usa sistemas com systemd:

# systemctl start greylogd
# systemctl start greyd

O próprio systemd cuidará de adicionar e habilitar esses serviços.

Mas ainda falta o firewall.  São necessárias algumas regras na  inicialização:

# ipset create greyd-whitelist hash:ip family inet hashsize 1024 maxelem 65536
# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -m set \
--match-set greyd-whitelist src -j LOG --log-prefix "[GREYD WHITED]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -m set \
--match-set greyd-whitelist src -j NFLOG --nflog-group 155 # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -m set \
--match-set greyd-whitelist src -j ACCEPT # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j LOG \
--log-prefix "[GREYD 25 DNAT]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j DNAT \
--to-destination 200.123.234.321:8025 # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j LOG \
--log-prefix "[GREYD 25 REDIRECTED]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j REDIRECT \
--to-ports 8025 # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j LOG \
--log-prefix "[GREYD FAILED]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8025 -j LOG \
--log-prefix "[GREYD 8025 JAILED]" # iptables -t filter -A INPUT -p tcp --dport smtp -j ACCEPT # iptables -t filter -A INPUT -p tcp --dport 8025 -j ACCEPT

Eu adicionei mais logs pra poder também acompanhar os pacotes, pra ver se estão sendo marcados ou não de acordo.

De início eu fiquei na dúvida se eu estava recebendo algum e-mail ou não, mas logo percebi que estava funcionando de acordo.

A fila de mails indesejados, que ficavam travados por não ter endereço de retorno, praticamente zeraram.  O uso de memória aumento um pouco, assim como o conntrack no kernel.  Por enquanto nada absurdo.  E parece estar funcionando bem até agora.  Se não respondi algum mail seu, já sabe o motivo.

Acabaram os SPAMs?  Não!  Spam é spam.  Enquanto houver mail, existirá spammers.  É fácil de implementar e barato.  Mas eles diminuíram.  E ao saber que estou gastando a conexão deles fazendo nada já me alegra o suficiente.

Meu próximo passo será gerar um pacote no meu ppa no launchpad: https://launchpad.net/~helioloureiro

Pra saber mais como lutar contra spam: http://antispam.br/

Data de criação:
Data de publicado:
Acessos: 4294

Nem mal instalei o Ubuntu 16.04 com KDE5 e já quebrei o sistema.  Não sei bem o que fiz, mas as fontes ficaram simplesmente impossível de enxergar.  E olha que estou usando o desktop numa TV de 47 polegadas de  LED.

Tentei de tudo quanto foi jeito pra tentar ao menos ler os menus do KDE5, mas estava impossível.  Tentei reverter alguma possível mudança feita removendo os diretórios ~/.kde* ~/.config/k* e... nada!  Continuei com fontes micro.

Dando uma pesquisada na Internet encontrei alguns problemas semelhantes pra quem tinha placa NVIDIA, meu caso, que alguma atualização mudou os DPI (dot per inch, ou pontos por polegada) que afeta diretamente a resolução.

Encontrei uma boa descrição com solução no askubuntu: http://askubuntu.com/questions/197828/how-to-find-and-change-the-screen-dpi

Eu alterei o /etc/X11/Xsession.d/99x11-common_start e adicionei antes do fim a seguinte linha:

xrandr --dpi 96

E problema resolvido.

Só não entendi muito bem como cai nesse tipo de problema.  Talvez algum update no driver da NVIDIA.

 

Data de criação:
Data de publicado:
Acessos: 4166

Quando do lançamento da versão LTS do Ubuntu, a 16.04, vi várias receitas exotéricas de upgrade.  Depois do terceiro ou quarto artigo que li, tive a nítida sensação de que um copiou do outro, pois seguiam mais ou menos os mesmos passos.

Como eu não tinha tentado o upgrade, pois eu sempre espero um pouco pra fazer o upgrade já que é normal que vários bugs apareçam e depois de mais ou menos 1 mês estão corrigidos, achei que realmente essas formas de upgrade eram necessárias uma vez que o sistema de init mudou do 14.04 de sysvinit pra systemd no 16.04.

Agora finalmente fiz o upgrade e usei a forma anterior.  Não sei o motivo de ninguém ter mencionado mas... a forma de fazer upgrade é rodando o seguinte comando:

sudo do-release-upgrade

Pronto!  Upgrade será feito.  Como todo bom upgrade, vai dar umas zique-ziras que se resolve com um reboot seguido de "dpkg --configure -a" e "apt-get -f install", mas nada de muito grande.

Desculpem se foi curto, mas upgrade é coisa simples.  Sempre foi.

Data de criação:
Data de publicado:
Acessos: 2889

Quem participa dos grupos que faço parte, principalmente no FaceBook, sabem que uma das minhas respostas mais comuns é "leia o guia foca Linux".

O objetivo é trollar quem pergunta, sempre, mas também fazer a pessoa abrir os olhos sobre a documentação que existe na Internet.  Mas claro que é mais fácil perguntar primeiro, e ler depois.  Isso quando lêem.  Também sei que o nome mudou pra "guia foca gnu/linux", mas prefiro chamar pelo nome mais curto.  Questão de simplicidade, mesmo que gladiadores da liberdade não gostem.

O guia surgiu pela iniciativa de Gleydson Mazioli pra suprir uma demanda de material sobre Linux, acessível e em português.  Claro que atualmente abudam os livros, os sites e os blogs, mas na época em que o guia foi lançado isso não era tão verdadeiro assim.  Longe disso.  Era 1999.

O guia ajudou muita gente a iniciar e aprender Linux e Unix.  As bases são quase as mesmas nos últimos 40 anos de Unix (mesmo Linux não sendo Unix).  Mas como tudo em tecnologia, o guia está defasado.  Faltam coisas como systemd, novas distros, e até mesmo sobre git.

Então chegou a hora de poder contribuir.  Se algum dia fez uso de algum material disponível gratuitamente na Internet como o guia foca gnu/linux, ou mesmo do guia em si, aproveite pra contribuir e melhorar o mesmo, para que mais pessoas possam entrar nesse nosso mundo tão pequeno de software livre.

Eu criei um repositório do guia no GitHub: https://github.com/helioloureiro/guiafocalinux

basta fazer um clone do dele, criar ou atualizar os documentos e mandar seus pull requests.

Não é um fork do guia.  A idéia é melhorar o guia com atualizações e enviar as sincronizações pro próprio Gleydson, para atualizar no site.

Como contribuir?  O guia está escrito em SGML, que é um tipo de HTML mais direcionado para documentos.  Mas não precisa ficar preocupado com isso.  Basta adicionar o documento que queira implementar, e depois eu dou uma revisada e adiciono as tags necessárias.  O importante é escrever.  Se quiser começar de forma mais simples, pode editar um dos arquivos existentes e atualizar o mesmo.  É necessário utilizar o pacote debiandoc-sgml para ter os templates usados no documento no lugar e poder gerar o guia.  Então é mais fácil usar um Debian/Debian-alike como distro.  Claro que não é necessário e Docker sempre pode ajudar se for preciso.

Até agora eu converti somente os arquivos de iso-8859-1 para utf-8 e criei um Makefile para gerar o guia em pdf.  O próximo passo será descrever systemd.  E você?  Já pensou em como vai contribuir?

Aguardo seus pull requests :)

Data de criação:
Data de publicado:
Acessos: 2328

Quando li sobre docker e containers pela primeira vez, meu pensamento foi "ah... outra forma de ter uma VM".  Eu não sabia das facilidades que isso gerariam no meu dia-a-dia de trabalho em relação aos outros métodos de virtualização.

Docker, ao contrário de outras formas de virtualização, não é um sistema isolado onde se carrega um sistema operacional inteiro.  Por exemplo em KVM/Qemu ou KVM/Xen é possível instalar Windows, Android ou FreeBSD pois é um sistema completo de virtualização, que emula até uma camada de BIOS.  Já containers, como o Docker, não.  Eu não consigo rodar outro sistema que não seja aquele que roda na minha máquina em termos de versão de kernel e libc.  Então enquanto Qemu e Xen rodam em servidores com Linux ou FreeBSD, Docker é inerente somente ao Linux.

A parte de containers é relativamente nova no Linux.  Ela já existe faz uns 10 anos no FreeBSD com jails e mais ainda em Solaris com o zoneadm.  Depois que implementaram o cgroups no kernel que Linux começou a explorar essa possibilidade.  Os primeiros containers que surgiram no Linux foram através de LXC, que criava um segundo ambiente dentro do seu.  Em FreeBSD e Solaris containers significam compartilhar seu sistema em vários pequenos sistemas, o que faz sentido afinal, mas em Linux... Linux é um kernel.  Dizemos Linux por simplicidade, mas o sistema operacional que inclui kernel, Linux, e aplicativos, GNU por exemplo, é o que chamamos de distro.  Ubuntu é um sistema operacional, RedHat é outro sistema operacional, Debian outro ainda e assim por diante.  Então eles não rodam com as mesmas bibliotecas, nem usam o mesmos sistemas de pacotes.  E isso é um problema.  Os containers em LXC são capazes de criar um ambiente baseado no que está rodando, mas não uma outra distro dentro dessa distro original.

Nesse ambiente de possibilidades surgiu o Docker.  Docker permite rodar um container que tenha uma outra distro completamente diferente daquela que roda no sistema principal.  Mais ainda: Docker tem um repositório no estilo de GitHub que permite carregar ou baixar máquinas virtuais criadas por outras pessoas.

Então basta instalar Docker para começar a brincar.  Apesar de ter servidores Debian, eu rodo bastante Docker no meu laptop.  Então sei o procedimento pra Ubuntu via ppa, mas acredito que Debian deve ser bem parecido.  Outras distros não devem ser muito diferentes.

Instalando Docker no Ubuntu

Adicione diretamente o repositório nas configurações de fontes do apt:

root@laptop:~# cat << EOF > /etc/apt/sources.list.d/docker.list
deb https://get.docker.io/ubuntu docker main
EOF

Depois atualize a listagem de pacotes disponíveis e instale docker.io.

root@laptop:~# apt-get update; apt-get install docker.io

Então é preciso adicionar seu usuário ao grupo docker pra poder rodar sem precisar usar "sudo":

root@laptop:~# usermod -a -G docker helio

Reiniciada sua sessão (não precisa rebootar), docker deve estar disponível pra uso. 

Docker - primeiros passos

Com o Docker é possível verificar quais imagens estão disponíveis pra uso no repositório público.

helio@laptop:~$ docker search centos
NAME                            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
centos                          The official build of CentOS.                   1575      [OK]       
ansible/centos7-ansible         Ansible on Centos7                              60                   [OK]
jdeathe/centos-ssh-apache-php   CentOS-6 6.6 x86_64 / Apache / PHP / PHP m...   11                   [OK]
blalor/centos                   Bare-bones base CentOS 6.5 image                9                    [OK]
jdeathe/centos-ssh              CentOS-6 6.6 x86_64 / EPEL/IUS Repos / Ope...   8                    [OK]
torusware/speedus-centos        Always updated official CentOS docker imag...   7                    [OK]
million12/centos-supervisor     Base CentOS-7 with supervisord launcher, h...   7                    [OK]
nimmis/java-centos              This is docker images of CentOS 7 with dif...   6                    [OK]
feduxorg/centos                                                                 3                    [OK]
nathonfowlie/centos-jre         Latest CentOS image with the JRE pre-insta...   3                    [OK]
centos/mariadb55-centos7                                                        2                    [OK]
tcnksm/centos-node              Dockerfile for CentOS packaging node            2                    [OK]
nathonfowlie/centos-jira        JIRA running on the latest version of CentOS    1                    [OK]
feduxorg/centos-postgresql      Centos Image with postgres                      1                    [OK]
lighthopper/orientdb-centos     A Dockerfile for creating an OrientDB imag...   1                    [OK]
yajo/centos-epel                CentOS with EPEL and fully updated              1                    [OK]
layerworx/centos                CentOS container with etcd, etcdctl, confd...   1                    [OK]
feduxorg/centos-apache          Run Apache Event MPM on Centos                  1                    [OK]
blacklabelops/centos            Blacklabelops Centos 7.1.503 base image wi...   0                    [OK]
feduxorg/centos-rack            Centos to run rack applications like Ruby ...   0                    [OK]
jsmigel/centos-epel             Docker base image of CentOS w/ EPEL installed   0                    [OK]
lighthopper/openjdk-centos      A Dockerfile for creating an OpenJDK image...   0                    [OK]
jasonish/centos-suricata        Suricata base image based on CentOS 7.          0                    [OK]
pdericson/centos                Docker image for CentOS                         0                    [OK]
feduxorg/centos-geminabox       Gem in a box on centos                          0                    [OK]

É possível adicionar outros repositórios e, claro, fazer sua própria instalação.  Um problema sobre esse repositório público é que não existe garantia de não ter um malware junto.  Se o seu uso for como o meu, corporativo, não use.  Se for pra brincar e testar, vale o tempo.

A beleza do Docker é que pra rodar, basta chamar o comando.  Se o container não existe, ele busca imediatamente no repositório e roda.

helio@laptop:~$ docker run -it centos bash
Unable to find image 'centos:latest' locally
latest: Pulling from centos
47d44cb6f252: Pull complete 
168a69b62202: Pull complete 
812e9d9d677f: Pull complete 
4234bfdd88f8: Pull complete 
ce20c473cd8a: Pull complete 
centos:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:3aaab9f1297db9b013063c781cfe901e2aa6e7e334c1d1f4df12f25ce356f2e5
Status: Downloaded newer image for centos:latest
[root@1512dcd70309 /]# hostname 
1512dcd70309

Então, em outro terminal é possível ver a instância de Docker ativa.

helio@laptop:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
1512dcd70309        centos:latest       "bash"              2 minutes ago       Up 2 minutes                            jolly_sinoussi      

A cada nova chamada pra rodar Docker, uma nova instância é criada.

helio@laptop:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3b48633e67cc        centos:latest       "bash"              8 seconds ago       Up 6 seconds                            romantic_turing     
1512dcd70309        centos:latest       "bash"              4 minutes ago       Up 4 minutes                            jolly_sinoussi      

Como se deve imaginar, cada instância de Docker é completamente diferente uma da outra.  E não persistente.  Uma vez terminada a sessão, os dados adicionados são removidos.  Assim, se aplicar um upgrade no container e quiser manter, tem de criar um "snapshot" dele. Então pra salvar uma atualização no container:

[root@1512dcd70309 /]# yum update
Loaded plugins: fastestmirror
base                                                                                                                                              | 3.6 kB  00:00:00     
extras                                                                                                                                            | 3.4 kB  00:00:00     
systemdcontainer                                                                                                                                  | 2.9 kB  00:00:00     
updates                                                                                                                                           | 3.4 kB  00:00:00     
(1/5): base/7/x86_64/group_gz                                                                                                                     | 154 kB  00:00:00     
[... várias coisas seguem...]

é preciso fazer:

helio@laptop:~$ docker commit -m "Atualizado com yum update" 1512dcd70309 centos-atualizado
ff0f333c4abd4d9045ff074121df8fea7d109e87cc1dcb88317254fa0cfd66e4

É preciso usar o ID do container uma vez que várias instâncias podem existir originados da mesma imagem "centos".  Pra verificar suas imagens de containers, basta usar: 

helio@laptop:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos-atualizado   latest              ff0f333c4abd        40 seconds ago      269.9 MB
fedora2             latest              d97facef5329        31 minutes ago      398.7 MB
fedora              latest              c7d2f0130dae        5 days ago          204.3 MB
centos              latest              ce20c473cd8a        3 weeks ago         172.3 MB
susebuilder4        latest              97c67ab3589f        4 weeks ago         882.1 MB
susebuilder3        latest              15af476bea7b        4 weeks ago         784.6 MB
susebuilder2        latest              299ff2fa953d        4 weeks ago         685.6 MB
susebuilder         latest              9ca4e4487b77        4 weeks ago         661.3 MB
kiwi                latest              a037d86af491        12 weeks ago        436.7 MB
aekeroth/synapse    latest              a56b155c49a4        5 months ago        450.4 MB

 Pra remover alguma dessas images, como por exemplo esse aekeroth/synapse que nem lembro o motivo de estar ali, onde todos os "snapshots" relacionados serão removidos também:

helio@laptop:~$ docker rmi aekeroth/synapse
Untagged: aekeroth/synapse:latest
Deleted: a56b155c49a427661055b1a45c9233107b59fc6ec801467f04a29659a8330624
Deleted: b1c70ec40fcc659efd9da36beade75b8c2505c56c53499b231be692e29330d15
Deleted: 051d6978b0a8d3f344c0b6fdbdcae3e172f8e24c839d3969e118f2e6c1c64174
Deleted: b856d151b9c77a47d3d706e64880f898939afeb8312727a8fb5d715ef64ccf86
Deleted: c908ae302de39cb78669241ab2a65dfa1c750eb7f0818820286551bc450b5b0d
Deleted: 8927bb4878535574411efe47e5006049662fffa3f8984288b00ea49436fe5caf
Deleted: a055b38089a89db6f97c4bef2de139ebe06fd56976a87ef442ce6a9f5047497d
Deleted: 1057eb355528fc473af4bb6e9f529fdd70d7b8b02b764bf873166d7650341bd0
Deleted: 7bfe65031a48db2cc6206d6b4af9e52063a7d538a8e3d13b2f6e4f5d888e0f08
Deleted: cec2959569e4d51aee4bcc0409cebfc4a0a46b9d42142e4611c0fe6294824a8b
Deleted: ed5b1f07a6c393d55598770da45ec197be4682bfedabdf26bbab0208d5b7061a
Deleted: 2103b00b3fdf1d26a86aded36ae73c1c425def0f779a6e69073b3b77377df348
Deleted: 4faa69f72743ce3a18508e840ff84598952fc05bd1de5fd54c6bc0f8ca835884
Deleted: 76b658ecb5644a4aca23b35de695803ad2e223da087d4f8015016021bd970169
Deleted: f0dde87450ec8236a64aebd3e8b499fe2772fca5e837ecbfa97bd8ae380c605e
Deleted: 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158

Moby Docker, o monstro mítico dos mares das nuvens

Depois dessa rápida introdução ao Docker e containers, fica a pergunta: cadê a tal vantagem?  Pois precisei fazer uso dela recentemente por causa do LSB, Linux Standard Base.

Quando ouvi falar de LSB achei que era algo como padronização de diretórios como "/opt" e "/usr/local" além de localização de arquivos de inicialização em "/etc/init.d".  É, mas não é só isso. LSB cria uma base comum pra se compilar um binário em uma distro e rodar em outra.  Isso evita precisar ter ambientes diferentes com distros diferentes e versões dessas distros diferentes.  É uma facilidade. Mas... Debian, e consequentemente Ubuntu, não seguem mais a LSB.  Primeiro que é algo complicado, pois envolve verificação de compatibilidade de ABI, segundo que se não tem um interesse econômico, leia-se alguém pra pagar por isso, não vale a pena manter.

Como na empresa desenvolvemos binários pra RedHat e Suse, meu laptop se tornou um local inóspito pra compilar os binários que usamos.  São de OpenSAF, um projeto de software livre, mas é complicado manter um ambiente de compilação pra cada sistema.  E caro.  A solução inicial que adotamos foi instalar servidores com as versões de RedHat e Suse pra podermos compilar e verificar. 

Daí lembrei do Docker :)

Bastou criar um container com os pacotes de compilação necessários como gcc, g++ e rpmbuild.  Mas o repositório está no laptop, que roda Ubuntu.  Como compilar?  Como acessar os dados?

Primeiramente criei um usuário no container Docker com mesmo UID e GID que o meu, pra não criar tudo como root.  Em seguida chamei o Docker com parâmetros pra usar meu filesystem:

helio@laptop:~$ docker run -it -v /home/helio/OpenSAF:/opensaf --user=helio -w /opensaf susebuilder4 ./configure

e pronto!  Binários compilados num ambiente que suporta LSB.  Docker mapeia meu diretório local "/home/helio/OpenSAF" como "/opensaf" no container.  Inicia como usuário "helio" dentro do diretório "/opensaf" e roda o comando "./configure".  E pronto.  Quando termina o comando, o container desaparece.

Sim, saem lágrimas dos olhos de tão lindo.

Docker permite isso.  Imagine então rodar um ambiente virtual com servidor web ou qualquer outra aplicação.  Uma vez terminada, some o container.  Quer aumentar capacidade?  Só criar outro container.  Eu não comentei muito, mas é possível mapear portas locais pra portas internas do container, além de rodar o próprio como daemon.

Docker é um monstro de tão bom.  Não é uma baleia, mas um Moby Docker!  Vale testar.

Data de criação:
Data de publicado:
Acessos: 3037

Ainda hoje muita gente mostra supresa quando digo que estou rodando um kernel recém lançado em meu sistema.  Apesar de quase todo mundo saber que Linux é o kernel apenas, uma parte do sistema operacional, pouca gente compila seu próprio kernel. E isso é uma coisa bastante simples com Debian e Ubuntu, ou qualquer outro sistema baseado neles.

Também vejo pessoas distribuindo o kernel em forma de download em sites como 4share, mega, etc.  É legal contribuir com comunidade, mas distribuir um kernel assim, a parte mais vital do sistema, dá brecha de segurança pra que alguém insira um malware ali.  Então evite fazer isso.  E compile seu próprio kernel.

O primeiro passo é ter o código fonte do Linux.  Depois que passou a utlizar o git pra controle de versão (e muito mais que isso), eu também passei a usar o mesmo pra sincronizar meus fontes.  No diretório "/usr/src", como root, crie o repositório git local da seguinte forma:

root@jessie:src# git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

Não é um processo rápido.  O sistema vai baixar mais de 1 GB de arquivos no diretório "/usr/src/linux-stable".

Antes de botar a mão na massa, crie um novo "branch" com a versão que irá compilar.  É possível ver as versões disponíveis pelo comando "git tag -l".  No meu caso eu usei a versão v4.1-rc7.  Então a coisa toda pra listar e criar seu "branch" fica assim:

root@jessie:linux-stable# git tag -l | grep v4.1 
root@jessie:linux-stable# git checkout -b v4.1-rc7 tags/v4.1-rc7

O próximo passo é criar uma configuração de kernel antes de compilar.  Em geral eu copio o arquivo "/root/config-<minha versão corrente>".  Se quiser fazer isso, o comando correto é: 

root@jessie:linux-stable# cp /boot/config-$(uname -r) .

Existem outras maneiras de configurar o kernel, como usando o comando "make menuconfig" ou "make xconfig", entre outros.  Mas é preciso saber exatamente o que se quer do kernel pra configurar o que se realmente deseja.  Uma tarefa não muito fácil pras primeiras compilações.

O passo seguinte é instalar um pacote chamado "kernel-package".  Esse pacote é que faz toda a mágica da compilação e geração de pacotes pra você.  Isso mesmo: ao final do processo terá um kernel seu num arquivo .deb.  Eu já usei isso muito pra compilar em uma máquina e instalar em várias outras.  Voltando ao pacote, instale usado "apt-get", "apt" (novíssimo), ou "aptitude".

root@jessie:linux-stable# apt install kernel-package

O passo seguinte é chamar o kernel-package pra criar o kernel.  Eu pessoalmente uso da seguinte forma:

root@jessie:linux-stable# make-kpkg --initrd --append-to-version "-helio" --bzimage --revision 1 -j 4 kernel_image

O comando passado e os parâmetros são:

  • make-kpkg: é o comando instalado pelo pacote kernel-package.
  • --initrd: criar um sistema de boot initrd (a maioria dos sistema usa).
  • --append-to-version "-helio": pra deixar seu kernel com a sua "cara".  Vai aparecer algo como 4.1.0-rc7-helio na versão dele.
  • --bzimage: criar um kernel comprimido no formato bz.
  • --revision 1: revisão do pacote que será gerado.
  • -j 4: quantas CPUs serão usadas durante a compilação.  Se sua máquina tem múltiplos cores como a minha, basta colocar esse número.  Se não tem ou não sabe, não use esse parâmetro.
  • kernel_image: é o que diz pro kernel-package pra gerar só o pacote .deb do linux-image.  Pode-se criar outros pacotes como source, headers, etc.

Ao iniciar a compilação, o sistema passará por uma etapa de revisão da configuração que foi definida anteriormente.  Todo opção nova passará por uma pergunta se deve ou não ser incluída, ou ficar como módulo (pra ser carregado dinamicamente).  Toda pergunta já vem com alguma sugestão de resposta.  Em geral essa é a melhor opção a menos que realmente saiba o que aquela configuração significa.

Passada essa etapa, pode ir pegar um café.  Um café?  Melhor um bule inteiro.  E pode ir assistir ao último episódio de Game of Thrones que a compilação demora um pouco.

Uma vez terminada, se não tiver nenhum erro, será gerado um pacote com o formato "/usr/src/linux-image-<versão do kernel><nome que você personalizou>_<revisão>_<arquitetura da máquina>.deb".  No meu caso foi o pacote "/usr/src/linux-image-4.1.0-rc7-helio_1_amd64.deb".  Basta instalar e rebootar o computador pra testar a nova versão.

root@jessie:linux-stable# cd ..
root@jessie:linux-stable# dpkg -i linux-image-4.1.0-rc7-helio_1_amd64.deb
root@jessie:linux-stable# reboot

Se por acaso alguma coisa der errado, basta segurar o <Shift> ou <Esc> na inicialização da máquina, antes de carregar o Grub, pra poder ver o menu do mesmo.  Em seguida escolher o kernel que se estava rodando antes e inicializar por ele.  Depois basta remover o kernel criado, algo que e facilitado pela geração do pacote .deb.

root@jessie:linux-stable# dpkg -r linux-image-4.1.0-rc7-helio

Se for compilar o mesmo kernel, mas com opções de configuração diferentes, pode usar outra revisão.  Aliás incrementar a mesma.  Isso aparecerá no pacote gerado, mas não no kernel.

Boa compilação e boa diversão :)

Data de criação:
Data de publicado:
Acessos: 2330

Vírus em LinuxTem sido bastante difícil pra mim manter meu site atualizado, e não estou conseguindo manter meu ritmo de ao menos 1 post por semana.  Sinal de trabalho duro em outras coisas.

Estava pra comentar sobre esse assunto espinhoso, dos vírus pra Linux, faz um certo tempo.  Ao menos desde o início do ano.  Mas... enfim consegui um momento livre pra eu poder fazer isso.

A pergunta que surge de tempos em tempos é clara: EXISTEM VÍRUS PRA LINUX?

As respostas variam.  Defensores de Windows dizem que com toda certeza existem.  Mostram receitas esotéricas sobre como isso é possível e sempre voltam com a famosa frase "nenhum sistema é infalível", ou algo parecido com isso.

Os defensores de Linux, eu me incluo nesse grupo, dizem que é impossível.  Linux não é Windows.  Não foi feito sobre a mesma plataforma furada da Microsoft, que é cheia de buracos, e até provavelmente com alguns toques da NSA pra ajudar.  Se o usuário do Linux tem algum problema, o motivo é que não sabe atualizar sua distro.

Mas isso não explica a quantidade de problemas que têm aparecido sobre malwares em plataformas Linux, inclusive Android.

 

O problema é o windows.  Não que o windows tenha criado uma geração de vírus, mas o windows cunhou fortemente o conceito errado de que tudo é vírus.  Todo problema, malware, tudo é vírus.  E também foi graças ao windows que o conceito "se não funcionar, reinstala, se está lento, reinstala, e se quer mudar o wm, reinstala" se fortaleceu.  Isso se faz bem claro nos usuários que, pra trocar o Unity no Ubuntu, reinstalam o sistema inteiro.  Em geral com alguma refisefuqui.

Vírus é um pedaço de código que altera binários ou arquivos, e que se executa cada vez que esse programa é chamado ou aberto, no caso de arquivos.

Claramente isso não é possível no Linux por um simples motivo: quem executa o programa é o usuário e quem é o "dono" do binário é em geral o root.

Mas os problemas existem.  E muitos.  Existem os usuários que teimam em trabalhar como root no sistema, pra "facilitar as coisas".  Em geral os mesmos que reinstalam os sistema inteiro pra apenas trocar o wm (window manager).  Existem também os "programas de terceiros", como o plugin flashplayer, que não recebem as devidas atualizações de segurança.  Felizmente esses "programas de terceiros" não causam danos ao sistema como um todo, mas infelizmente podem fazer estrago o suficiente com o usuário, como permitir que suas credenciais de banco sejam roubadas.  Basta ver os recentes problemas do Java da Oracle.  Recentes?  Melhor dizer "contínuos".

E dá pra viver sem esses "aplicativos de terceiros"?  Até dá, mas não é muito fácil.  Alternativas existem, como pepperflashplugin ao invés do flash da Adobe, não usar acrobat reader ou seu plugin, mas os modos nativos do Firefox e do Chrome/Chromium pra renderizar pdf, etc.  O problema não são os "aplicativos de terceiros", mas se esses terceiros tratam os usuários de Linux com respeito, atualizando a cada falha encontrada.  Um bom exemplo dessa prática é o "steam", de jogos.

O problema então é o usuário, sempre?

Não.  Novamente o problema vem do windows.  Ou melhor, da idéia de vírus que veio com o uso do windows.  Quando discutimos o conceito de vírus, sempre nos vem a imagem de um desktop.  Daí os argumentos de problemas de segurança no Linux são apenas falta de atualização.  Isso não é verdade.

O outro lado do problema apareceu bem recentemente durante os ataques de DDoS do grupo LizzardSquad contra as redes de jogos PSN e Xbox Live.

Lizard Squad used hacked routers to take down Xbox Live and PlayStation Network

Foram usados roteadores caseiros, desses que usamos pra ter acesso wi-fi as nossas redes dentro de casa.  O artigo não diz, mas acredito que câmeras IPs também foram usadas.  

Esse tipo de problema não é novidade.  Foi discutido durante um dos YSTS, acho que o de 2013 que participei.  fabricantes, em geral na China, criam seus produtos pra rodar Linux, mas não dão nenhuma manutenção.  São sistemas customizados a ponto de ser impossível de rodar uma alternativa como dd-wrt/open-wrt. Esses sistemas rodam kernels Linux muito, mas muito velhos.  Daí que as explorações de vulnerabilidades, não vírus, ficam fáceis.  Nesse ponto temos de dar o braço a torcer pros usuários de windows.  Defender Linux nessas condições é quase como apontar o dedo pras máquinas windows comprometidas que rodam a versão XP.  O agravante é que o usuário se torna refém do fabricante, pois diferente dos computadores, esses sistemas embutidos não permitem que qualquer um atualize como quer, quando quiser, com a distro que mais gostar.

Então da próxima vez que ler sobre "vírus pra Linux", antes de cair na gargalhada, pense nesses roteadores e câmeras IPs.  Pense se esses sistemas rodando um Linux 2.4.20 não pode ter sua segurança facilmente comprometida.  Depois lembre que Windows, até hoje, pode ser comprometido acessando uma página web.  Foi corrigido?  Espere algumas semanas que sempre aparece de novo.

Ah... o windows...

Data de criação:
Data de publicado:
Acessos: 2055

Começando 2015, todos se lembram de como foi 2014.  Então resolvi escrever com um artigo sobre memória :)

Durante umas das discussões no grupo SOSLinux, alguém postou que já não usava Linux com swap fazia um tempo.  Nos meus velhos conceitos Unix adquiridos no século passado isso era algo inconcebível.  Uma heresia.  Um motivo pra receber um belo dum RTFM.

Esse é o problema de ter "aquela mesma velha opinião formada sobre tudo", como dizia Raul Seixas.  As coisas mudam.  Os sistemas evoluem.  Aquela recomendação de sempre se ter swap, e com fórmulas mágicas sobre seu tamanho, são coisas do passado, de uma era em que Linux era pra servidores e desktops.  Agora Linux está em todo lugar.  Na minha TV, no meu telefone, no meu tablet, e vai saber mais onde.  Talvez já esteja até no meu café e eu ainda não saiba.

Mas o fato é que naquela época a idéia era que as máquinas seriam cada vez maiores, mais potentes, mais gigantes, mais mais, muito mais.  Na verdade até são.  Mas aconteceu um fato interessante: o cloud.  Esse conceito permitiu uma forma de computação mais distribuída, com vários pequenos computadores ao invés de somente um maior.  E esse conceito foi se espalhando.  Se pensarmos hoje em dia nos celulares, eles são uma extensão computacional de algo que roda num datacenter.  Temos uma parte do aplicativo rodando localmente, e outra parte na nuvem.

Nesse novo paradigma, não é preciso tanto swap quanto antes.  Meu laptop tem 8 GB de RAM (tinha 12 GB com um pente extra de 4 GB que comprei no Dealextreme, mas o danado teima em dar problema de acesso e travar), mais que suficiente pra muita coisa.

Então resolvi experimentar.

Desabilitei o swap (swapoff /dev/mapper/vg-swap) e comentar a linha que o habilitava durante o boot no /etc/fstab.  E funcionou.  Mas bastou abrir chrome, firefox, thunderbird e eclipse pra coisa ficar feia (claro que a culpa é do java).

root@elx3030vlm-78:vm# head -16 /proc/meminfo 
MemTotal:        7926776 kB
MemFree:          218640 kB
MemAvailable:     889676 kB
Buffers:           57568 kB
Cached:           750036 kB
SwapCached:            0 kB
Active:          6672176 kB
Inactive:         404504 kB
Active(anon):    6282356 kB
Inactive(anon):    55548 kB
Active(file):     389820 kB
Inactive(file):   348956 kB
Unevictable:       65852 kB
Mlocked:           65852 kB
SwapTotal:             0 kB
SwapFree:              0 kB

Quando chega próximo do limite de memória, eu simplesmente tenho de aguardar o kernel decidir matar alguma coisa pra eu conseguir mandar um comando.  Até fiz um vídeo pra mostrar a situação.

{youtube}ga8lG2xE7wc{/youtube}

Nessas ocasiões a carga do sistema vai às alturas, provavelmente por troca de contexto de processos no kernel, tentando achar memória onde não tem.

Quando isso acontece, uma mudança do ambiente gráfico pro console e um reinicio do mesmo resolve.  Mas é chato.

Esses são os load averages que consegui enquanto gerava o vídeo acima:

 12:51:51 up 21:12,  6 users,  load average: 36.61, 59.21, 75.31
 13:01:24 up 21:21,  6 users,  load average: 57.21, 51.78, 61.71
 13:29:59 up 21:50,  6 users,  load average: 110.99, 122.08, 107.70

Então melhor com swap?  Não é tanto assim.  O sistema evoluiu, mas o problema de gerenciamento de memória é coisa do Linux.  Com swap esse tipo de problema também acontece, só demora mais.  Eu já tinha visto isso justamente com criação de vídeo no kdenlive.  Tinha um bug no melt, possivelmente um memory leak, que ia consumindo toda a memória.  Travava?  Não, mas tinha de aguardar o kernel matar o melt pra conseguir voltar.  Isso levava de 4 a 6 horas.  Usando somente RAM acontece o mesmo, mas é mais rápido, por volta de 20 ou 30 minutos.

Eu tentei achar alguma referência de tunning pra ajudar.

Memory Management Approach for Swapless Embedded Systems

When Linux Runs Out of Memory

http://linux-mm.org/LinuxMMDocumentation

O problema é que a maioria das informações são antigas.  No kernel que estou usando, 3.17.7, não tem esses parâmetros.  Mas eu tentei melhorar a responsividades alterando algumas coisas:

vm.laptop-mode = 1
vm.memory_failure_early_kill = 1
vm.memory_failure_recovery = 1

O resultado foi bastante satisfatório e agora o sistema tem estado mais responsivo durante alta carga que exige alocação de memória.  E com mensagens interessantes vindas do kernel.

Out of memory: Kill process 24223 (chromium-browse) score 332 or sacrifice child
Killed process 24223 (chromium-browse) total-vm:1360048kB, anon-rss:242548kB, file-rss:15632kB

Gosto de um sistema que exige sacrifícios.

Data de criação:
Data de publicado:
Acessos: 1733

Isso mesmo.  Olhando meus diretórios pra começar um backup, percebi que criei um arquivo com nome "-C".  Provavelmente resultando de alguma comando errado.

O que fazer nesse caso?  Em geral comandos como "rm" e "mv" não funcionam pois interpretam o "-C" como uma opção do comando, não como arquivo.

Existem várias formas de resolver isso, inclusive algumas mais fáceis via interface gráfica usando nautilus/dolphin ou algo do gênero.  Mas vou mostrar a "forma UNIX" de resolver isso.

Primeiramente, onde está o danado do arquivo?

helio@linux:home$ ls
backup -C helio fisl lost+found support

No caso estava no meu diretório "/home".  E o que era o arquivo?

helio@linux$ home# ls -l
total 646124
drwxr-xr-x 2 root root 4096 Nov 21 09:41 backup
-rw-r--r-- 1 root root 661555200 Oct 9 12:05 -C
drwxr-xr-x 367 helio linux 36864 Nov 21 09:43 helio
drwxr-xr-x 6 fisl fisl 4096 Mar 5 2014 fisl
drwx------ 2 root root 16384 Nov 16 2013 lost+found
drwxr-xr-x 5 support admin 4096 May 17 2013 support

Agora vem o truque.  Cada arquivo criado no seu filesystem tem junto um número de i-node, que é onde ele foi efetivamente gravado no disco.  É possível usar a opção "-i" do comando "ls" pra verificar cada número de i-node de cada arquivo do diretório, seja um arquivo, seja um diretório, ou seja qualquer outra coisa (em Unix, tudo é arquivo).

root@linux:home# ls -i
15335425 backup 4741 -C 16252929 helio 14942209 fisl 11 lost+found 15466497 support

Verificado qual o número do i-node, 4741, agora é usar o comando "find" com opção de "-inum" pra mexer nesse arquivo, junto com um "-exec".  Na opção "-exec", o arquivo encontrado é substituído pelo "{}", que é como se fosse uma variável com o que foi encontrado pelo parâmetros anteriores, no caso o "-inum".  

Então basta usar isso pra renomear o arquivo pra qualquer outro nome.

root@linux:home# find . -maxdepth 1 -inum 4741 -exec mv {} arquivo_alien \;

Verificando...

root@linux:home# ls
backup helio fisl lost+found support arquivo_alien

Agora descobrindo o que é esse arquivo.

root@linux:home# file arquivo_alien
arquivo_alien: POSIX tar archive (GNU)
root@linux:home# mv arquivo_alien arquivo_alien.tar
root@linux:home# tar tvf arquivo_alien.tar
drwxr-xr-x root/root 0 2014-10-09 12:05 home/
drwxr-xr-x fisl/fisl 0 2014-03-05 10:16 home/fisl/
drwxr-xr-x fisl/fisl 0 2014-03-05 10:16 home/fisl/.purple/
-rw-r--r-- fisl/fisl 173 2014-03-05 10:16 home/fisl/.purple/blist.xml
drwxr-xr-x fisl/fisl 0 2013-07-04 22:21 home/fisl/.purple/certificates/

Realmente um arquivo do tipo tar.  Provavelmente de algum backup que tentei fazer e passei a opção de forma errado.  Sem stress e problema resolvido.

root@linux:home# rm arquivo_alien.tar

unrpm

Autor:
Data de criação:
Data de publicado:
Acessos: 2169

unRPM

Apesar de adorar Debian e Ubuntu, o trabalho me exige mexer com pacotes RPM.  Ao contrário do format DEB, os pacotes RPM são mais simples de gerar.  Basta ter um arquivo SPEC, que informa os dados dos pacote como dependência e scripts para instalação, que é possível gerar usando rpmbuild.  Mesmo num Debian/Ubuntu.

Mas cai no caso de uma aplicação de opensaf já compilada.  E precisava gerar um pacote só com versão diferente, pra testar uma campanha de upgrade.  A solução seria desmontar o pacote RPM e montar novamente.  Um "unrpm" por assim dizer.  Eu tentei usar um pacote "rpmrebuild", mas o mesmo é feito pra sistemas já com uso de RPM, e precisa que o pacote esteja instalado pra conseguir reconstuir o mesmo.  Com certeza não o meu caso.

A parte do conteúdo não é difícil de fazer pois o pacote RPM é na verdade um arquivo de CPIO.  Usando como exemplo o pacote aalib-libs do fedora 20, com comandos rpm é possível ver as informações do pacote e seu conteúdo:

helio@debian:~$ rpm -qip aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm
warning: aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 246110c1: NOKEY
Name : aalib-libs
Version : 1.4.0
Release : 0.23.rc5.fc20
Architecture: x86_64
Install Date: (not installed)
Group : System/Libraries
Size : 159154
License : LGPLv2+
Signature : RSA/SHA256, Fri 16 Aug 2013 05:21:44 PM CEST, Key ID 2eb161fa246110c1
Source RPM : aalib-1.4.0-0.23.rc5.fc20.src.rpm
Build Date : Sat 03 Aug 2013 02:17:12 AM CEST
Build Host : buildvm-07.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager : Fedora Project
Vendor : Fedora Project
URL : http://aa-project.sourceforge.net/aalib/
Summary : Library files for aalib
Description :
This package contains library files for aalib.
helio@debian:~$ rpm -qlp aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm
warning: aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 246110c1: NOKEY
/usr/lib64/libaa.so.1
/usr/lib64/libaa.so.1.0.4
/usr/share/doc/aalib-libs
/usr/share/doc/aalib-libs/COPYING
/usr/share/doc/aalib-libs/ChangeLog
/usr/share/doc/aalib-libs/NEWS
/usr/share/doc/aalib-libs/README

Com o comando rpm2cpio seguido de cpio, é possível verificar que o conteúdo é o mesmo, sem perdas.

helio@debian:~$ cat aalib-libs-1.4.0-0.23.rc5.fc20.x86_64.rpm | rpm2cpio - | cpio -itv
lrwxrwxrwx 1 root root 14 Aug 3 2013 ./usr/lib64/libaa.so.1 -> libaa.so.1.0.4
-rwxr-xr-x 1 root root 125872 Aug 3 2013 ./usr/lib64/libaa.so.1.0.4
drwxr-xr-x 2 root root 0 Aug 3 2013 ./usr/share/doc/aalib-libs
-rw-r--r-- 1 root root 25265 Apr 26 2001 ./usr/share/doc/aalib-libs/COPYING
-rw-r--r-- 1 root root 3649 Apr 26 2001 ./usr/share/doc/aalib-libs/ChangeLog
-rw-r--r-- 1 root root 764 Apr 26 2001 ./usr/share/doc/aalib-libs/NEWS
-rw-r--r-- 1 root root 3604 Apr 26 2001 ./usr/share/doc/aalib-libs/README
314 blocks

Para extrair o conteúdo, bastaria usar as opções "-idv" do cpio.

Mas ainda falta os scripts de instalação que fazem a parte de pré-instalação, pós-instalação, pré-remoção e pós-remoção.  Como escolhi um pacote de biblioteca, esses não precisam de algo assim.  Pegando um pacote de servidor, no caso o bind - servidor de dns, é possível ver esses scripts que compões o SPEC.  Basta usar o comando "rpm --scripts -qp <pacote>".

helio@debian:~$ rpm --scripts -qp bind-9.9.4-8.fc20.x86_64.rpm
warning: bind-9.9.4-8.fc20.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 246110c1: NOKEY
preinstall scriptlet (using /bin/sh):
if [ "$1" -eq 1 ]; then
/usr/sbin/groupadd -g 25 -f -r named >/dev/null 2>&1 || :;
/usr/sbin/useradd -u 25 -r -N -M -g named -s /sbin/nologin -d /var/named -c Named named >/dev/null 2>&1 || :;
fi;
:;
postinstall scriptlet (using /bin/sh):
/sbin/ldconfig

if [ $1 -eq 1 ] ; then
# Initial installation
/usr/bin/systemctl preset named.service >/dev/null 2>&1 || :
fi
if [ "$1" -eq 1 ]; then
# Initial installation
[ -x /sbin/restorecon ] && /sbin/restorecon /etc/rndc.* /etc/named.* >/dev/null 2>&1 ;
# rndc.key has to have correct perms and ownership, CVE-2007-6283
[ -e /etc/rndc.key ] && chown root:named /etc/rndc.key
[ -e /etc/rndc.key ] && chmod 0640 /etc/rndc.key
fi
:;
preuninstall scriptlet (using /bin/sh):
# Package removal, not upgrade

if [ $1 -eq 0 ] ; then
# Package removal, not upgrade
/usr/bin/systemctl --no-reload disable named.service > /dev/null 2>&1 || :
/usr/bin/systemctl stop named.service > /dev/null 2>&1 || :
fi
postuninstall scriptlet (using /bin/sh):
/sbin/ldconfig
# Package upgrade, not uninstall

/usr/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ] ; then
# Package upgrade, not uninstall
/usr/bin/systemctl try-restart named.service >/dev/null 2>&1 || :
fi

Com essas informações é possível construir um pacote RPM binário.  Claro que no caso isso não é necessário pois bastaria pegar o pacote SRC e fazer o build novamente.  No meu caso, eu não sabia onde estavam os fontes e essa forma foi muito mais rápida, ainda mais que eu só precisava modificar a informação de versão pra testar upgrade.

Data de criação:
Data de publicado:
Acessos: 2466

Linux BSD

É comum encontrar em fóruns algumas discussões acaloradas sobre o uso do termo "GNU/Linux" ao invés de "Linux", e que o mesmo não seria o que é, pois é somente um kernel, sem o GNU.

Concordo em número, gênero e grau sobre a importância do GNU na história do software livre, e mesmo na do Linux.  Sem a influência de liberdade, Linus nunca teria pensado em ter um sistema completamente aberto.  Mas será mesmo que ele precisava das ferramentas da GNU, ou de outro modo não conseguiria sair do zero?

BSD para quem ama Unix

Em uma entrevista de 1993, Linus Torvalds comenta que não teria nem tentando criar o Linux se o 386BSD existisse.

The choice of GNU generation

Pra quem não lembra, Linux foi criado em 1991, enquanto que o FreeBSD apareceu somente em 1993.  Onde estava o BSD esse tempo todo?

Em 1991, Berkeley estava sofrendo um processo judicial por parte da AT&T, a dona do código fonte do UNIX, que tinha compartilhado com Berkeley durante sua origem, nos anos 70.  O UNIX BSD sempre fora distribuído gratuitamente, e com códigos fontes abertos e livres, sob a licença BSD.  Enquanto a AT&T tinha o UNIX como um projeto de laboratório, uma brincadeira dos engenheiros, isso não importava muito.  Mas no final da década de 80 o UNIX já era muito difundido e usado tanto nas universidades quanto fora delas.  Quando a AT&T chegou ao fim de seu contrato de monopólio das telecomunicações, ela simplesmente resolveu comercializar seu UNIX.  E como lidar com o seu concorrente livre, o BSD?  Não teria problema se continuasse dentro das universidades, mas existia uma empresa que vendia um UNIX derivado do BSD, o BSDi.  Então entra um processo judicial no meio do caminho.

BSD estava na sua versão 4, que incluia o stack recém criado de redes, o TCP/IP.  O processo terminou em 1992, quando foi feito um acordo em que o código BSD seria re-escrito sem a parte que pertencia à AT&T.  Surgia a especificação 4.4BSD-lite.  Nessa época, a revista Dr.Dobbs iniciou uma série de artigos que vinham com o código pra ter o BSD rodando em computadores com o processador i368.  Era o surgimento do 386BSD.

Mas o 386BSD tinha o problema de ter dono, Lynne Jolitz e William Jolitz.  Apesar do código estar totalmente publicado e permitir qualquer um compilar seu próprio UNIX BSD, era preciso passar quase 2 dias aplicando patches de voluntários pra ter o sistema atualizado e funcional.  Nesse ambiente sugiram os sistemas FreeBSD e NetBSD, como uma forma mais colaborativa de participação e manutenação do código.

E o GNU?

Nesse meio tempo entre 1990 e 1993, pode-se dizer que os UNIX BSDs praticamente pararam seu desenvolvimento.  Eles existiam dentro de máquinas PDP, os mini computadores da época, mas não nos computadores pessoais, que era o que Linus usava em casa pra programar.  Os BSDs precisavam do GNU?  Precisavam mas não do GNU como um todo.  Eles usavam o compilador GCC, que foi um dos marcos mais importantes do software livre.  O restante, dos comandos básicos ao kernel, já tinham em BSD.  Linux é um kernel enquanto que FreeBSD é um sistema operacional completo.  E descendente direto do UNIX.

Se Linus tivesse começado um pouco depois, em 92, ele poderia ter construído o Linux em cima de uma base BSD.  E continuaria um software livre.    Vantagens?  Acho que talvez mudasse o licenciamento pra BSD, mas provavelmente seria muito semelhante com o que temos hoje.

Mudar pra BSD ainda é possível?

Possível, é.  Valeria o esforço?  Eu diria que não.  Linux funciona muito bem com a parte GNU.  Se um dia surgisse algum problema de licenciamento, o que é impossível com softwares da GNU, ele poderia eventualmente ter um esforço pra mudar.  

Benefícios de desempenho?  Acho que também não.  Apesar dos BSDs terem um stack de rede com desempenho superior ao do Linux, isso não é imutável e frequentemente acontece de um passar o desempenho do outro.  Recentemente o Facebook anunciou uma iniciativa de melhorar o stack de rede do Linux pra igualar ao do FreeBSD.  Eu espero que supere, pra assim o grupo do BSD ter um objetivo pra melhorar mais :-)

E os BSDs não estão na frente em tudo.  O próprio "grep" da GNU é muito mais rápido e eficiente que seu semelhante BSD, pra listar apenas alguns.

Então, antes de dizer que Linux não seria nada sem o GNU, lembre dos BSD.  Atualmente nem o compilador é mais o GCC, sendo um sistema operacional totalmente funcional sem precisar necessariamente do GNU.  E 100% software livre.

Atualização: Tue Aug 19 18:30:18 CEST 2014

Eu esqueci completamente de comentar (obrigado pelo lembrete Bruno Máximo) mas o Android é um kernel Linux sem GNU, totalmente feito em cima de BSD.  E sim, o desempenho é muito bom.

2017  helio.loureiro.eng.br   globbersthemes joomla templates