Migrando aplicativos para Linux para System z

Dicas técnicas e ferramentas para ajudar a simplificar a migração de aplicativos para System z

A consolidação de servidor baseada em Linux para IBM System z oferece vantagens, mas mover aplicativos existentes requer conhecimento especializado. Este artigo oferece conselhos gerais sobre como organizar um projeto de transferência, incluindo detalhes técnicos sobre virtualização de mainframe, ordenação de bytes e cálculo de endereço específicos do System z. Este artigo também aborda como as ferramentas de desenvolvimento (compilador, vinculador, depurador) são suportadas no System z, e apresenta o Kit de Migração de Solaris OS para Linux da IBM grátis.

08 Jun 2012 - Por solicitação do autor, foi removida uma frase que não se aplica mais no segundo parágrafo de Endereços de 31 bits.

Wolfgang Gellerich, Developer, IBM

Dr. Wolfgang Gellerich estudou ciência da computação e química na Universidade Erlangen-Nuernberg e formou-se em 1993 com mestrado em ciência da computação. Até 1999, esteve no grupo de linguagens de programação da Universidade de Stuttgart, onde obteve o grau de PhD. Gellerich passou a fazer parte dos laboratórios de desenvolvimento da IBM em Boblingen em 2000. Fez parte do grupo de desenvolvimento de firmware, no qual sua principal responsabilidade era o desenvolvimento de GNU PL8. Atualmente é membro do grupo de desenvolvimento Linux para zSeries e trabalha em otimização de código de compilador e ferramentas de análise de desempenho. Seu email é gellerich-at-de.ibm.com.



26/Jul/2012

A consolidação de servidores em um ambiente baseado em Linux para System z traz muitas vantagens, mas, como você sabe, não existe almoço grátis — nem mesmo para pinguins. Mover aplicativos e servidores existentes para um ambiente Linux para System exige conhecimento específico e algum esforço.

Este artigo apresenta uma visão geral da transferência de aplicativos e não um guia detalhado. São incluídas referências a informações mais detalhadas para quem quiser aprofundar-se.

O Kit de Migração de Solaris OS para Linux contém várias ferramentas interativas para transferir aplicativos, além de algumas documentações técnicas (o Guia para Migrar do Solaris OS ao Linux e o IBM Redbook®Solaris to Linux Migration: A Guide for System Administrators).

Organizando seu projeto de migração

Antes de alterar algo, procure informações sobre as diferenças entre Linux para System z e seu sistema operacional e plataforma de hardware atuais. Todas as questões mencionadas neste artigo podem ser relevantes (ordenação de bytes, as opções passadas para o compilador etc). Além das referências neste artigo, há algumas excelentes fontes de informação que trazem muitos detalhes sobre as diferenças entre outros sistemas operacionais e o Linux. O livro UNIX® to Linux Porting aborda problemas gerais da retirada de programas de aplicativo de variantes proprietárias do UNIX, como AIX®, Solaris e HP-UX. Também apresenta uma introdução detalhada às ferramentas de desenvolvimento do Linux. (A seção Recursos contém links para esses e outros documentos úteis.)

Ao começar a modificar o aplicativo, não faça muitas alterações em cada etapa. Antes de alterar o próprio código fonte, modifique o ambiente de desenvolvimento. Verifique se as ferramentas de desenvolvimento necessárias no Linux estão disponíveis na sua plataforma atual (a coleção de compiladores GCC e GNU make são as mais importantes). Embora qualquer mecanismo de procura possa ajudar, as melhores fontes de informação são provavelmente as páginas iniciais do GNU e do GCC.

Em seguida, desenvolva o aplicativo na plataforma atual, mas use as novas ferramentas de desenvolvimento e execute um ciclo de teste completo. Apenas nesse momento você deve mover o código fonte para Linux e fazer as modificações apropriadas. As etapas restantes são as mesmas para qualquer outro projeto de software:

  • Faça testes extensivos.
  • Corrija os erros que encontrar.

Várias ferramentas de depuração do Linux suportam essa etapa e ajudam no ajuste de desempenho.


