Friday, August 19, 2005


Please welcome the new football leader! Posted by Picasa

Wednesday, August 10, 2005

Importance to be FreeBSD (part 1)

   Тази първа част ще я посветя на инсталацията на FreeBSD. Водя се от принципа: "Ако се чупи нещо, то да е колкото се може по-рано". Така се предпазвам от безкрайно търсене в FreeBSD Google за решаването на някой проблем. Правя базовата система и не бързам с X - desktop. Стъпките, които ще предложа тук са съвсем начални, но те са достатъчни за лесна по-нататъчна надстройка и подръжка. Някои неща съм спестил, а в някои съм изложил в дълбочина. Инсталацията обаче може да поеме в толкова много посоки, че е невъзможно да се опише.
   Когато се появи менюто избирам Custom. От там разделям диска (40 GB):


Filesystem Size Mounted on
/dev/ad6s1a 512M /
/dev/ad6s1b 1G swap
/dev/ad6s1e 22G /home
/dev/ad6s1d 10G /usr
/dev/ad6s1f 2G /var
/dev/ad6s1g 838M /tmp (каквото е останало, но по-голямо от 512MB)

Отедлил съм 1G (2хRAM приблизително) за SWAP по възможност в началото на диска. Ще имате и нуждата от linprocfs ще я разберете, когато започнете да инсталирате java виртуалната машина. Не го забравяйте! В един момен трабва да добавите в fstab:
linprocfs   /compat/linux/proc   linprocfs   rw   0  0

Като втора стъпка инсталирам съвсем малко неща, които ще ми са нужни за начало. От менюто избирам Distributions и селектирам:
src(за да мога да компилирам ядрото), binaries(те са required). Така, до тук добре вече имаме базовата система. Останаха някои дребни добавки - Root Password, Time Zone, Mouse enable, Network(enable interface). Тук е и момента да се добави user. Когато се прави нов потребител, добре е да се знае, че само потребители от групата wheel могат да използват командата su. Преценете сами. Е, може да не вярвате, но имаме работеща FreeBSD система!
    Може би е добре да разясня каква ми е идеята. Искам да направя компютър, който да го ползвам за workstation. Моето PC не е първа младост, така че се старя да оптимизирам максимално FreeBSD-то. Една от първите стъпки в тази посока е инсталацията на приложенията. Искам да инсталирам от сорсовете т.н. ports. Каква е подготовката? Инсталирам надлежно както следва:

# pkg_add -r cvsup-without-gui
# pkg_add -r fastest_cvsup
# pkg_add -r portupgrade
# pkg_add -r docproj-nojadetex

Приготвям нещата за използването на cvsup. Създавам /root/cvs-supfile със следното съдържание:

#
# See variable PACKAGESITE in .cshrc(.bashrc)
# when update to next STABLE
#
*default host=cvsup7.freebsd.org
*default base=/var/db
*default prefix=/usr
*default tag=RELENG_6
*default release=cvs delete use-rel-suffix compress
src-all
doc-all tag=.

Не се изкушавайте да вземате последното ядро дори и това да не е сървър(с опцията *default tag=.). В HEAD-а на CVS попадат доста експериментални(някои неуспешни) неща има и много debug съобщения, затова като цяло системата ви ще работи по-бавно. Ако е продукционна системата, сложете *default tag=RELENG_6(STABLE release) например. За да не тегля всичко мога да укажа кои документи НЕискам. За целта създавам директориите /var/db/sup и /var/db/sup/doc-all. В /var/db/sup/doc-all поставям файла refuse. Ето какво има в него:

doc/bn_*
doc/da_*
doc/de_*
doc/el_*
doc/es_*
doc/fr_*
doc/it_*
doc/ja_*
doc/nl_*
doc/no_*
doc/pl_*
doc/pt_*
doc/ru_*
doc/sr_*
doc/tr_*
doc/zh_*

Мммда готови сме за първия старт на cvsup.
# cvsup -L2 -h  cvsup.freebsd.org /root/cvs-supfile

Тя ще обнови всички сорсове в базовата система и документацията. Ще положим малко усилия и за портовте. Използва се portsnap.

# portsnap fetch
# portsnap extract

