IPv6 in Plesk
I read a post 2 weeks ago here about a way of include ipv6 in plesk in a “persistent” way. I made exactly what the post says and it works. Now I can publish my IPv6 addresses.
Then I saw that my backups stop working with the error in /opt/psa/PMM/sessions/SOME_DATE_HOUR/migration.result:
<?xml version="1.0" encoding="UTF-8"?> <execution-result status="error"> <object name="backup" type="backupowner"> <message severity="error" code="msgtext">The dump have been invalidated by check-dump operation</message> </object> <object name="backup" type="backupowner"> <message severity="error" code="msgtext">Runtime error: The check dump failed with code '1'. The dump can contain invalid data! at /opt/psa/admin/bin/plesk_agent_manager line 638. </message> </object> </execution-result>
I found that the backup xml has a DTD and it’s validated after backup. This DTD is at /opt/psa/PMM/plesk.dtd. The patch is here:
--- plesk.dtd.old 2009-10-29 15:09:19.000000000 -0200 +++ plesk.dtd 2009-10-29 14:58:47.000000000 -0200 @@ -316,7 +316,7 @@ dst: destination record opt: optional record (MX priority and PTR subnet) --> <!ATTLIST dnsrec - type (A|NS|MX|CNAME|PTR|TXT|master|SRV) #REQUIRED + type (A|AAAA|NS|MX|CNAME|PTR|TXT|master|SRV) #REQUIRED src CDATA #REQUIRED dst CDATA #IMPLIED opt CDATA #IMPLIED --- plesk.xsd.old 2009-10-29 15:18:20.000000000 -0200 +++ plesk.xsd 2009-10-29 15:17:34.000000000 -0200 @@ -1818,6 +1818,7 @@ <xs:simpleType> <xs:restriction base="xs:token"> <xs:enumeration value="A"/> + <xs:enumeration value="AAAA"/> <xs:enumeration value="NS"/> <xs:enumeration value="MX"/> <xs:enumeration value="CNAME"/> --- restore-specification.xsd.old 2009-10-29 15:18:27.000000000 -0200 +++ restore-specification.xsd 2009-10-29 15:18:01.000000000 -0200 @@ -1814,6 +1814,7 @@ <xs:simpleType> <xs:restriction base="xs:token"> <xs:enumeration value="A"/> + <xs:enumeration value="AAAA"/> <xs:enumeration value="NS"/> <xs:enumeration value="MX"/> <xs:enumeration value="CNAME"/>
I hope this helps some of you that are trying to implement ipv6 in your servers.
Shrink de ext3 com LVM
Para fazer o shrink primeiro você precisa redimensionar o filesystem(resize2fs) e depois a partição(que no caso é LVM então é só redimensionar o LVM com lvreduce).
O grande problema é que no resize2fs você precisa jogar o tamanho da partição e não da para retirar espaço com -25G por exemplo como parâmetro, e o tamanho da partição nunca é igual ao tamanho do filesystem(que no caso possui journaling, etc…).
Qual a solução então. Suponha que temos uma partição com 395Gb e você quer devolver 25G para o VG. Então fação um resize2fs menor que o tamanho que você quer, lvreduce -25G e resize2fs sem parâmetro(que ele faz o resize para o tamanho máximo alocado):
# resize2fs /dev/vg00/home 340G # lvreduce -L -25G /dev/vg00/home # resize2fs /dev/vg00/home
Obs. 1: A partição precisa estar desmontada
Obs. 2: MUITO, mas MUITO cuidado com estes comandos. Você pode perder TUDO o que tem no disco. Os comandos resize2fs e lvreduce não são 100% confiáveis. Eu mesmo já perdi coisa(mas eu sempre faço backup antes de rodar isto em produção).
Repositório Ubuntu Intrepid
Resolvi criar um repositório para o intrepid com alguns pacotes indisponíveis e versões novas de outros softwares que desejo manter.
Entre eles atualmente:
- nagios3 (versão 3.0.6)
- php5-eaccelerator (versão 0.9.5.3)
- fwknop-server (1.9.9)
Para ativar o repositório como root digite:
# wget http://www.wsartori.com/repository/wsartori-repository.list --output-document=/etc/apt/sources.list.d/wsartori-repository.list
# wget http://www.wsartori.com/repository/wsartori-repository.key
# apt-key add wsartori-repository.key
# apt-get update
Controlando DNS round-robin de um Blackberry/IPhone
Tive que fazer uma interface de gerenciamento de DNS round-robin para fazer um “poor high-availability”. Consiste em de um telefone celular ou de qualquer browser controlar os servidores que fazem parte de uma entrada round-robin do DNS. Utilizei python para fazer um CGI simples que faz uma consulta no servidor de DNS para ver quais servidores estão atualmente respondendo e a página abre com estes servidores pré-selecionados. Você seleciona os servidores que deverão ser utilizados para a entrada e da um atualizar e ele atualiza via dynamic update no BIND.
Read the rest of this entry »
QEMU/KVM lentidão para instalar o Debian
Estava instalando o debian etch 32bits na minha máquina ubuntu hardy 64bits aqui da Predicta. Quando começa a carregar os pacotes do cd, ele fica MUITO lento e no ALT+F4 aparece:
hda: DSC timeout
A solução é antes de apertar enter em qualquer coisa no menu depois que subir o instalador, de um ALT+F2, de enter e digite:
echo dsc_overlap:0 > /proc/ide/ide0/hda/settings
A busca do Santo Graal: Google File System open-source
Talvez você já ouviu falar do file system que o google desenvolveu. Se ainda não, você pode ver o paper que eles publicaram em http://labs.google.com/papers/gfs.html. O GoogleFS(não vou escrever GFS pois é outro file system) foi aprimorado do BigFile criado por Larry Page e Sergey Brin(co-fundadores do google) no início do google. O mais lindo de tudo o que ele pode fazer é: simplesmente ir acrescentando servidores(na realidade computadores xing-ling mesmo até) na sua rede e eles irem adicionando espaço a um file system “virtual”, sempre tendo redundância em caso de falhas e podendo lidar com work-loads altíssimos. Ele é utilizado como backend por exemplo no GMail, no serviço de buscas do google, entre muitos outros produtos do google. Vou mostrar neste artigo o que da para fazer com ferramentas open-source.
Certificação ITIL
Fiz o curso de ITIL do dia 10 ao dia 20 de julho. Achei o curso muito legal para aqueles que querem treinar mais o lado gerencial. Fiz a prova hoje(dia 25/07/2007) e passei com 85%. Acertei 34 questões de 40 e fui extremamente bem. Agora sou um profissional certificado ITIL. Queria agradecer primeiramente a professora Monica Keiko Korosue que deu boas dicas para a prova e também aos outros alunos que ajudaram muito dentro e fora das aulas.
Keepalived, ipvs-sync e memory leak
Tenho uma camada de load-balance com Debian, utilizando keepalived com sync de conexão do IPVS(para não perder os estados das conexões).
Acontece que a bosta do IPVS, vai lotando a tabela de conexões e parece que nunca expira as conexões TCP/IP. Já tentei alterar os timeouts do TCP/IP nos proc do linux mais NADA da resultado. Meu próximo passo é testar uns patchs malucos que tem na lista de discussão para ver se resolve. Por enquanto so dando restart. Acontece que meu tráfego só aumenta, e a freqüência dos restarts também
. Não vou fazer testes em produção ou seja, estou esperando chegar alguns servidores, e vou acabar colocando um CentOS e configurando o Piranha(solução RedHat$$$ para o IPVS,MON,etc…) para fazer isto para mim. Vamos ver no que dá.
Abaixo o gráfico(note que quando os restarts são feitos a memória zera):
![]()
DRBD: Desync, split-brain, como voltar
Estou enfrentando uns paus com o DRBD. Do nada ele mata o sync e fode com tudo. Meu MySQL vai para o saco, CVS para de funcionar, etc… No log mostra um split-brain error e só consigo matar o DRBD rebootando a máquina(éca, mas fazer o que?)… o que eu fiz: no drbd.conf, tem 3 linhas do arquivos de configuração em resource, net:
after-sb-0pri disconnect;
after-sb-1pri disconnect;
after-sb-2pri disconnect;
mudei para:
after-sb-0pri discard-younger-primary;
after-sb-1pri consensus;
after-sb-2pri disconnect;
segundo a documentação do DRBD:
# In case the nodes of your cluster nodes see each other again, after
# an split brain situation in which both nodes where primary
# at the same time, you have two diverged versions of your data.
#
# In case both nodes are secondary you can control DRBD's
# auto recovery strategy by the "after-sb-0pri" options. The
# default is to disconnect.
# "disconnect" ... No automatic resynchronisation, simply disconnect.
# "discard-younger-primary"
# Auto sync from the node that was primary before
# the split brain situation happened.
# "discard-older-primary"
# Auto sync from the node that became primary
# as second during the split brain situation.
# "discard-least-changes"
# Auto sync from the node that touched more
# blocks during the split brain situation.
# "discard-node-NODENAME"
# Auto sync _to_ the named node.
after-sb-0pri disconnect;
# In one of the nodes is already primary, then the auto-recovery
# strategie is controled by the "after-sb-1pri" options.
# "disconnect" ... always disconnect
# "consensus" ... discard the version of the secondary if the outcome
# of the "after-sb-0pri" algorithm would also destroy
# the current secondary's data. Otherwise disconnect.
# "discard-secondary"
# discard the version of the secondary.
# "panic-primary" Always honour the outcome of the "after-sb-0pri"
# algorithm. In case it decides the the current
# secondary has the right data, it panics the
# current primary.
# "suspend-primary" ???
after-sb-1pri disconnect;
# In case both nodes are primary you control DRBD's strategy by
# the "after-sb-2pri" option.
# "disconnect" ... Go to StandAlone mode on both sides.
# "panic" ... Honor the outcome of the "after-sb-0pri" algorithm
# and panic the other node.
after-sb-2pri disconnect;
vamos ver se da resultado. eu aviso
Tarifador em C++
Há algum tempo atrás, desenvolvi em C++ um tarifador simples para PABX com saída serial. Com ele, você loga em um banco mysql todas as ligações que sua central faz e recebe. Espero que gostem. Só por curiosidade ele ta rodando até hoje se problemas lá
.
tarifador-v2.cpp
/* Author: Wagner Sartori Junior <wsartori@uol.com.br> Revision: $Id: tarifador-v2.cpp,v 2.0 2004/11/04 17:38:51 greg Exp greg $ GPL License Compatible */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <ctype.h> #include <string> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <syslog.h> #include <getopt.h> #include <termios.h> #include <mysql++/mysql++.h> using namespace std; char __revision__[] = "$Id: tarifador.cpp,v 2.0 2004/11/04 17:38:51 greg Exp greg $"; /* Override with -f option */ #define DEFAULT_CONFIG_FILE "/etc/tarifador.conf" /* Modify with -v/-q options */ static int VERBOSE = 0; /* Default */ #define VERSAO "2.0" #define _POSIX_SOURCE 1 #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; static char * USAGE = "usage: tarifador [options]\n" "\n" "options:\n" " -h, --help this help screen\n" " -d, --daemon detach and run as a daemon process\n" " -v increase verbosity by 1\n" " -q, --quiet run with no output\n" " -fFILE, --file=FILE read config from FILE\n" " (default: " DEFAULT_CONFIG_FILE ")\n" "\n" "-d implies -q; non-zero verbosity disables -d\n"; /* DataBase Variables */ char *dbserver; char *database; char *username; char *password; /* Serial Variables */ char *device; char *baudrate; static char * munge_line (char * line) { char * c; c = line+strlen(line)-1; if (*c == '\n') *c = (char) 0; c = strchr(line, '#'); if (c != NULL) *c = (char) 0; else c = line + strlen(line); c--; while (c > line && isspace(*c)) { *c = (char) 0; c--; } c++; if (c == line) return NULL; else return line; } static void read_config(char * filename) { char buf[1024]; FILE * file; char * param; char * resul; int i; int linenum; file = fopen(filename, "r"); if (!file) { fprintf(stderr, USAGE); if (VERBOSE > 0) { printf("Erro abrindo arquivo de configura��o %s\n", filename); exit(1); } } linenum = 0; while (!feof(file)) { char * line; if (!fgets(buf, 1024, file)) { break; } linenum++; line = munge_line(buf); if (line == NULL) continue; if (VERBOSE > 1) { printf("valid configfile line(%d): %s\n", linenum, line); } param = strtok(line, "="); resul = strtok(NULL, "="); if (strcmp(param, "dbserver") == 0) { dbserver = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(dbserver, resul); } else if (strcmp(param, "database") == 0) { database = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(database, resul); } else if (strcmp(param, "username") == 0) { username = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(username, resul); } else if (strcmp(param, "password") == 0) { password = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(password, resul); } else if (strcmp(param, "device") == 0) { device = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(device, resul); } else if (strcmp(param, "baudrate") == 0) { baudrate = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(baudrate, resul); } } fclose(file); } static void daemonize (void) { pid_t pid; pid = fork(); if (pid) { printf("parent process exiting\n"); exit(0); } else { printf("child process detaching\n"); setsid(); chdir("/"); close(0); open("/dev/null", O_RDONLY); close(1); open("/dev/null", O_WRONLY); close(2); open("/dev/null", O_WRONLY); } } MYSQL *pConnection; int main (int argc, char *argv[]) { int fd,c, res; struct termios oldtio,newtio; char buf[255]; string Query; string linha; int daemon = 0; char * config_file = DEFAULT_CONFIG_FILE; char * optstring = "dvqhf:"; struct option longopts[] = { { "daemon", no_argument, NULL, 'd' }, { "quiet", no_argument, NULL, 'q' }, { "help", no_argument, NULL, 'h' }, { "file", required_argument, NULL, 'f' }, { NULL, 0, NULL, 0 } }; int opt; int longindex = 0; opt = getopt_long(argc, argv, optstring, longopts, &longindex); while (opt != -1) { if (opt == 'd') { daemon = 1; VERBOSE = 0; } else if (opt == 'v') { VERBOSE++; daemon = 0; } else if (opt == 'q') { VERBOSE = 0; } else if (opt == 'f') { config_file = strdup(optarg); } else if (opt == 'h' || opt == '?') { fprintf(stderr, USAGE); exit(1); } opt = getopt_long(argc, argv, optstring, longopts, &longindex); } read_config(config_file); if (VERBOSE > 0) { printf("Var: device=%s\n", device); printf("Var: baudrate=%s\n", baudrate); printf("Var: dbserver=%s\n", dbserver); printf("Var: dbserver=%s\n", database); printf("Var: dbserver=%s\n", username); printf("Var: dbserver=%s\n", password); } fd = open(device, O_RDONLY | O_NOCTTY ); if (fd < 0) { printf("Erro na abertura do device (%s)\n", device); exit(1); } tcgetattr(fd,&oldtio); bzero(&newtio, sizeof(newtio)); if (strcmp(baudrate, "2400") == 0) { newtio.c_cflag = B2400 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "4800") == 0) { newtio.c_cflag = B4800 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "4800") == 0) { newtio.c_cflag = B4800 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "9600") == 0) { newtio.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "19200") == 0) { newtio.c_cflag = B19200 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "38400") == 0) { newtio.c_cflag = B38400 | CRTSCTS | CS8 | CLOCAL | CREAD; } else { printf("Baudrate (%s) not supported.", baudrate); exit(1); } newtio.c_iflag = IGNPAR | ICRNL; newtio.c_oflag = 0; newtio.c_lflag = ICANON; tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); if (daemon) { daemonize(); syslog(LOG_NOTICE, "Daemon started"); } while (STOP==FALSE) { res = read(fd,buf,255); buf[res]=0; if (res > 30) { linha.empty(); Query.empty(); linha = buf; if (VERBOSE > 0) { cout<<"Linha:"<<linha<<endl; cout<<"Data:"<<linha.substr(0,8)<<endl; cout<<"Hora:"<<linha.substr(8,8)<<endl; cout<<"Linha:"<<linha.substr(17,1)<<endl; cout<<"Ramal:"<<linha.substr(21,2)<<endl; cout<<"Duracao:"<<linha.substr(28,8)<<endl; cout<<"Destino:"<<linha.substr(36,32)<<endl; cout<<"Tipo:"<<linha.substr(68,1)<<endl; cout<<"================================================"<<endl; } if (linha.substr(68,1) == "2") { pConnection = mysql_init(NULL); if(!pConnection) { if (daemon) syslog(LOG_ERR, "mysql_init error"); printf("mysql_init error\n"); exit(1); } if(mysql_real_connect(pConnection, dbserver, username, password, database,0,NULL,0) == NULL) { if (daemon) syslog(LOG_ERR, "mysql pConnection error"); printf("mysql pConnection error\n"); exit(1); } Query = "INSERT INTO pabx_ligacoes (lin_id, ram_ramal, lig_data, lig_duracao, lig_destino) VALUES ('" + linha.substr(17,1) + "', '" + linha.substr(21,2) + "', '20" + linha.substr(6,2) + "-" + linha.substr(3,2) + "-" + linha.substr(0,2) + " " + linha.substr(8,8) + "', '" + linha.substr(28,8) + "', '" + linha.substr(36,32) + "');"; if(mysql_query(pConnection,Query.c_str()) != 0) { if (daemon) syslog(LOG_ERR, "Query (%s) error\n", Query.c_str()); printf("Query (%s) error\n", Query.c_str()); exit(1); } mysql_close(pConnection); } } if (buf[0]=='z') STOP=TRUE; } tcsetattr(fd,TCSANOW,&oldtio); return 0; }
tarifador.conf
# Configuracoes do Tarifador # device = device serial para leitura das tarifas # dbserver = hostname/ip do servidor de banco de dados # database = nome do banco de dados # username = nome do usuario para acesso ao banco de dados # password = senha de acesso ao banco de dados device=/dev/ttyS0 baudrate=2400 dbserver=server01 database=dbname username=dbuser password=dbpass sql=INSERT INTO pabx_ligacoes (lin_id, ram_ramal, lig_data, lig_duracao, lig_destino) VALUES (?, ?, ?, ?, ?);
tarifador.sql
-- -- Estrutura da tabela `pabx_ligacoes` -- CREATE TABLE `pabx_ligacoes` ( `lig_id` int(11) NOT NULL AUTO_INCREMENT, `lin_id` int(11) NOT NULL DEFAULT '0', `ram_ramal` int(2) NOT NULL DEFAULT '0', `lig_data` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `lig_duracao` time NOT NULL DEFAULT '00:00:00', `lig_destino` varchar(32) NOT NULL DEFAULT '', PRIMARY KEY (`lig_id`), KEY `lin_id` (`lin_id`), KEY `ram_ramal` (`ram_ramal`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tabela de Ligacoes Telefonicas' AUTO_INCREMENT=0; -- -------------------------------------------------------- -- -- Estrutura da tabela `pabx_linhas` -- CREATE TABLE `pabx_linhas` ( `lin_id` int(11) NOT NULL AUTO_INCREMENT, `lin_linha` int(8) NOT NULL DEFAULT '0', `lin_celular` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`lin_id`), UNIQUE KEY `lin_linha` (`lin_linha`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tabela de Linhas Telefonicas' AUTO_INCREMENT=0 ; -- -------------------------------------------------------- -- -- Estrutura da tabela `pabx_ramais` -- CREATE TABLE `pabx_ramais` ( `ram_ramal` int(2) NOT NULL DEFAULT '0', `fun_id` int(11) DEFAULT NULL, PRIMARY KEY (`ram_ramal`), KEY `fun_id` (`fun_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tabela de Ramais Telefonicos'; -- -- Constraints for table `pabx_ligacoes` -- --ALTER TABLE `pabx_ligacoes` -- ADD CONSTRAINT `pabx_ligacoes_ibfk_1` FOREIGN KEY (`lin_id`) REFERENCES `pabx_linhas` (`lin_id`), -- ADD CONSTRAINT `pabx_ligacoes_ibfk_2` FOREIGN KEY (`ram_ramal`) REFERENCES `pabx_ramais` (`ram_ramal`); -- -- Constraints for table `pabx_ramais` -- --ALTER TABLE `pabx_ramais` -- ADD CONSTRAINT `pabx_ramais_ibfk_1` FOREIGN KEY (`fun_id`) REFERENCES `funcionarios` (`fun_id`);