Linux para IBM System z

Felizmente, são poucas as questões conceituais que precisam ser consideradas ao migrar programas de aplicativos para Linux executando em um mainframe IBM System z. As interfaces oficiais do kernel Linux são projetadas para não depender de plataformas.

No entanto, uma diferença importante diz respeito à virtualização. Computadores pessoais geralmente executam sistemas operacionais nativos que controlam todo o sistema do computador. Por sua vez, os computadores IBM System z suportam o conceito de virtualização. Cada sistema operacional é executado em um ambiente virtual, e pode haver (e geralmente há) várias instâncias de sistemas diferentes em execução ao mesmo tempo. Esse ambiente virtual também gera alguns problemas administrativos.

Estrutura geral de um mainframe System z

Em um mainframe IBM System z, o Linux é sempre executado em um ambiente virtual. O mainframe é dividido em partições lógicas (LPARs). Cada LPAR pode executar diretamente um sistema operacional, como o kernel Linux, ou executar algumas imagens de máquinas virtuais (VM), como mostra a Figura 1. O uso de VM é um meio alternativo para criar um ambiente virtual para execução do Linux.

Figura 1. Estrutura geral de um computador System z executando várias LPARs e VMs
Estrutura geral de um computador System z executando várias LPARs e VMs

Essa estratégia apresenta várias vantagens, que vão desde balanceamento de carga dinâmico, planejamento de capacidade e questões de segurança a redes virtuais de alta velocidade entre as imagens do Linux. A rede virtual permite que as partes que estão comunicando ajam como se estivessem enviando e recebendo dados através de uma rede real, mas a transferência de dados é muito mais rápida e é realizada movendo dados dentro da memória principal do mainframe.

No entanto, o fato de que Linux para System z é executado em um ambiente virtual não afeta a tarefa de migrar um aplicativo. Portanto, não entrarei em mais detalhes aqui. O livro Linux on the Mainframe traz uma excelente visão geral e introdução. Além disso, IBM Redbooks contêm muitas informações valiosas e atualizadas e estão disponíveis online. (A seção Recursos contém os links.)

Convenções de nomenclatura

Ao longo dos anos, os modelos de IBM System z mudaram de nome várias vezes. Linux para System z foi lançado quando o nome do sistema era System/390®. A plataforma ainda chama-se S/390® no que concerne ao Linux.

Para código que depende da plataforma, use os seguintes símbolos predefinidos em expressões de pré-processador:

  • __s390__ a compilar para System z em modo de 31 bits ou 64 bits, ou ao compilar para S/390
  • __s390x__ ao compilar para System z em modo de 64 bits

A diferença mais importante talvez sejam as variações de endereços. Os modelos atuais do System z possuem arquiteturas de 64 bits, enquanto os modelos antigos forneciam apenas endereços de 31 bits. Quando for importante distinguir entre essas duas variações de endereços, a convenção é que s390 indica uma plataforma de 31 bits, enquanto s390x indica uma plataforma de 64 bits. O modo de endereçamento tem seu próprio conjunto de implicações, como discutido aqui. Observe que um dos bits na arquitetura de 32 bits define a arquitetura como modo de endereçamento de 31 bits; daí usarmos o termo modo de 31 bits.

Endereços de 31 bits

Observe que endereços de 31 bits não possuem um 32º bit utilizável. Portanto, endereços como:

0x80000000 +n

são mapeados para:

0x00000000 +n

Portanto, é preciso cuidado com aplicativos que aplicam valores de número inteiro em tipos de ponteiro. Além disso, endereços absolutos variam com a plataforma, e código que seja afetado por essa situação provavelmente precisa de alterações também.

Obviamente, valores de ponteiro criados usando os recursos "oficiais" da linguagem C sempre estarão corretos. Portanto, o compilador pode não remover o último bit à esquerda, fazendo com que a expressão a seguir seja falsa:

(void*)0x80000000 == (void*)0x00000000