Първата команда прави download на "порт дървото", а втората го слага в /usr/ports. Управляващия файл e /etc/portsnap.conf.
Приемете нещата там "по default" - махнете коментарите. Там може и да окажете НЕжеланите портове, за да спестите малко време.

REFUSE arabic chinese french german hebrew hungarian japanese korean
REFUSE polish portuguese russian ukrainian vietnamese
REFUSE astro biology


Kроя планове и за автоматизация. Един скрипт, които да пускам, докато си пия сутришното кафе и той да ми подсказва какво трябва да update-на. Идеята си струва, ще знам дали съм up-to-date само с една команда. Преминавам към действие. За да имам документацията само на английски са нужни малко обходни стъпки. Променям една част от /usr/doc/Makefile файла:

.if defined(DOC_LANG) && !empty(DOC_LANG)
SUBDIR = ${DOC_LANG}
.else
SUBDIR = en_US.ISO8859-1
.endif


За съжаление cvsup ще "забърше" моите промени, и затова правя хитринка:

# cp /usr/doc/Makefile /usr/doc/Makefile.orig


Ето и моя работещ cvsupScript.sh:


#!/bin/sh

#Use fastest_cvsup to find fastest geographically
#close mirror; I'll check Russion, Germany

if SERVER=`fastest_cvsup -q -c ru,de`
then
echo "Running cvsup...(src, doc)"
cvsup -g -L 2 -h $SERVER /root/cvs-supfile
else
echo "Oooops! There's a problem" 1>&2
exit 1

fi

# Before this you have to run:
# portsnap fetch && portsnap extract
echo "Updating ports tree...(/usr/ports)"
cd /usr/ports
portsnap fetch
portsnap update
make fetchindex
portsdb -u

# Also see /var/db/refuse
echo "Buiding docs..."
cd /usr/doc
cp Makefile.orig Makefile
make install > /dev/null


echo "The following ports need upgrading: "
portversion -l "<"


echo "DONE. Finished at `/bin/date`."
echo "=========================================

This script will NOT upgrade your ports!
Manually run:
(Do NOT forget to read /usr/ports/UPDATING before!)

portupgrade -varR

Only sources download:

portupgrade -aFrR

Tip: To delete unused downloaded sources run:

portsclean -D

========================================="
exit

Ура! Вече не е проблем да поддържаме системата up-to-date.
След като се стартира скрипта, той подсказва по-нататък как да се процедира.

Забележка 1: Не случайно в края на скрипта отпечатвам съобщение да се прочете /usr/ports/UPDATING. Това често се забравя и се допускат нелепи грешки. Ето пример:

===> kdelibs-3.5.0 conflicts with installed package(s):
kdebase-3.4.3_1

They install files into the same place.
Please remove them first with pkg_delete(1).
*** Error code 1

Stop in /usr/ports/x11/kdelibs3.
*** Error code 1

В новата версия на kdelibs има сменени пътища на някои библиотеки и portupgrade няма да се справи. Съобщението Please remove them first with pkg_delete(1) е вярно, но не и достатъчно. Целия алгоритъм в случая е описан в UPDATING файла. Намерете го:

cat /usr/ports/UPDATING |grep -B 2 -e "AFFECTS\:.*kdebase.*" |less

Ориентирайте се по датата(най-близката) и научете C, помага при разгадаването на съобщенията за грешка.
Друг проблем, който иска повече познания е следния:

===> Configuring for libbonobo-2.6.2
checking for a BSD-compatible install... /usr/bin/install -c -o root -g wheel
checking whether build environment is sane... yes
checking for gawk... no
checking for mawk... no
checking for nawk... nawk
checking whether gmake sets $(MAKE)... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for perl... /usr/bin/perl
configure: error: XML::Parser perl module is required for intltool

Тук нещата са завоалирани. Aко караме по стандартната процедура е редно да проверим дали е инсталиран такъв parser.

pkg_info |grep parser
bison-1.75_2,1 A parser generator from FSF, (mostly) compatible with Yacc
expat-2.0.0_1 XML 1.0 parser written in C
jade-1.2.1_9 An object-oriented SGML/XML parser toolkit and DSSSL engine
libxml2-2.6.23_1 XML parser library for GNOME
p5-XML-Parser-2.34_2 Perl extension interface to James Clark's XML parser, expat

