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).
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.
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`);
BUG do OCFS2 e documentação
Meu RAID1 via rede DRBD deu kernel panic e matou minhas duas máquinas(ARGHHH!!!). Depois de vasculhar a net, achei no FAQ do OCFS2(primeiro lugar que eu devia ter olhado) o problema:
Q05 I encounter “Kernel panic – not syncing: ocfs2 is very sorry to
be fencing this system by panicing” whenever I run a heavy io
load?
A05 We have encountered a bug with the default “cfq” io scheduler
which causes a process doing heavy io to temporarily starve out
other processes. While this is not fatal for most environments,
it is for OCFS2 as we expect the hb thread to be r/w to the hb
area atleast once every 12 secs (default).
Bug with the fix has been filed with Red Hat and Novell. For
more, refer to the tracker bug filed on bugzilla:http://oss.oracle.com/bugzilla/show_bug.cgi?id=671
Till this issue is resolved, one is advised to use the
“deadline” io scheduler. To use deadline, add “elevator=deadline”
to the kernel command line as follows:1. For SLES9, edit the command line in /boot/grub/menu.lst.
title Linux 2.6.5-7.244-bigsmp elevator=deadline
kernel (hd0,4)/boot/vmlinuz-2.6.5-7.244-bigsmp root=/dev/sda5
vga=0×314 selinux=0 splash=silent resume=/dev/sda3
elevator=deadline showopts console=tty0
console=ttyS0,115200 noexec=off
initrd (hd0,4)/boot/initrd-2.6.5-7.244-bigsmp2. For RHEL4, edit the command line in /boot/grub/grub.conf:
title Red Hat Enterprise Linux AS (2.6.9-22.EL)
root (hd0,0)
kernel /vmlinuz-2.6.9-22.EL ro root=LABEL=/ console=ttyS0,115200
console=tty0 elevator=deadline noexec=off
initrd /initrd-2.6.9-22.EL.imgTo see the current kernel command line, do:
# cat /proc/cmdline
Fiz também a documentação de como foi feito isso, disponível no meu site.
Configurando DRBD com OCFS2 Em Modo Ativo-Ativo