Um problema relacionado ocorre quando aplicativos tentam carregar código em um endereço absoluto por meio de uma chamada a mmap com o sinalizador MAP_FIXED. Esse uso de endereços absolutos não é portátil e pode exigir alterações.

Convenções de numeração para bits

No Linux, é comum representar bits individuais de um byte ou palavra pelo expoente que teriam se fossem interpretados como um número binário. Os bits de uma palavra de 32 bits, por exemplo, seriam representados assim:

| 31 | 30 | 29 | ... 2 | 1 | 0 |

No entanto, a documentação relacionada ao IBM System z conta os bits da esquerda para a direita:

| 0 | 1 | 2 | ... 29 | 30 | 31 |

Nesse exemplo, o último bit à direita com valor binário 2^0 é chamado de bit 31. Em um sistema de 64 bits, esse bit é chamado de bit 63.

Tamanhos de tipos de dados padrão

A Tabela 1 mostra os tipos de dados C padrão em tamanhos de bytes:

Tabela 1. Tipos de dados padrão de C em tamanho de bytes
Tipo de dadosModo de 31 bitsModo de 64 bits
char11
short22
int44
float44
long48
pointer48
long long88
double88
long double88
size_t48
ptrdiff_t48
wchar_t44

O alinhamento é sempre o mesmo que o tamanho do tipo. Ou seja, uma variável do tipo int tem quatro bytes e é armazenada em um limite de 4 bytes. A Tabela 2 define os tipos de dados padrão do kernel Linux.

Tabela 2. Tipos de dados padrão do kernel Linux
Modogid_tmode_tpid_tuid_t
Modo de 31 bitsunsigned intunsigned intintunsigned int
Modo de 64 bitsunsigned intunsigned intintunsigned int

O documento ELF Application Binary Interface Supplement traz detalhes do layout de dados.

Extremidade

Extremidade refere-se à ordem na qual os bytes de uma palavra com vários bytes são armazenados na memória. Há várias maneiras de armazenar um valor binário de 32 bits, como 4A3B2C1D, incluindo:

  • O esquema big endian armazena o most significant byte (MSB) primeiro, gerando 0x4A 0x3B 0x2C 0x1D.
  • O esquema little endian armazena o least significant byte (LSB) primeiro, gerando 0x1D 0x2C 0x3B 0x4A.

Arquiteturas big endian incluem Sun SPARC e IBM System z. Todos os professores da família Intel x86 são little endian.

Infelizmente, muitos programas dependem da maneira como os dados são organizados na memória. Essa incompatibilidade entre plataformas é especialmente perigosa, pois pode fazer com que programas apresentem resultados errados em vez de causar um erro no tempo de compilação. Esse é um assunto sério. Padrões de código que podem ser afetados pela diferença em extremidade incluem:

  • Dados de processamento orientados por bytes.
  • Estruturas de dados acessadas por código de assembler. É necessário entender profundamente o layout dos dados ao reescrever as partes do código fonte que são implementadas em assembler.
  • Dados recebidos via rede.
  • Conversão de tipo usando "truques sujos" com ponteiros. Observe que até mesmo um código aparentemente simples como o exemplo a seguir depende da ordem de bytes da máquina:
    int x= 1;
    if (* (char *)&x == 1)
         printf ("little endian \n");
    else
         printf ("big endian \n");
  • Passar argumentos reais pequenos demais para uma função. Essa situação é semelhante ao exemplo de ponteiro anterior.
  • Conversão de tipo que usa (mal) tipos de dados union.

A Endianness Checking Tool, incluída no Kit de Migração de Solaris OS para Linux ajuda a localizar as partes do código que dependem de extremidade. A entrada dessa ferramenta é o código fonte do aplicativo e os binários resultantes compilados com algumas opções do compilador ativadas. O guia de operação da ferramenta apresenta instruções detalhadas. Uma instância comum seria semelhante a esta:

/test/src/init.c - Line 199: E30001 
Variable/parameter size mismatch arg 2 size 4 in call to mystrncpy.
(Defined in /test/src/init.c at line 190 size 1)

