Escrito por Helio Loureiro
Categoria:

Esse ano consegui me organizar e participar de um FLISOL, festival latino-americano de instalação de software livre.  Não só participar: participar mesmo, inclusive da organização.  Fiquei responsável pelo "installfest", para instalação de qualquer sistema livre.

Enquanto muitos associam "software livre" com Linux, eu fui além e preparei instalações para a família BSD: NetBSD, OpenBSD e FreeBSD.  Eu poderia ter incluído o OpenSolaris, mas achei que já seria muito preciosismo de minha parte.

Eu baixei as seguintes imagens de sistemas, para instalar via boot remoto ou algum outro método:

  • debian-testing-amd64-CD-1.iso
  • debian-testing-amd64-kde-CD-1.iso
  • debian-testing-amd64-netinst.iso
  • debian-testing-i386-CD-1.iso
  • debian-testing-i386-kde-CD-1.iso
  • debian-testing-i386-netinst.iso
  • Fedora-18-i386-DVD.iso
  • Fedora-18-x86_64-DVD.iso
  • linuxmint-201303-cinnamon-dvd-32bit.iso
  • linuxmint-201303-cinnamon-dvd-64bit.iso
  • linuxmint-201303-mate-dvd-32bit.iso
  • linuxmint-201303-mate-dvd-64bit.iso
  • NetBSD-6.0.1-amd64-install.img.gz
  • NetBSD-6.0.1-amd64.iso
  • NetBSD-6.0.1-i386-install.img.gz
  • NetBSD-6.0.1-i386.iso
  • openSUSE-12.3-DVD-i586.iso
  • openSUSE-12.3-DVD-x86_64.iso
  • slackware-14.0-install-d1.iso
  • slackware64-14.0-install-dvd.iso
  • ubuntu-12.10-desktop-amd64.iso
  • ubuntu-12.10-desktop-amd64+mac.iso
  • ubuntu-12.10-desktop-i386.iso
  • ubuntu-13.04-beta2-desktop-amd64.iso
  • ubuntu-13.04-beta2-desktop-i386.iso

No total foram 35 GB de imagens, incluindo AMD64 e i386, para atender máquinas com 32 bits ou 64 bits.  E mesmo uma imagem para tentar instalar em MACs, caso alguém pedisse.

O saldo foi que somente um laptop apareceu para ser "atualizado" de um Ubuntu 8.04 ou algo assim.  Após vários problemas, o sistema foi para 10.04 e... morreu.  O laptop começou a apresentar problemas de leitura e escrita (o motivo de estar dando problemas no upgrade).  E só.  Nada mais para instalar.

Mesmo assim foi um evento agradável onde foi possível rever vários amigos e conhecer pessoalmente mais outros tantos.  Como sempre, valeu a pena participar.

Essa são as fotos que fiz durante o evento.

Escrito por Helio Loureiro
Categoria:

Estou me cadastrando oficialmente como consultor de serviços de sistemas Debian.