Ами този последния може би е подходящия, но за бога той съществува! Лекарството е преинсталиране!

portupgrade -r -f p5-XML-Parser

Всяко правило си има изключение.
Забележка 2: portupgrade -varR не винаги минава гладко! Понякога ни напомня, че трябва да се пусне pkgdb -F. Въпросите, които задава pkgdb -F са трудни и затова ще ги илюстрирам с пример:

# pkgdb -F
---> Checking the package registry database
Stale dependency: digikam-0.5.1 -> openldap-client-2.1.23
(net/openldap21-client):
open-motif-2.2.2_2 (score:23%) ? ([y]es/[n]o/[a]ll) [no]
New dependency? (? to help):
Skip this? ([y]es/[n]o/[a]ll) [yes]


Какво значи това? Ами няма инсталиран openldap-client-2.1.23! Опитва се да намери "нещо подобно" с не много добър успех както се вижда - score: 23%. Ако обаче резултата е повече от 70% изберете yes! Иначе лекарството е:

# cd /usr/ports/net/openldap21-client
# make install && make clean


Съвета ми е: не бързайте с отговорите! Правете провреки. Ето и друг пример:

# pkgdb -F
---> Checking the package registry database
Stale dependency: Mesa-3.4.2_2 -> fontconfig-2.2.0 (x11-fonts/fontconfig):
New dependency? (? to help): ?
[Enter] to skip, [Ctrl]+[D] to delete, [.][Enter] to abort, [Tab] to complete


Хммм. Я бързо една справка:

# pkg_info -I fontconfig\*

Е? Какъв е резултата? Ако има инсталиран fontconfig, коя версия е? Ако сте доволен от отговорите на зададените въпроси посочете fontconfig-2.2.0. Ако го няма - инсталирайте. Think!

До тук с "лошите" страни на portupgrade. Една нова възможност, която научих наскоро е да накарам portupgrade да използва pakages вместо ports при update. Така избягвам компилацията на големи пакети, примерно на OpenOffice, който е инсталиран като:

pkg_add -r openoffice.org

FreeBSD не се "бърка" при инсталирането и на packages, и на ports! За да бъдем още по-бързи в .cshrc (или .bashrc, зависи какъв shell се ползва) добавяме:

# Edit this when switch to next STABLE (see cvs-supfile)
setenv PACKAGESITE ftp://bg.freebsd.org/pub/FreeBSD/ports/i386/packages-6-stable/Latest
setenv PKG_SITES ftp://bg.freebsd.org/pub/FreeBSD/ports/i386/packages-6-stable/Latest

Това е сървъра - "ФЮТ". Много ме кефи името!
Параметрите за update са следните:

portupgrade -varRPP

Идва ред на оптимизацията на ядрото. Как се прави ново ядро? Ето подготовката:


# cd /usr/src/sys/i386/conf
# mkdir /root/kernels
# cp GENERIC /root/kernels/NEX_KERNEL
# ln -s /root/kernels/NEX_KERNEL


Преди да се захвана с ядрото оптимизирам малко компилатора. Добaвям типа на процесора(Duron 1.3G) в /etc/make.conf

CPUTYPE?=k7

и започвам с редакцията на параметрите на ядрото (моето съм го кръстил NEX_KERNEL). Аз лично махам всичко, което не ми е нужно на първо четене. После добавям параметрите за оптимизация, в случая:


machine i386
cpu I686_CPU
ident NEX_KERNEL
makeoptions COPTFLAGS="-O2 -pipe -funroll-loops -ffast-math"

options SCHED_ULE # NEW scheduler instead of SCHED_4BSD



Най-накрая слагам допълнителните неща:

# Better console
options VESA
options SC_PIXEL_MODE

# Security: PF
device pf #PF OpenBSD packet-filter firewall
device pflog #logging support interface for PF
device pfsync #synchronization interface for PF

# Traffic bandwidth( to test it use pchar, iperf )
options ALTQ
options ALTQ_CBQ # Class Bases Queueing
options ALTQ_RED # Random Early Detection
options ALTQ_RIO # RED In/Out
options ALTQ_HFSC # Hierarchical Packet Scheduler
options ALTQ_CDNR # Traffic conditioner
options ALTQ_PRIQ # Priority Queueing