A Endianness Checking Tool não está restrita ao Solaris. Ela pode ser usada em qualquer código fonte C.

Caso seja necessário suportar plataformas com extremidades diferentes, é possível incluir o arquivo de cabeçalho asm/byteorder.h do kernel Linux, que define um dos dois símbolos dependendo da extremidade da máquina: __BIG_ENDIAN e __LITTLE_ENDIAN. Os arquivos de cabeçalho que se encontram em /usr/src/linux/include/linux/byteorder/ incluem macros para converter entre representações big endian e little endian. Quando a ordem é igual, essas macros resultam em nenhuma operação. Do contrário, retornam o valor convertido.

Existem funções semelhantes para lidar com problemas de ordem de bytes relacionados a dados transferidos via rede. Essas funções são declaradas em /usr/include/netinet/in.h e convertem valores entre a ordem de bytes da rede e do host. Observe que as redes geralmente usam a ordem de bytes big endian, portanto, um aplicativo que é executado no System z não precisa de conversão. De qualquer forma, é sempre uma boa prática de programação inserir as rotinas de conversão apropriadas.

Problemas de ASCII e EBCDIC

Por motivos históricos, sistemas operacionais de mainframe, como z/OS® e z/VM® usam o conjunto de caracteres EBCDIC. Linux para System z é completamente baseado em ASCII. Isso significa que migrar dados ou aplicativos do Linux para outras plataformas não cria problemas. Por outro lado, a interface do Linux para System z com dados ou programas executados sob controle de um sistema operacional que usa EBCDIC requer uma conversão.

A ferramenta do Linux chamada "recode" suporta a conversão de arquivos entre diferentes conjuntos de caracteres. A versão atual reconhece aproximadamente 280 conjuntos de caracteres, incluindo 19 variantes de EBCDIC com suporte a caracteres nacionais. Quando um programa exigir essas conversões, use a função iconv declarada em /usr/include/iconv.h

Listas de argumentos de variáveis

Geralmente, programas de aplicativos em C não precisam saber como listas de argumentos de variáveis são implementadas. No entanto, alguns códigos podem usar designações que não são migráveis, o que irá falhar no Linux para System z.

Linux para System z implementa o tipo va_list como struct. Portanto, uma designação normal como:

va_list va1, va2;
va_start (va1);
va2 = va1;       /* This assignment will not work. */

de uma variável desse tipo para outra não funciona como esperado. Em vez disso, use a macro __va_copy() para cópia, como em __va_copy (va2, va1);.

Bibliotecas e chamadas específicas da plataforma

Todos os sistemas operacionais oferecem alguma interface para programas de aplicativos e geralmente possuem um grande número de bibliotecas associadas. Algumas podem não estar disponíveis no Linux, ou podem ter um nome diferente. Informações sobre essas diferentes são fornecidas, por exemplo, em Unix to Linux Porting.

Ao migrar aplicativos do Solaris OS para Linux, a Source Checking Tool interativa (fornecida no Kit de Migração de Solaris OS para Linux) da IBM pode ajudar. A ferramenta reconhece aproximadamente 3.800 chamadas para a API do Solaris OS, incluindo arquivos específicos do sistema e pragmas (ou diretivas) do compilador Sun.

A Figura 2 mostra entrada para a ferramenta na forma de código fonte de aplicativo do Solaris OS escrito em C ou C++ que pode ser selecionado interativamente.

Figura 2. Seleção interativa de arquivos ou diretórios inteiros
Seleção interativa de arquivos ou diretórios inteiros

Em seguida, a ferramenta detecta todas as chamadas que precisam de alteração e destaca-as (Figura 3).

Figura 3. A Source Checking Tool destaca as chamadas de biblioteca que precisam de modificação
A Source Checking Tool destaca as chamadas de biblioteca que precisam de modificação

Alternativas do Linux e mais informações técnicas estão disponíveis interativamente, ou podem ser incluídas como comentários nos arquivos de origem, para que os desenvolvedores possam usar as informações sem precisar executar a ferramenta (Figura 4).