Entre os serviços prestandos estão:

  • Segurança
  • Configuração de firewall.
  • Configuração de IPS/IDS.
  • Auditoria de sistemas.
  • Auditoria de redes.
  • Sevidores
    • Web Apache.
    • Mail com sendmail ou postfix.
    • PBX IP com Asterisk.
    • Servidor SAMBA (autenticação de máquinas windows).
    • Criação de daemons para atividades específicas.
  • Monitoração
    • Zabbix.
    • Nagios.
    • Munin.
    • Criação de módulos customizados.
  • CMS (Content Management Systems)
    • Wordpress.
    • Joomla
  • Redes
    • Servidor DHCP.
    • Roteador BGP/OSPF/RIP com Quagga.
    • Tráfego de rede com SNMP.

     

    Interessado em algum desses?  Então não hesite em entrar em contato.

    Mail: helio-arroba-loureiro-ponto-eng-ponto-br
    Twitter: @helioloureiro
    Escrito por Helio Loureiro
    Categoria:

    Se um dia disserem que é verdade, negarei com todas as forças.  Vamos dizer que essa história é uma ficção e que esse tipo de coisa nunca acontece nos meios corporativos.

    Então toda e qualquer referência por aqui é pura imaginação minha, certo?

    Pois então.  Sabem o que é virose?  Não?  Não minha opinião, é algo genial criado pelos médicos.  Já explico: pra quem tem filho, é comum ir ao médico pra ver alguma febre repentina que surge no meio da noite.  E, na falta de um diagnóstico, é comum ouvir o termo "ah, isso é algum virose".  Em geral trata-se com algum anti-termal (paracetamol ou algo do gênero) pra controlar a febre, e só.  Tem de se esperar passar.  

     Pois uma vez eu trabalhava com um sistema de stream de vídeo, e o vídeo, vez ou outra, mostrava umas áreas "quadriculadas" por alguma perda de pacotes da rede.  A questão é que a topologia estava exatamente assim:

    O servidor de stream estava conectado num roteador de core, que ligava via fibra ótica (10 Gbps) ao switch core, que ligava no DSLAM.  O DSLAM dividia a saída em 2 VLANs: uma pra Internet em geral, e outra específica pra TV.  Não existia nada mais ligado nessa rede.

    E quando é época de inferno astral, realmente não se tem muito o que fazer.  Pois bem no dia em que estávamos testando isso, surge uma "visita" inesperada do diretor da conta de vendas, querendo ver como andavam os testes.  No exato momento em que ele adentra a porta do recinto, a TV (talvez já mancomunada com algum ente espiritual maligno, algo como o exu-tranca-sistemas) resolve expor os pequenos pontos quadriculados.

    A meia hora seguinte foi de sabatina de perguntas sobre o motivo dos quadriculados.  Resolveu-se que aquilo era inaceitável e que a topologia deveria ser revista.  Toda ela.

    Não houve solução senão ir conectando o setupbox (a caixinha que convertia o stream pra saída de vídeo da TV) nos nós da rede para tentar detectar qual elemento estava falhando.  Primeiro retiramos a parte DSL (DSLAM e modem), ligando diretamente no switch core.  O quadriculado continuava lá.

    Movemos diretamente para o roteador de core, apenas trocando a porta de fibra ótica para ethernet.  E o quadriculado continuava lá.

    Então conectamos diretamente no servidor de stream, para assim já decretar sua morte e dizer que tínhamos encontrado a origem do problema.  E o vídeo passou normalmente...

    Esse é o exato momento em que todo mundo fica com aquela cara de poker face.

    Então resolvemos reconectar ao roteador, pois esse deveria ser o causador do problema.  Tudo conectado, fomos aos testes e... vídeo funcionando perfeitamente.  Nenhum problema aparente.

    Então conectamos novamente ao switch core para verificar se o problema poderia ser a porta de via fibra ótica e...

    Voltamos ao DSLAM e...

    Assumimos que aquilo era obra do demônio, o exu-tranca-sistemas mesmo, e seguimos a vida em frente, ou melhor, continuamos com os testes.

    Ao final do dia, recebo uma ligação de um alto escalão querendo saber se o problema havia sido resolvido.  Expliquei gentilmente que sim, e que todos os elementos de rede tinham sido revisados.  Então recebi a pergunta fatídica: qual era a origem do problema?  

    Sem titubear, respondi:

    - Virose de rede, mas já estamos administrando 10 pings de 4 em 4 horas, por 7 dias, para evitar inflamações nos links.

    E tudo teria terminado aí, se não houvesse uma apresentação para altos executivos.  

    No dia da tal apresentação, apareceram os distintos senhores, todos devidamente engravatados.  E começou-se a apresentação.  Eu, por ser um cara muito técnico, apenas fiquei ao fundo da sala assistindo a apresentação, que era ministrada por alguém que eu nunca tinha visto na vida, e que estava também devidamente engravatado.  E falava com bastante segurança sobre os testes realizados.  E tudo corria bem e tranquilo, com exibição perfeita do vídeo, quando, ao final da apresentação, o engravatado soltou em alto e bom som:

    - E durante os testes, nossos técnicos encontraram uma virose de rede.  Mas eles trabalharam arduamente para elinimar esse vírus e agora garantem que os links não ficarão inflamados, não afetando a performance do vídeo.

    Tive de sair da sala para não engasgar de tanto rir.

    Escrito por Helio Loureiro
    Categoria:

    Desde o fim do ano passado, tenho percebido que o Estadão resolveu colocar um filtro de conteúdo em alguns de seus artigos na web.

    Como o conteúdo pertence ao jornal, eles têm todo o direito de fazer esse tipo de abordagem.  Mas o que eu acho chato é que eles publicam esses artigos no twitter, e depois enfiam na sua cara o bloqueio.  

    Enfiam?  Será?

    Se enfiam na cara, quer dizer que roda na minha máquina e não na deles, certo?  Então eu posso dizer para meu navegador (no caso o Google Chrome) "não" ler esse bloqueio, não posso?  Claro que sim!

    Depois de uma procura no código da página, encontrei um javascript que chama uma função fadeOut() para criar esse efeito.  Bastou então achar o arquivo javascript com tal função.  Pra isso contei ajuda do browser por linha de comando Lynx e um pouco de shell script.

    for link in $(lynx \
       -source -dump \
       "http://www.estadao.com.br/noticias/esportes,pistorius-rejeita-acusacao-de-assassinato-da-namorada,997339,0.htm" | \
       grep js | \
       sed "s/.*src=\"//" | \
       grep estadao | \
       sed "s/\".*//" | \
       sed "s|^/|http://www.estadao.com.br/|" | \
       grep -v img.estadao)
       do 
       echo $link
       lynx -dump -source "$link" | \
          grep -i fadeout && \
          echo "ACHEI: $link" && \
          break
    done
    

    Então consegui achar que o vilão é o javascript de jquery:

    http://www.estadao.com.br/estadao/novo/js/jquery-1.5.2.min.js

    Bastou então usar o AdBlock Plus pra bloquear esse arquivo e tudo funcionou novamente.

     

    Escrito por Helio Loureiro
    Categoria:

    Finalmente resolvi publicar alguma coisa no slideshare.  Não que eu tenha tanta coisa assim pra compartilhar, mas estava ficando envergonhado de receber vários pedidos para "seguir" pessoas por lá, uma vez que nunca publiquei absolutamente nada.

    Então fiz o upload de algumas apresentações antigas, realizadas entre 2002 e 2005 (acho), que fiz para eventos do Debian-SP, GTER (Grupo de Trabalhos de Engenharia de Redes, ligado ao Nic.BR) e Maratona HOWTO, esse último um evento de HOWTOS que foi ideaizado pela 4Linux, se não estou enganado.

    São assunto variados, indo de roteamento avançado e controle de banda à PABX IP com Asterisk.  Provavelmente devem estar obsoletos, uma vez que faz mais de 10 anos que foram escritos, mas... ao menos publiquei algo por lá ;-)

     

    http://www.slideshare.net/helioloureiro

     

    Escrito por Helio Loureiro
    Categoria:

    Leap of faith, ou salto de fé, é um passo no vazio que se dá durante a série de jogos "Assassins Creed".  Basicamente significa "fechar os olhos e acreditar que vai dar certo".  Durante o jogo, existem lugares já marcados para usar o "salto da fé", onde em geral existem pombas, mas na vida real, nem tanto.

    Não que eu tenha tentado pular da varanda de casa, nem tentado assassinar ninguém.  Nada disso.  Mas esses dias eu fiz um "salto de fé" ao cancelar meu serviço de banda larga do Net Virtua e assinar o de fibra óptica da TIM.  Como não existem muitas instalações e descrições, foi um passo seguido de fé, muita fé...

    O acesso não é caro: paga-se por volta de R$ 60,00 por 35 Mbps de downstream e 20 Mbps de upstream.  Por mais ou menos R$ 50,00, o Net Virtua me fornecia somente 1 Mbps.  E esse não era o único problema com o Virtua: a latência de rede era o pior.  Simplesmente estava impossível de fazer qualquer coisa com o link, pois tudo tinha uma latência absurda, fazendo vídeos do Youtube engasgarem mesmo com a menor qualidade, e tornando impossível jogar jonline, como com "call of duty", na PSN do Playstation.  Não sei se é QoS mal feito do lado da Net, ou o que pode ser, mas com certeza não era o fato de ter somente 1 Mbps que fazia a diferença, pois tenho a mesma banda em outro lugar, também pelo Net Virtua, e não sofro desse problema.  

    Pela monitoração do link, dava pra ver que dificilmente essa banda era totalmente utilizada.  Mesmo sem tráfego na rede, os tempos de respostas de ping alcançavam valores próximos de 800 ms, o que mudou para 10 ms em geral com o link da TIM.

    helio@shibboleet:~$ ping -c 10 helio.loureiro.eng.br
    PING helio.loureiro.eng.br (200.160.198.15) 56(84) bytes of data.
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=1 ttl=50 time=10.6 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=2 ttl=50 time=10.1 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=3 ttl=50 time=10.1 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=4 ttl=50 time=10.7 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=5 ttl=50 time=10.2 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=6 ttl=50 time=11.3 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=7 ttl=50 time=10.0 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=8 ttl=50 time=10.1 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=9 ttl=50 time=10.0 ms
    64 bytes from cp01-tvt-db.durand.com.br (200.160.198.15): icmp_req=10 ttl=50 time=11.2 ms
    
    --- helio.loureiro.eng.br ping statistics ---
    10 packets transmitted, 10 received, 0% packet loss, time 9013ms
    rtt min/avg/max/mdev = 10.006/10.469/11.338/0.498 ms
    

    E justamente pela falta de comentários sobre o Live TIM, fibra óptica, que resolvi escrever um pouco sobre o mesmo.

    Primeiro que não é um serviço de fibra que chega em casa, o FTTH (Fiber To The Home).  É mais um FTTB (Fiber To The Building), pois a fibra óptica chega até o DG (Distribuidor Geral) do prédio, que fica no térreo, e daí é convertido por um DSLAM em VDSL, que então sobe para residência pelo sistema de par trançado de cobre, usado pela telefonia.  Na residência, ou melhor, no apartamento, é preciso um modem (CPE) de VDSL para converter esse sinal em rede ethernet.

    Nesse ponto existe um lado que pode ser tanto ruim quanto bom: o CPE.  É um modem da ZTE fornecido pela TIM que levanta uma sessão PPPoE com a rede, recebendo o IP válido, e faz NAT de saída.  O serviço da TIM gentilmente fornece o login e senha de administração pra poder alterar os parâmetros (admin/admin), mas o CPE usa um firmware completamente limitado, que não permite mudar muita coisa.  É possível configurar o wifi que vem embutido e o endereçamento interno, mas acaba por aí.  Isso me levou a ter 2 nívels de NAT na minha rede interna: o já existente no roteador TP-Link TL-WR1043ND e que roda DD-WRT, e esse segundo NAT do CPE da ZTE.  Com isso, não consigo mais acessar por ssh as máquinas internas da minha rede.

     

    Como não consegui acessar a portas das máquinas internas, utilizando port fowarding, não sei dizer se está faltando configuração no CPE ou se a TIM bloqueia as portas.  Isso no momento é chato, mas não é um problema que me faça voltar a usar o Net Virtua.  E também não quero desligar meu roteador com DD-WRT, pois o mesmo me ajuda a monitorar a rede com SNMP, entre outras coisas.  Eu testei a colocação de uma máquina logo atrás do CPE, com o roteamento de porta, e o mesmo não funcionou.  Então estou acreditando que a TIM realmente BLOQUEIA as portas ou o tráfego entrante.

    Tentei fazer a configuração do DD-WRT totalmente em bridge, mas não consegui até o momento.  Então esse é um ponto negativo do Livre TIM: utilizar um PPPoE com NAT no modem sem possibilidade de mudar.  Como o acesso fornecido não tem limitação de quantidade de dados, não entendi muito bem o motivo de usar o PPPoE  - outro ponto que não vou classificar como negativo, mas diria que desnecessário.  Outra coisa que fiquei decepcionado foi em relação ao tipo de IP recebido: somente IPv4.  Eu já estava salivando de excitação esperando um IPv6 também.  Mas como o CPE é novo, provavelmente deve suportar upgrade.

    Dos pontos positivos, a banda, o custo e o fato de não ter nem custo de instalação, nem contrato de serviço, podendo ser interrompido a qualquer momento.  Testei fazer download utilizando até 20 Mbps de downstream, com 10 de upstream liberado, e jogar ao mesmo tempo.  O resultado foi fantástico: sem problemas, nem latências, nem travamentos.  Ainda mandei um stream de vídeo no Youtube com mais um stream do NetFlix, ambos em HD, e... sem problema algum!

    Foi um realmente um salto de fé no escuro, mas aparentemente o serviço IP da TIM é muito melhor que seu serviço de telefonia.  Não estou arrependido, mas só vou poder dar uma opinião sobre a qualidade geral do serviço após 6 meses de uso, no mínimo.

    Atualização: Fri Feb 15 13:45:53 BRST 2013

    Justamente quando estava escrevendo sobre a banda larga da TIM, fiquei quase 24 horas sem Internet.

     

    Em termos de acesso à rede, isso é quase uma eternidade, o que desencadeou minha síndrome de abstinência internética.  Durante esse período, consegui acessar uma rede Wi-Fi de algum vizinho, que estava generosamente aberta sem senha alguma.  Nisso fui informado pelos amigo que o problema era um rompimento de fibra óptica, justamente na minha região.

    http://tecnologia.uol.com.br/noticias/redacao/2013/02/05/rompimento-de-fibra-otica-afeta-servicos-da-tim-e-da-intelig.htm

    Realmente foi muito azar ou acaso.  Acabei indo viajar até o carnaval, o motivo pelo qual não terminei de escrever e publicar esse post e só voltar a ele agora.  

    Mas após esse incidente, o link voltou e está funcionando sem problemas.

    Escrito por Helio Loureiro
    Categoria:

    XGH é uma das coisas mais genias que surgiu nos últimos tempos, descrevendo a estupidez que se aplica em métodos ágeis, mas que reflete bem o ambiente corporativo.  Infelizmente o site foi abandonado e seu conteúdo, apagado.

    Mas com a ajuda do wayback machine, consegui resgatar o conteúdo, e estou replicando aqui, para que fique imortalizado na Internet.

    Afinal, quem aqui nunca praticou XGH?

    Fonte: http://gohorseprocess.wordpress.com/extreme-go-horse-xgh/

    Wayback: http://web.archive.org/web/20100404033640/http://gohorseprocess.wordpress.com/extreme-go-horse-xgh/

     

    eXtreme Go Horse (XGH)

    1- Pensou, não é XGH.

    XGH não pensa, faz a primeira coisa que vem à mente. Não existe segunda opção, a única opção é a mais rápida.

    2- Existem 3 formas de se resolver um problema, a correta, a errada e a XGH, que é igual à errada, só que mais rápida.

    XGH é mais rápido que qualquer metodologia de desenvolvimento de software que você conhece (Vide Axioma 14).

    3- Quanto mais XGH você faz, mais precisará fazer.

    Para cada problema resolvido usando XGH, mais uns 7 são criados. Mas todos eles serão resolvidos da forma XGH. XGH tende ao infinito.

    4- XGH é totalmente reativo.

    Os erros só existem quando aparecem.

    5- XGH vale tudo, só não vale dar o toba.

    Resolveu o problema? Compilou? Commit e era isso.

    6- Commit sempre antes de update.

    Se der merda, a sua parte estará sempre correta.. e seus colegas que se fodam.

    7- XGH não tem prazo.

    Os prazos passados pelo seu cliente são meros detalhes. Você SEMPRE conseguirá implementar TUDO no tempo necessário (nem que isso implique em acessar o BD por um script malaco).

    8- Esteja preparado para pular fora quando o barco começar a afundar… ou coloque a culpa em alguém ou algo.

    Pra quem usa XGH, um dia o barco afunda. Quanto mais o tempo passa, mais o sistema vira um monstro. O dia que a casa cair, é melhor seu curriculum estar cadastrado na APInfo, ou ter algo pra colocar a culpa.

    9- Seja autêntico, XGH não respeita padrões.

    Escreva o código como você bem entender, se resolver o problema, commit e era isso.

    10- Não existe refactoring, apenas rework.

    Se der merda, refaça um XGH rápido que solucione o problema. O dia que o rework implicar em reescrever a aplicação toda, pule fora, o barco irá afundar (Vide Axioma 8).

    11- XGH é totalmente anárquico.

    A figura de um gerente de projeto é totalmente descartável. Não tem dono, cada um faz o que quiser na hora que os problemas e requisitos vão surgindo (Vide Axioma 4).

    12- Se iluda sempre com promessas de melhorias.

    Colocar TODO no código como uma promessa de melhoria ajuda o desenvolvedor XGH a não sentir remorso ou culpa pela cagada que fez. É claro que o refactoring nunca será feito (Vide Axioma 10).

    13- XGH é absoluto, não se prende à coisas relativas.

    Prazo e custo são absolutos, qualidade é totalmente relativa. Jamais pense na qualidade e sim no menor tempo que a solução será implementada, aliás… não pense, faça!

    14- XGH é atemporal.

    Scrum, XP… tudo isso é modinha. O XGH não se prende às modinhas do momento, isso é coisa de viado. XGH sempre foi e sempre será usado por aqueles que desprezam a qualidade.

    15- XGH nem sempre é POG.

    Muitas POG’s exigem um raciocínio muito elevado, XGH não raciocina (Vide Axioma 1).

    16- Não tente remar contra a maré.

    Caso seus colegas de trabalho usam XGH para programar e você é um coxinha que gosta de fazer as coisas certinhas, esqueça! Pra cada Design Pattern que você usa corretamente, seus colegas gerarão 10 vezes mais código podre usando XGH.

    17- O XGH não é perigoso até surgir um pouco de ordem.

    Este axioma é muito complexo, mas sugere que o projeto utilizando XGH está em meio ao caos. Não tente por ordem no XGH (Vide Axioma 16), é inútil e você pode jogar um tempo precioso no lixo. Isto fará com que o projeto afunde mais rápido ainda (Vide Axioma 8). Não tente gerenciar o XGH, ele é auto suficiente (Vide Axioma 11), assim como o caos.

    18- O XGH é seu brother, mas é vingativo.

    Enquanto você quiser, o XGH sempre estará do seu lado. Mas cuidado, não o abandone. Se começar um sistema utilizando XGH e abandoná-lo para utilizar uma metodologia da moda, você estará fudido. O XGH não permite refactoring (vide axioma 10), e seu novo sistema cheio de frescurites entrará em colapso. E nessa hora, somente o XGH poderá salvá-lo.

    19- Se tiver funcionando, não rela a mão.

    Nunca altere, e muito menos questione um código funcionando. Isso é perda de tempo, mesmo porque refactoring não existe (Vide Axioma 10). Tempo é a engrenagem que move o XGH e qualidade é um detalhe desprezível.

    20- Teste é para os fracos.

    Se você meteu a mão num sistema XGH, é melhor saber o que está fazendo. E se você sabe o que está fazendo, vai testar pra que? Testes são desperdício de tempo, se o código compilar, é o suficiente.

    21- Acostume-se ao sentimento de fracasso iminente.

    O fracasso e o sucesso andam sempre de mãos dadas, e no XGH não é diferente. As pessoas costumam achar que as chances do projeto fracassar utilizando XGH são sempre maiores do que ele ser bem sucedido. Mas sucesso e fracasso são uma questão de ponto de vista. O projeto foi por água abaixo mas você aprendeu algo? Então pra você foi um sucesso!

    22- O problema só é seu quando seu nome está no Doc da classe.

    Nunca ponha a mão numa classe cujo autor não é você. Caso um membro da equipe morra ou fique doente por muito tempo, o barco irá afundar! Nesse caso, utilize o Axioma 8.

    Escrito por Helio Loureiro
    Categoria:

    Se você conhece o inimigo e conhece a si mesmo, não precisa temer o resultado de cem batalhas. Se você se conhece mas não conhece o inimigo, para cada vitória ganha sofrerá também uma derrota. Se você não conhece nem o inimigo nem a si mesmo, perderá todas as batalhas.

    Sun Tzu

    Não que eu considere todos que visitam os links aqui como inimigos, muito pelo contrário, mas é sempre importante ter uma visão do tipo de público que acessa o conteúdo para eu ter certeza que não estou fazendo minha propaganda em local errado e, assim, até melhorar a audiência.

    Quando rodava com o Joomla 1.5, eu tinha o JoomlaStats para fazer análise dos visitantes, páginas mais acessadas, etc.  Com a migração pra versão 2.5, o JoomlaStats simplesmente deixou de funcionar - principalmente pelo abandono do projeto - e fiquei sem esse tipo de informação.

    Aproveitei esse início de 2013 para buscar alternativas para isso, uma vez que passei praticamente o ano inteiro de 2012 sem saber nada sobre o tráfego no site.  Tentei várias alternativas até chegar no j4age.  Fiquei simplesmente maravilhado em ver que tudo o que o JoomlaStats fornecia agora existe no j4age.

    Estatísticas com j4ag

    Agora, novamente, posso verificar quais sistemas operacionais acessaram o site.  Apesar da pouca coleta de dados, Windows ainda predomina.  O interessante é ver o Ubuntu separado de Linux.

    E também os navegadores mais utilizados.  Já de início aparece o chrome bem à frente do restante.

    E gráficos de tráfego.  Existem também um detalhamento por visitante, onde novos robôs de busca e indexação podem ser marcados como tal e, assim, não ser contabilizados.

    Além dessas funcionalidades que já existiam no JoomlaStats, existe agora uma amostra de visitas e indexadores em gráfico de pizza.  Ainda não entendi muito bem qual a vantagem disso, mas achei bonitinho.

    Uma vantagem do j4age em relação ao joomlastats é o fato de que o template de página não precisa ser alterado pra funcionar.  Basta instalar um módulo de mesmo nome, j4age-module, e ativar.

    Se você conhece o seu público e conhece a si mesmo, não precisa temer o resultado de cem acessos ao seu site. Se você se conhece mas não conhece o seu público, para cada acesso ganho sofrerá também um rebaixamento de link no Google. Se você não conhece nem o seu público nem a si mesmo, perderá todas as indexações no Google.

     

    Escrito por Helio Loureiro
    Categoria:

    Monitoração de pacotes

    Num desses dias que começaram o ano, precisei fazer o monitoramente de uma mensagem em SOAP (padrão de comunicação dos sistema de pré-pago com que trabalho).  Estava acostumado ao uso do wireshark pra fazer isso, mas descobri que não tinha o mesmo instalado.

    Instalar um wireshark não é nada demais pra quem tem apt-get, mas como eu estava dentro do ambiente da empresa e não queria problemas com a área de segurança da informação, que monitora o download de aplicativos como o wireshark, resolvi fazer direto com tcpdump.

    Para isso basta usar os parâmetros "-s 0", para definir tamanho máximo de pacote (não pegar somente alguns bytes), "-l" pra fazer a saída sem bufferização e, finalmente, "-A" para ter uma saída em modo texto dos caractéres ASCII dos pacotes capturados.

    Com isso, utilizei o comando "tcpdump -n -s 0 -l -A -i lo port 10066" e pude verificar se meu protocolo SOAP estava enviando os cabeçalhos corretamente.

    root@shibboleet:~# tcpdump -n -s 0 -l -A -i eth0 port 10066
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
    17:04:12.661207 IP 10.1.2.5.43789 > 10.1.2.5.10066: Flags [S], seq 2942898742, win 32792, options [mss 16396,sackOK,TS val 284979440 ecr 0,nop,wscale 7], length 0
    E..<b.@.@...
    {..
    'R.i.6........KB....@....
    ..p.........
    17:04:12.661232 IP 10.1.2.5.10066 > 10.1.2.5.43789: Flags [S.], seq 2517428391, ack 2942898743, win 32768, options [mss 16396,sackOK,TS val 284979440 ecr 284979440,nop,wscale 7], length 0
    E..<..@.@...
    {..
    .....i.7....KB....@....
    ..p...p.....
    17:04:12.661251 IP 10.1.2.5.43789 > 10.1.2.5.10066: Flags [.], ack 1, win 257, options [nop,nop,TS val 284979440 ecr 284979440], length 0
    E..4b.@.@...
    {..
    'R.i.7........K:.....
    ..p...p.
    17:04:12.661302 IP 10.1.2.5.43789 > 10.1.2.5.10066: Flags [P.], seq 1:1441, ack 1, win 257, options [nop,nop,TS val 284979440 ecr 284979440], length 1440
    E...b.@.@..H
    {..
    'R.i.7........P......
    ..p...p.POST /Air HTTP/1.1
    Accept-Encoding: identity
    Content-Length: 1245
    Host: air:10066
    User-Agent: DSMN/4.4/1.0
    Connection: close
    Content-Type: text/xml
    Authorization: Basic dmFpbGE6c2V1dHJvdXhh

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <methodCall>
    <methodName>UpdateOffer</methodName>
    <params>
    <param>
    <value>
    <struct>
    <member>
    <name>originNodeType</name>
    <value>
    <string>EXT</string>
    </value>
    </member>
    <member>
    <name>originHostName</name>
    <value>
    <string>HELIO</string>
    </value>
    </member>
    <member>
    <name>originTransactionID</name>
    <value>
    <string>410</string>
    </value>
    </member>
    <member>
    <name>originTimeStamp</name>
    <value>
    <dateTime.iso8601>20130115T17:04:12+0000</dateTime.iso8601>
    </value>
    </member>
    <member>
    <name>subscriberNumber</name>
    <value>
    <string>5511912345678</string>
    </value>
    </member>
    <member>
    <name>offerID</name>
    <value>
    <int>11</int>
    </value>
    </member>
    <member>
    <name>offerType</name>
    <value>
    <int>0</int>
    </value>
    </member>
    <member>
    <name>expiryDate</name>
    <value>
    <dateTime.iso8601>20131027T12:00:00+0000</dateTime.iso8601>
    </value>
    </member>
    </struct>
    </value>
    </param>
    </params>
    </methodCall>

    17:04:12.661312 IP 10.1.2.5.10066 > 10.1.2.5.43789: Flags [.], ack 1441, win 256, options [nop,nop,TS val 284979440 ecr 284979440], length 0
    E..4.X@.@.WX
    {..
    .....i......K:.....
    ..p...p.
    17:04:12.829800 IP 10.1.2.5.10066 > 10.1.2.5.43789: Flags [P.], seq 1:836, ack 1441, win 256, options [nop,nop,TS val 284979609 ecr 284979440], length 835
    E..w.Y@.@.T.
    {..
    .....i......N}.....
    ..q...p.HTTP/1.1 200 OK
    Content-Length: 681
    Content-Type: text/xml
    X-Powered-By: AIR-XmlRpc Server 3.2
    Server: air
    Date: Tue, 15 Jan 2013 19:04:24 GMT

    <?xml version="1.0" encoding="utf-8"?>
    <methodResponse>
    <params>
    <param>
    <value>
    <struct>
    <member>
    <name>expiryDate</name>
    <value><dateTime.iso8601>20131027T12:00:00+0000</dateTime.iso8601></value>
    </member>
    <member>
    <name>offerID</name>
    <value><i4>11</i4></value>
    </member>
    <member>
    <name>offerType</name>
    <value><i4>0</i4></value>
    </member>
    <member>
    <name>originTransactionID</name>
    <value><string>410</string></value>
    </member>
    <member>
    <name>responseCode</name>
    <value><i4>0</i4></value>
    </member>
    <member>
    <name>startDate</name>
    <value><dateTime.iso8601>20130115T12:00:00+0000</dateTime.iso8601></value>
    </member>
    </struct>
    </value>
    </param>
    </params>
    </methodResponse>
    17:04:12.829865 IP 10.1.2.5.43789 > 10.1.2.5.10066: Flags [.], ack 836, win 256, options [nop,nop,TS val 284979609 ecr 284979609], length 0
    E..4b.@.@...
    {..
    'R.i..........K:.....
    ..q...q.
    17:04:12.830228 IP 10.1.2.5.43789 > 10.1.2.5.10066: Flags [F.], seq 1441, ack 836, win 256, options [nop,nop,TS val 284979609 ecr 284979609], length 0
    E..4b.@.@...
    {..
    'R.i..........K:.....
    ..q...q.
    17:04:12.865118 IP 10.1.2.5.10066 > 10.1.2.5.43789: Flags [F.], seq 836, ack 1442, win 256, options [nop,nop,TS val 284979644 ecr 284979609], length 0
    E..4.Z@.@.WV
    {..
    .....i......K:.....
    ..q...q.
    17:04:12.865140 IP 10.1.2.5.43789 > 10.1.2.5.10066: Flags [.], ack 837, win 256, options [nop,nop,TS val 284979644 ecr 284979644], length 0
    E..4b.@.@...
    {..
    'R.i..........K:.....
    ..q...q.
    ^C
    10 packets captured
    20 packets received by filter
    0 packets dropped by kernel

    Nesse caso é uma aplicação que roda na porta 10066 que foi criada pra atribuir "Offers", ou ofertas de serviços através de um servidor que se chama AIR, Account Information and Refilling.

    Escrito por Helio Loureiro
    Categoria:

    E fechando o ano de 2012, um último artigo sobre hibernação no Ubuntu 12.10, que é pra lembrar de entrar 2013 bem descansado :-)

    Escrevo um artigo sobre a utilização do laptop sem ficar desligando, a guerra dos 100 dias, e seus benefícios e então me deparo justamente com um upgrade de sistema que não funciona com a hibernação.  E em menos de 6 meses.

    Tudo começou quando decidi passar o laptop de 32 bits para 64 (processador Intel Core i3).  Minha limitação para não realizar tal tarefa antes era o sistema de SSL VPN, da Juniper, usado pela empresa para conectar remotamente.  O sistema de VPN inicia um applet java que instala e roda uma biblioteca de 32 bits.  

    Já fazia algum tempo, eu vinha testando rodar isso em um modo "híbrido", com a funcionalidade de multi-arch ou com chroot de um ambiente de 32 bits.  Como tudo estava funcionando nos testes, resolvi mudar o sistema aproveitando as férias de fim de ano.

    Eu estava com Ubuntu 12.04 para i386, LTS, e resolvi instalar o 12.10 para amd64.  Eu poderia ter escolhido um upgrade do sistema, que aparentemente funcionaria, mas resolvi fazer uma instalação nova, o que acabou me gerando a perda de dados do /home, mas essa é outra história.

    Ao finalizar a instalação do 12.10 (e recuperar minha partição perdida - mas não completamente, duh!), eu me deparei com um kernel mais novo: 3.5.0-21-lowlatency.  Anteriormente eu estava rodando o 3.2.7-pf (post factum).  Não consegui fazer funcionar a hibernação de jeito nenhum.  Nem com pm-suspend, nem com pm-hibernate, nem com o novo método, o pm-suspend-hybrid.  Em todos os casos o sistema travava logo no início da hibernação e me deixava com uma tela preta, sistema operacional travado, mas máquina ligada.  Somente um procedimento de "dedo-off" conseguia desligar o laptop.  E sem nenhum log de problema por parte do ACPI.

    Tentei recompilar o kernel, instalar outra versão, a versão sem lowlatency, enfim de tudo.  Mas sem resultados.

    Por um acaso, notei um erro no sistema pelo "dmesg".  No começo achei que era problema da minha memória RAM.

    [    5.974345] BUG: unable to handle kernel paging request at 0000000000ff1000
    [    5.974351] IP: [] memcpy+0xd/0x110
    [    5.974359] PGD 1b0dbc067 PUD 1b0db9067 PMD 0 
    [    5.974363] Oops: 0000 [#1] SMP 
    [    5.974366] CPU 2 
    [    5.974367] Modules linked in: snd_page_alloc drm_kms_helper serio_raw drm 
    coretemp cfg80211 kvm_intel i2c_algo_bit kvm videobuf2_vmalloc videobuf2_memops 
    mxm_wmi wmi sony_laptop(+) intel_ips microcode mac_hid video mei lpc_ich btusb 
    bluetooth xfs firewire_ohci firewire_core crc_itu_t sdhci_pci sdhci atl1c
    [    5.974385] 
    [    5.974387] Pid: 637, comm: modprobe Not tainted 3.5.0-17-generic #28-Ubuntu 
    Sony Corporation VPCS110GB/VAIO
    [    5.974390] RIP: 0010:[]  [] memcpy+0xd/0x110
    [    5.974394] RSP: 0018:ffff8801b0d31c40  EFLAGS: 00010246
    [    5.974395] RAX: ffff8801b0d31c90 RBX: ffff8801ae9545c0 RCX: 0000000000000001
    [    5.974397] RDX: 0000000000000000 RSI: 0000000000ff1000 RDI: ffff8801b0d31c90
    [    5.974398] RBP: ffff8801b0d31c58 R08: ffff8801b2218200 R09: 000000018040003e
    [    5.974399] R10: 0000000000000000 R11: ffffffff813ad3e5 R12: ffff8801b0d31c90
    [    5.974401] R13: ffff8801b0d31caf R14: ffff8801b22f4800 R15: 0000000000000135
    [    5.974403] FS:  00007fb7feb92700(0000) GS:ffff8801bbc80000(0000) knlGS:0000000000000000
    [    5.974404] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    [    5.974405] CR2: 0000000000ff1000 CR3: 00000001b271d000 CR4: 00000000000007e0
    [    5.974407] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    [    5.974408] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    [    5.974410] Process modprobe (pid: 637, threadinfo ffff8801b0d30000, task ffff8801b0d8c500)
    [    5.974411] Stack:
    [    5.974413]  ffffffffa01a8893 0000000000000009 0000000000000035 ffff8801b0d31ce8
    [    5.974416]  ffffffffa01a9b69 ffff8801b16986a0 ffff8801b0067800 ffff8801b0d31c80
    [    5.974419]  ffffffff00000000 0000000000000009 0000000000000000 0000000000000000
    [    5.974422] Call Trace:
    [    5.974430]  [] ? sony_nc_buffer_call.constprop.12+0x43/0xa0 [sony_laptop]
    [    5.974435]  [] sony_nc_function_setup+0x2f9/0xab0 [sony_laptop]
    [    5.974440]  [] sony_nc_add+0x1f8/0x660 [sony_laptop]
    [    5.974446]  [] ? sysfs_do_create_link+0xeb/0x200
    [    5.974451]  [] acpi_device_probe+0x50/0x11d
    [    5.974457]  [] driver_probe_device+0x7e/0x220
    [    5.974460]  [] __driver_attach+0xab/0xb0
    [    5.974462]  [] ? driver_probe_device+0x220/0x220
    [    5.974465]  [] bus_for_each_dev+0x55/0x90
    [    5.974468]  [] ? 0xffffffffa01b4fff
    [    5.974470]  [] driver_attach+0x1e/0x20
    [    5.974473]  [] bus_add_driver+0x198/0x270
    [    5.974475]  [] ? 0xffffffffa01b4fff
    [    5.974478]  [] driver_register+0x77/0x150
    [    5.974483]  [] ? dmi_matches+0x53/0xc0
    [    5.974485]  [] ? 0xffffffffa01b4fff
    [    5.974488]  [] acpi_bus_register_driver+0x3e/0x47
    [    5.974492]  [] sony_laptop_init+0x57/0x1000 [sony_laptop]
    [    5.974498]  [] do_one_initcall+0x12a/0x180
    [    5.974502]  [] sys_init_module+0xc2/0x230
    [    5.974508]  [] system_call_fastpath+0x16/0x1b
    [    5.974509] Code: 2b 43 50 88 43 4e 48 83 c4 08 5b 5d c3 90 e8 eb fb ff ff 
    eb e6 90 90 90 90 90 90 90 90 90 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07  
    48 a5 89 d1 f3 a4 c3 20 4c 8b 06 4c 8b 4e 08 4c 8b 56 10 4c 
    [    5.974539] RIP  [] memcpy+0xd/0x110
    [    5.974542]  RSP 
    [    5.974543] CR2: 0000000000ff1000
    [    5.974545] ---[ end trace 67f7b54c3f5c5271 ]---
    

    Como a danada da falha mostrava um erro com "memcpy+0xd/0x110", eu imaginei que era falha de cópia de dados pra alguma endereço da memória RAM, ou seja, o pente de memória que comprei no #DX estava com problemas, o que denota a máxima de que, na dúvida, culpe o fornecedor Chinês mais próximo de você.

    Passei os restantes dos dias buscando por mais reclamações sobre problemas de hibernação no Ubuntu 12.10 ou algo parecido, e... nada.  Comecei a desconfiar mesmo dos produtos chineses, a ponto de passar 2 dias rodando memtest pra verificar o estado da RAM, procedimento aliás que só causa expectativa seguida de frustração, e não tira o produto Chinês da mira de vilão da história.

    Hoje, por um acaso muito grande, eu resolvi buscar pelo erro do bug, mas na verdade para buscar alguma ferramenta para bloquear o segmento de memória danificado.  Então busquei pela linha:

    BUG: unable to handle kernel paging request at

    E encontrei umas referências sobre problemas em... Sony Vaio!  Justamente a marca do meu laptop.  Coincidência?

    Então resolvi buscar diretamente o endereço de memória do meu problema:

    BUG: unable to handle kernel paging request at 0000000000ff1000

    E não é que peguei um problema reportado e bem descrito no Launchpad, o sistema de reporte de bugs do Ubuntu? Eu nunca tinha encontrado referências a esse bug porque a descrição fala de problema de Sony Vaio (outro duh!).

    [SONY VAIO VPCS12L9E] Suspend doesn't work after dist-upgrade to Quantal 12.10

    Felizmente a pessoa que abriu o bug report fez uma bela descrição do problema e também de uma solução.  Apenas apliquei os seguintes passos para ter meu sistema funcionando corretamente:

    sudo add-apt-repository ppa:shiba89/vaio-kernel
    sudo apt-get update
    sudo apt-get install linux-headers-generic sony-laptop-dkms
    

    Com isso, no boot seguinte tive a comprovação de que meu laptop voltou à hibernar feito um bebê.  E com isso fecho 2012 sem pendências, ao menos pessoais, para 2013.

    E que venha 2013!  Se sobrevivemos ao fim do mundo segundo os Maias, não é um problema de kernel que vai nos segurar!

    Escrito por Helio Loureiro
    Categoria:

     

    Invariavelmente eu preciso trocar o hostid de uma máquina com Solaris para realizar testes.  O objetivo não é pirataria, ou algo assim, mas testes de verificação de aplicativos com licença de uso, que são amarrados ao hostid da máquina.

    Eu conhecia um programa para fazer isso, mas essa semana topei com uma explicação bem legal de como fazer manualmente a mudança, disponível aqui: 

    How to Change the Hostid of a Sun Solaris Machine?

    Baseado nessa explicação, montei um programa em perl pra conseguir fazer a mesma coisa de forma mais simplificada, o hostid.pl.

    #! /usr/bin/perl
    
    $HOSTID = "/usr/bin/hostid";
    $SAVEORIG = "/etc/hostid.orig";
    $ADB = "/usr/bin/adb";
    $ADBOPTS = "-w -k /dev/ksyms /dev/mem";
    
    
    sub Usage() {
      print "Use: $0 \n";
      print "\t note: hostid must be 8 chars long\n";
      exit(1);
    }
    
    if ($ENV{"USER"} ne "root") {
      print "This must be run as root.\n";
      exit(1);
    }
    
    $newhostid = $ARGV[0];
    if (length($newhostid) != 8) {
      Usage();
    }
    
    if (! -f "$SAVEORIG") {
      print "Saving original hostid into $SAVEORIG\n";
      open(SAVE,">$SAVEORIG") or die "Impossible to save original hostid: $!\n";
      print SAVE `$HOSTID`;
      close SAVE;
    }
    
    $myhex = eval("0x".$newhostid);
    $mystr = sprintf("%s", $myhex);
    
    $i = 0;
    $parts[$i] = substr($mystr, $i, 4);
    $parts[$i + 1] = substr($mystr, $i + 4, 4);
    $parts[$i + 2] = substr($mystr, $i + 8, 4);
    
    for ($i = 0; $i <= 3; $i++) {
      foreach $p (split(//,$parts[$i])) {
    	$hwserial[$i] .= ($p + 30);
      }
    }
    $hwserial[2] .= "0000";
    
    $msg = "$ADB $ADBOPTS << EOF > /dev/null
    
    hw_serial/W 0x".$hwserial[0]."
    hw_serial+4/W 0x".$hwserial[1]."
    hw_serial+8/W 0x".$hwserial[2]."
    END
    
    EOF
    ";
    print "Applying hostid change into memory\n";
    system($msg);
    print "Enforcing new hostid across system\n";
    system("/etc/rc2.d/S20sysetup");
    
    Escrito por Helio Loureiro
    Categoria:

    O calcanhar de Aquiles do Linux sempre foi o gerenciamento de memória.  Por mais memória que se tenha disponível, ele vorazmente sempre quer mais.  E nunca libera a memória livre.

    E meus parcos 6 GB de memória do laptop tem sentido isso nesses últimos dias de 2012.   E verificável pelos gráficos do Munin, que mostra o pedido de 10 GB de memória pra usar.  Isso me faz pensar que talvez os Maias esteja certos.

     

     

    Eu ainda não descobri qual programa (ou processo) está causando isso, e o kernel Linux não cuida de matar o processo comilão.

    Então criei um pequeno daemon, em perl, para ficar lendo o /proc e matando os processos que mais consomem memória se a carga do sistema aumentar muito (atualmente marquei para load average maior de 10).

     

    #! /usr/bin/perl
    
    use POSIX;
    
    $PROC = "/proc";
    $MAXLOAD = 10;  #loadaverage
    $SLEEPTIME = 1; #seconds
    
    if (getuid() != 0) {
      print "Only root can run this program.\n";
      exit(1);
    }
    
    if (! -d $PROC) {
      print "Not possible to run.  System not running with $PROC directory\n";
      exit(1);
    }
    
    sub GetMem() {
      $pid_dir = $_[0];
      my $dir = $PROC."/".$pid_dir."/statm";
      open(MEM, $dir) or die "Error:$dir $!\n";
      @params = split(/ /, );
      close MEM;
      $memory = $params[0];
    
      return $memory;
    }
    
    sub GetPID() {
      my %MEM;
      opendir(PROC,$PROC) or die "Not possible to run.  System not running with $PROC directory\n";
    
      foreach $dir (readdir PROC) {
    	# Just read higher processes
    	# avoid init (1) or non-pid
    	next if ($dir !~ m/^\d\d\d+/);
    	$mem = &GetMem($dir);
    	if ($mem) {
    	  $MEM{$dir} = $mem;
    	}
    	
      }
      closedir PROC;
    
      return %MEM;
    }
    
    sub GetLoad() {
      open(LOAD,$PROC."/loadavg") or die "Impossible to detect load average by $PROC:$!\n";
      my $load = ;
      close LOAD;
      my @params = split(/ /, $load);
    
      return $params[0];
    }
    
    sub GetCommand() {
      my $pid = $_[0];
      open(CMD, $PROC."/".$pid."/cmdline") or die "Impossible to read the source command: $!\n";
      my $cmd = ;
      close CMD;
    
      return $cmd;
    }
    
    sub DaemonizeMe() {
      print "Starting to memory control daemon\n";
      POSIX::setsid or die "setsid: $!";
      my $pid = fork ();
      if ($pid < 0) {
    	die "fork: $!";
      } elsif ($pid) {
    	exit 0;
      }
      chdir "/";
      umask 0;
      foreach (0 .. (POSIX::sysconf (&POSIX::_SC_OPEN_MAX) || 1024)) { 
    	POSIX::close $_; 
      }
      open (STDIN, "/dev/null");
      #open (STDERR, ">&STDOUT");
    }
    
    &DaemonizeMe();
    my $mypid = getpid();
    my %DEATHCOUNTER;
    
    while (! $SIG{TERM}) {
      
      sleep($SLEEPTIME);
      my $load = &GetLoad();
      next if ($load < $MAXLOAD);
      my %MEM;
      %MEM = &GetPID();
    
      $higher_m = 0;
      $higher_pid = 0;
    
      foreach $k (sort keys %MEM) {
    	next if ($k eq $mypid);
    	$mem = $MEM{$k};
    	if ($mem > $higher_m) {
    	  $higher_m = $mem;
    	  $higher_pid = $k;
    	  $DEATHCOUNTER{$higher_pid}++;
    	}
      }
    
      if ($DEATHCOUNTER{$higher_pid} >= 5) {
    	print "Killing due higher memory usage: ".&GetCommand($higher_pid)." (".$higher_pid.") [".$higher_m." Bytes]\n";
    	%DEATHCOUNTER;
      }
    }
    
    print "Exiting...";
    exit(0);
    

    Os Maias podiam até estar certos, mas isso não significa que precisamos ficar sentados olhando.

    Escrito por Helio Loureiro
    Categoria:

    Se assim como eu, você precisa invariavelmente entregar programas binários e sem o código fonte, então também está sentindo falta do perlcc, que compilava o programa em perl em um belo binário.

    Devido à vários bugs, incompatibilidades e falta de manutenção, o perlcc foi removido já no perl 5.8.

    Eu testei várias outras soluções, mas ultimamente estava entregando binário utilizando o freeze do python, que eu achava mais simples.

    Hoje, buscando uma outra coisa perl, topei com um PAR packer.  Tanto a sintaxe quanto a funcionalidade é idêntica ao perlcc.

    PAR packer

    Eu testei aqui, e funcionou muito bem.

    helio@shibboleet:tmp$ pp -B -o accumulatorEventSender accumulatorEventSender.pl
    helio@shibboleet:tmp$ ls
    accumulatorEventSender  accumulatorEventSender.pl
    helio@shibboleet:tmp$ file accumulatorEventSender
    accumulatorEventSender: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), 
    dynamically linked (uses shared libs), for GNU/Linux 2.6.15,
    BuildID[sha1]=0x75828a5e4b38f0a935c9461e07d6ac23d3282d73, stripped

    O aplicativo se encontra no pacote libpar-packer-perl no Ubuntu (e possivelmente no Debian).