Хайде да направим новото ядро:

cd /usr/src
make buildkernel KERNCONF=NEX_KERNEL
make installkernel KERNCONF=NEX_KERNEL

За да използвам pf добавям в /etc/rc.conf

## My firewall will needs this
# То read logs use: tcpdump -n -e -ttt -r /var/log/pflog > /var/log/pflog.txt
pf_enable="YES" # Enable PF (load module if required)
pf_rules="/etc/pf.conf" # rules definition file for pf
pf_flags="" # additional flags for pfctl startup
pflog_enable="YES" # start pflogd(8)
pflog_logfile="/var/log/pflog" # where pflogd should store the logfile
pflog_flags="" # additional flags for pflogd startup

## ...and to be a getaway
gateway_enable="YES" # Enable as LAN gateway

## Better console resolution
allscreens_flags="-g 100x37 VESA_800x600"


и в /etc/pf.conf (Скоро ще публикувам и специална тема за PF и traffic bandwidth)


ext_if="xl0"

altq on $ext_if priq bandwidth 150Kb queue { q_pri, q_def }
queue q_pri priority 7
queue q_def priority 1 priq(default)

pass out on $ext_if proto tcp from $ext_if to any flags S/SA keep state queue (q_def, q_pri)

pass in on $ext_if proto tcp from any to $ext_if flags S/SA keep state queue (q_def, q_pri)


Край! Готово! След reboot трябва да имаме перфектна FreeBSD основа. Надграждането на системата вече е в наши ръце. Ето как процедирам аз, когато добавям приложение. Преди всичко трябва да го намеря в CVS дървото.

# cd /usr/ports
# make search key=<ключова дума> |less

или

# make search name=<името на приложението>

След като го намеря, инсталирам:

# cd /<пътя до приложението>
# make install && make clean


И така, малко по малко изграждам моя workstation инсталираните приложения са достатъчно оптимизирани, a имам и начин за лесен update. Искам да кажа, почти лесен. Понякога някои приложения ги инсталираме с определени опции. Например Apache, да може да работи с subversion.

cd /usr/ports/www/apache20
make install WITH_BERKELEYDB=db42 && make clean

cd /usr/ports/devel/subversion
make install -DWITH_MOD_DAV_SVN && make clean

Ако машинално напишем (или се подведете от това, което съм писал по-горе хехехе):

portupgrade -varR

Всички приложения ще се ъпграйднат с параметрите, които са по default. Помислено е за всичко.

emacs /usr/local/etc/pkgtools.conf

Ориентирам се отново по коментарите и примерите. В случая:

## Apache, Subversion
MAKE_ARGS = {
'www/apache20' => 'WITH_BERKELEYDB=db42',
'devel/subversion' => 'WITH_MOD_DAV_SVN=1'
}

Приложенията се изброяват със запетая, а параметрите им са разделени с интервал. Relax - FreeBSD работи вече за мен.

Забележка 3: За да компилирам цялата система използвам следната процедура:

cd /usr/src
make buildworld (ще трябва доста да изчакате!)
make buildkernel KERNCONF=NEX_KERNEL
make installkernel KERNCONF=NEX_KERNEL
shutdown now
-> ще направи системата в "single user mode". Още малко усилия:
# fsck -p
# mount -u /
# mount -a -t ufs
# swapon -a

-> Знаете какво е CVS, нали?
mergemaster -p
make installworld
mergemaster

shutdown -r now

Когато се преминава от една версия към друга естествено трвбва да се премахнат старите весии на библиотеките и на файловете от /lib. За целта:

make delete-old
make delete-old-libs



Това в всичко пиятели. Ще правя update на статията. Следете я!

Friday, August 05, 2005