Figura 4. A ferramenta sugere alternativas do Linux para as chamadas específicas do Solaris e fornece informações técnicas
A ferramenta sugere alternativas do Linux para as chamadas específicas do Solaris e fornece informações técnicas

Felizmente, há também alguns padrões e convenções gerais. Por exemplo, ao desenvolver a Source Checking Tool, a equipe percebeu que 46% de todas as chamadas eram idênticas. Um exemplo em que não existem diferenças são as funções matemáticas encontradas em math.h.


Compilando, vinculando e depurando

A migração de um programa de aplicativo inclui usar o compilador padrão do Linux, GCC, e algumas ferramentas associadas. Todas suportam System z em algum grau. Uma análise das melhorias de desempenho obtidas entre 1999 e 2005 sugere que é vantajoso explorar as opções de otimização específicas do System z e as opções que permitem otimização para um modelo de processador específico (veja a Figura 5).

Figura 5. Aumento de desempenho devido a melhor otimização do compilador
Aumento de desempenho devido a melhor otimização do compilador

Todos os dados incluídos na Figura 5 vieram do modelo System z mais recente no ano em particular e são normalizados. Foram usadas medições sobrepostas para ajuste de escala quando as medições foram feitas em um novo modelo do System z. Um artigo em IBM Systems Journal, "Contributions to the GNU Compiler Collection" , detalha como o teste de medição foi realizado.

Opções de Compilador

GCC e os utilitários binários fornecem algumas opções que suportam Linux para System z. Para uma descrição completa de todas as opções do GCC, consulte Using the GNU Compiler Collection (GCC). Como esse manual inclui uma seção dedicada às opções específicas do System z, precisamos apenas apresentar uma visão geral aqui.

Além disso, é provável que opções adicionais de compilador sejam fornecidas para novos modelos do System z, e melhorias podem ser oferecidas para modelos existentes. Verifique a versão mais recente do manual para detalhes. As opções de otimização de código específicas do System z incluem:

  • -march=cpu-type: Explorar todas as instruções fornecidas por cpu-type, incluindo aquelas não disponíveis em modelos antigos. Em geral, código compilado com essa opção não pode ser executado em CPUs mais antigos. O site do GCC contém uma lista de tipos de CPU suportados.
  • -mtune=cpu-type: Planejar instruções para explorar melhor a estrutura interna de cpu-type. Essa opção não gera incompatibilidade com CPUs mais antigas, mas código ajustado para uma CPU diferente pode ser executado mais devagar.
  • -mzarch e -mesa: Gera código que explora o conjunto de instruções de ESA/390 ou de z/Architecture®, respectivamente. Para valores padrão e interação com outras opções, consulte o site do GCC.
  • -m64 e -m31: Determina se o código gerado é compatível com a ABI Linux para S/390 (-m31) ou a ABI Linux para System z ABI (-m64). Para zSeries, consulte z/Architecture Principles of Operation e Linux para zSeries ELF Application Binary Supplement, ou, para S/390, consulte ESA/390 Principles of Operation e LINUX for S/390 ELF Application Binary Interface Supplement (todos em Recursos) para detalhes sobre application binary interfaces (ABIs).
  • -msmall-exec e -mno-small-exec: Um comutador para otimizar instruções de salto em executáveis com tamanho total inferior a 64 KB.

Algumas opções controlam e otimizam o crescimento de pilha:

  • -mwarn-framesize=framesize e -mwarn-dynamicstack: Essas opções verificam, no tempo de compilação, se uma função excede um dado tamanho de estrutura de pilha ou se usa estruturas de pilha com tamanho dinâmico. Essas opções ajudam em casos em que espaço na pilha é raro, como no caso do kernel Linux, ou em que programas de aplicativo apresentam falhas devido a um estouro da capacidade.
  • -mstack-guard=stack-guard e -mstack-size=stack-size: Essas opções também ajudam a depurar problemas de tamanho de pilha. No entanto, as verificações são executadas no tempo de execução ao executar código extra inserido na biblioteca.
  • -mpacked-stack e -mno-packed-stack: Essas opções determinam se a estrutura de pilha usa um esquema de empacotamento denso, otimizado para espaço, para registrar os slots de salvamento. O manual do GCC contém informações sobre a compatibilidade com outras opções e compatibilidade de chamada com código binário gerado em versões do GCC anteriores a 3.0.
  • -mbackchain e -mno-backchain: Essas opções determinam se o endereço da estrutura de chamada é armazenado como um ponteiro chamado de "cadeia inversa" apontando para a estrutura de pilha do responsável pela chamada. O manual do GCC contém detalhes sobre a compatibilidade com outras opções e detalhes sobre depuração.