Невъзможните наши любови

   Усещам погледа ти. Познавам добре кафявите очи изпълнени с вярност. Колко хубаво е да си край мен. Не смея да се обърна, не искам да те смутя. Знам че ме обичаш, знам че сме обречени да бъдем заедно. Обещах да те направя щастлива, когато те срещнах. Помниш това, нали?
   Не, няма да спра да те галя. Ще давам всичко от себе си, искам ти да си най-добре. Старая се да ти се харесам. Докосванията те правят тиха и мързелива. Леко притваряш очи. Мисли си за мен, моля те. За нашата среща ли? Малка, нежна и наивна. Такава те помня, мила. Ти се приближи и ние се докоснахме. Колко много неща могат да се усетят. Искрите прескачат и хората изгарят.
   Колко си хубава! Не мога да се откъсна. Студено е, приближи се до мен. Доближавам устни до ухото ти и споделям. Съгласна ли си? Да, ти би тръгнала навсякъде с мен, ти ме подкрепяш безрезервно. Това е любовта - прави ни едно цяло. Няма да ни е лесно. Ще се борим с живота, ще се сръжаваме рамо до рамо, ще вървим напред смело и безразсъдно. Човек е силен, когато работи за любимия.
   Тръпна и аз. Роси, ти си моето любимо куче. Обичам те!

Wednesday, August 03, 2005

C code indent

Програмите имат много лица. Още преди да почна да се знимавам по-сериозно с писането на С код, реших да проверя дали има начин автоматично да си подравнявам кода. За мен лично е важно програмата, която преглеждам да е в "удобен" за мен стил. Разгадаването на логиката идва на втори план.
Решението е indent! Как става това? Как се дефинират правилата за подравняване?
В home директорията трябва да се дефинира .indent.pro, който е ресурсен файл за indent. В него се поставят и желаните правила. Наложи ми се доста да експериментирам преди да налучкам "моя" стил (между другото, Java доста повлия на вкуса ми). По метода проба-грешка резултата е:

Преди:


void printpathto( ino_t this_inode )
{
ino_t my_inode ;
char its_name[ BUFSIZ ];

if ( get_inode("..") != this_inode )
{
chdir( ".." ); /* up one dir */
// some comment
inum_to_name(this_inode,its_name,BUFSIZ);

my_inode =get_inode( "."); /* print head */
printpathto( my_inode); /* recursively */
printf("/%s", its_name ); /* now print */
/* name of this */
}
}

След:


void printpathto(ino_t this_inode) {
ino_t my_inode;
char its_name[BUFSIZ];

if (get_inode("..") != this_inode) {
chdir(".."); /* up one dir */
// some comment
inum_to_name(this_inode, its_name, BUFSIZ);

my_inode = get_inode("."); /* print head */
printpathto(my_inode); /* recursively */
printf("/%s", its_name); /* now print */
/* name of this */
}
}


Ето правилата, дефинирани в моя .indent.pro

/* indentation */
--indent-level 4
--brace-indent 4
--continuation-indentation 2
--parameter-indentation 0
--case-brace-indentation 0
--case-indentation 4
--declaration-indentation 4
--struct-brace-indentation 4
--line-length 80
--tab-size 4
--dont-line-up-parentheses
--continue-at-parentheses

/* spacing */
--dont-break-procedure-type
--space-after-cast
--no-space-after-function-call-names
--no-space-after-parentheses
--no-tabs
--space-after-for
--space-after-if
--space-after-while
--space-after-cast
--space-special-semicolon
--dont-break-function-decl-args

/* misc */
--format-all-comments
--no-comment-delimiters-on-blank-lines
--break-before-boolean-operator
--comment-indentation 50

/* blank lines */
--blank-lines-after-declarations
--blank-lines-after-procedures
--blank-lines-before-block-comments
--blank-lines-after-commas

/* braces */
--braces-on-if-line
--braces-on-struct-decl-line
--cuddle-do-while
--cuddle-else
-brf /* brace on function line */

/* misc */
-ppi 3


Само да кажа, че понякога е добре да няма подравняване! За да изкючите местата в кода, където не искате да влиза indent ги обграждаите с т.н.control comments

/* *INDENT-OFF* */
< Част, която не искате да се форматира >
/* *INDENT-ON* */



Забележка: За повече подробност можете да погледнете тук

Забележка2: А за Eclipse има много подходящ plugin Astyle

algorithms (1) cpp (3) cv (1) daily (4) emacs (2) freebsd (4) java (3) javascript (1) JSON (1) linux (2) Lisp (7) misc (8) programming (16) Python (4) SICP (1) source control (4) sql (1) думи (8)