No Linux para System z, há uma diferença importante em relação a outros sistemas no que concerne bibliotecas compartilhadas: fpic e -fPIC. Ambas as opções permitem que o compilador gere position-independent code (PIC) para uso em bibliotecas compartilhadas reentrantes. No System z, -fpic faz com que a tabela de compensação global seja pequena; portanto, é melhor usar -fPIC para grandes bibliotecas compartilhadas.

Se o vinculador emitir a mensagem de erro "relocation overflow", verifique se o projeto usa a opção -fpic. A alteração para -fPIC pode corrigir isso. Observe que é necessário usar a mesma variante dessa opção para todas as execuções do compilador relacionadas ao mesmo projeto.

As opções -mfused-madd, -mno-fused-madd, -mhard-float e -msoft-float controlam o uso de operações de ponto flutuante. Consulte z/Architecture ou ESA/390 Principles of Operation para uma descrição completa do conjunto de infraestrutura e arquitetura do System z. Vários artigos técnicos (consulte Recursos) descrevem os aspectos da geração de código para System z por parte do GCC:

  • "The GNU 64-bit PL8 compiler: Towards an open standard environment for Firmware development."
  • "Porting GCC to the IBM S/390 Platform."
  • "Contributions to the GNU Compiler Collection."

Depuração

O Linux oferece uma ampla coleção de ferramentas de depuração. O GNU debugger (GDB) é bem eficiente. O Data Display Debugger é um front-end gráfico para GDB e suporta tarefas difíceis, como a visualização de estruturas de dados vinculadas por ponteiros.

Algumas ferramentas de depuração concentram-se na análise de erros relacionados a referências de memória. Electric Fence é uma ferramenta útil e disponível em muitas plataformas. Sua capacidade, no entanto, está limitada a memória de alocação dinâmica.

Outra ferramenta extremamente eficiente é VALGRIND. A principal propriedade desse programa é que é possível depurar qualquer binário, mesmo que ele não tenha sido compilado com opções de depuração ou mesmo que o código fonte não esteja disponível. Isso é realizado através de uma abordagem chamada instrumentação de código dinâmica.

Uma alternativa é usar a opção MUDFLAP oferecida pelo GCC. Ela faz com que o compilador insira verificações sempre que uma referência crítica de memória ocorre. Em seguida, essas verificações são executadas durante o tempo de execução do programa. Dado que o compilador teve acesso ao código fonte completo do programa, o diagnóstico de MUDFLAP é muito valioso.

Um recurso eficiente está disponível para Linux sendo executado em VM. O comando TRACE da VM é uma maneira conveniente de depurar todo o sistema Linux.

Para uma introdução à depuração, consulte Linux on the Mainframe; inclui uma descrição detalhada de depuração no Linux no arquivo /usr/src/linux/Documentation/s390/debugging390.txt.

Para depurar problemas mais difíceis, informações sobre uso de registro, layout da estrutura de pilha e outras convenções encontram-se em ELF Application Binary Interface Supplement. Além disso, Porting GCC to the IBM S/390 Platform descreve convenções usadas ao compilar para System z.

Desejo a você sucesso nos seus projetos de migração do Linux.

Recursos

Aprender

Obter produtos e tecnologias

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Linux
ArticleID=827402
ArticleTitle=Migrando aplicativos para Linux para System z
publish-date=07262012