2010-02-17

Linux сервер дээр SVN суулгах

SVN (Subversion) бол багаараа хамтарч төсөл гүйцэтгэхэд тун хэрэгтэй зүйл. Энд тохируулах үйл явцыг бичлээ. Хэрвээ та Debian юмуу Ubuntu хэрэглэж байгаа бол энд хэрэгтэй Apache HTTPd, Subversion зэргийг суулгах нүд эрмэхийн төдий амар зүйл тул суулгах хэсгийг алгасья. Доорх үйл явцад SVN-рүү HTTP протокол ашиглаж холбогдохоор бодож хийе:
# mkdir /subversion
# chown www-data:www-data /subversion
# su www-data
$ svnadmin create /subversion
$ exit
# htpasswd -c /subversion/htpasswd dagvadorj
# htpasswd /subversion/htpasswd oyunjargal
Дараа нь /etc/apache2/httpd.conf файлд дараах мөрүүдийг оруулна:
 <location /svn>
   DAV svn
   SVNPath /subversion
   AuthType Basic
   AuthName "Dagvadorj Subversion Repository"
   AuthUserFile /subversion/htpasswd
   Require valid-user
 </location>

2010-02-12

Spoj-ийн бодлого бодов

spoj.pl сайт ч гоё шүү. Мэдээд удаж байгаа боловч ёр бодлого бодож амжихгүй юмаа. Өнөөдөр ADDREV кодтой бодлогыг бодлоо. Өгөгдсөн тоонуудыг тонгоргож хөрвүүлээд хооронд нь нэмээд, нийлбэрээ бас тонгоргох юм байна. Тоонуудтай бөх барилдаж байгаа юм шиг болчлоо. :D Мартагдах гээд байхаар нь Python-оор бодлоо. Бодолт нь дор байгаа:


def reversify(num):
 p = str(num)
 s = ""
 i = len(p)-1
 while i >= 0:
  s += p[i]
  i = i - 1
 return int(s)

k = raw_input()

h = []

for j in range(int(k)):
 inp = raw_input()
 l = inp.split(" ")
 h.append(l[0])
 h.append(l[1])

u = 0

while u < 2*int(k):
 print reversify(reversify(h[u]) + reversify(h[u+1]))
 u = u + 2

Гэм нь Python-оор бодсон бусад бодолтуудын хажууд жаахан удаан ажилладаг боллоо. Илүү хурданг хийе гэхээр манай хүн унтья, орой болчлоо гээд байхын. Маргааш ажилтай унтья дөө.

2010-01-04

Энэ вэбийг синхрон бишээр авья

2, 3 жийлийн өмнө хүн болгоны магтан ярьж байсан зүйлсийг одоо л би ярих гэж байна даа. Төдий чинээ хоцорч яваа минь энэ биз дээ. Юуг магтаад байсан бэ гэхээр гэдэг технологи. Энэ нь Asynchronous JavaScript and XML гэсэн үгийн товчлол, гэсэн хэдий ч сүүлийн үед бас Ajax гээд товчлол биш шинэ үг маягаар хэрэглэх болсон нь энэ технологийг шүтэн хэрэглэгчдийн анархи биз. Санаа нь вэб хуудас ачааллаж дууссаны хойно бүхэл бүтэн шинэ хуудас ачаалахгүйгээр сервер дэх програмыг ажиллуулан үр дүнг буцааж аван өмнө ачаалласан хуудсанд харуулна гэдэг дээр тогтож байна. Энэ технологийн одууд гэвэл олон байна, жишээ нь: Google Maps, Writely (Google Docs болсон), GMail гээд олон байна. Тухайлбал, Google Maps хиймэл дагуулаас авсан жижгээс томруугаа 13 ширхэг том зураг олон хуваагдсан байгаагийн аль нэг ачаалласан зургийн зөвхөн хэрэглэгчийн фокуст байгаа хэсгийг л ачааллан харуулж, хэрэглэгч хулганаар зургийг чирэхэд зөвхөн шинэ фокус дахь зургуудыг серверээс нэмж ачааллах гэсэн замаар хурдан ажиллаж байна.

Яг тэр 2, 3 жилийн өмнө нь AJAX стандартчилагдаж байхад нь вэбийн стандандартын W3C-гийн сайтруу орж үзэж байгаад XMLHttpRequest обьектийг хэрэглэж үзэж билээ, ид шид юм шиг л санагдаж байсан. Гэхдээ JavaScript дорвитой хэрэглэхээс хальширч байсан учир тэгэсгээд орхисон юм. Учир нь нэг бичсэн код туршиж байсан вэбийн хөтөч програм дээр ажилаад өөр хөтөч дээр ажиллахгүй гэх мэт олон садаа байлаа. Мөн AJAX-д хамгаалалтын асуудлууд байлаа.

За тэгээд л вэб хийхдээ дандаа сервер талтай код бичээд л байлаа. Тэгсэн мөнгө бүхнийг өөрчлөнө гэгчээр санхүүгийн хямралд ороод ирэхээр яахын аргагүй нэгэн бүртгүүлсэн ажлынхаа ажил олгогчид нэг хоногийн дотор AJAX хэрэглэдэг үнэ хаялцах жижигхэн хэрэглээний програм бичиж үзүүлье гээд хэлчихлээ.

Харин энэ үед AJAX вэб хуудас хийх харьцангуй асар болсон байлаа. Ингээд feeditor.com/bidding хэрэглээний програмыг бичлээ. Хэрэглэсэн технологиудын хувьд гэвэл:

  • Java (Java 1.6; Tomcat 5.5)
  • DWR (Direct Web Remoting)
  • MySQL
  • Dojo Toolkit
  • Scriptaculous
  • Prototype

Ингээд кодуудыг (war + build.xml) нь эндээс татаж авч болно шүү. Харин эндээс өгөгдлийн сангийн кодыг авч болно.

Надаар кодуудыг нь тайлбарлуулсан бичлэг бичүүлмээр байвал бичлэгт санал сэтгэгдэлээ бичээрэй.

2009-12-25

Сайн тэсвэр хатуужилтай болмоор юм байна даа

Сүртэй аймар тэсвэр хатуужил бишээ, юмыг өөр зүйлд сатаарахгүй хянамгай уншиж дадах хэрэгтэй юм байна. Саяхан хийсэн хэрэглээний програмыг (feeditor.com) хийхэд хэд хэдэн стандартын бичиг баримт, мөн төчнөөн RFC унших хэрэгтэй боллоо. Зарим нэгнээс нь ойлгож мэдсэнээ тоймлож блогтоо тавихыг бодноо.

Ассемблэр дээр програм бичих

Өчигдөр CodeWarrior татаж авлаа, үнэхээр лаг юмаа хэхэ. Ингээд доор сарыг аваад тухайн сар хэдэн хоногтойг A аккумляторт буцаадаг програс бичлээ. LCD цаг хийсэн лабораторт хэрэг болсон юм л даа. Илүү хурдан ажиллах кодны санаа байвал хуваалцаарай хүмүүсээ.
MY_EXTENDED_RAM: SECTION
YEAR        DS.w 1
MONTH       DS.b 1
DAY         DS.b 1

MyCode:     SECTION
main:
_Startup:
Entry: 
            LDD    #2006
            STD    YEAR
            LDAA   #4
            STAA   MONTH
            LDAA    #5
            STAA   DAY
            JSR   DAYBYMONTH
            SWI

DAYBYMONTH:             ; returns # of days in ACC A
            LDAB   MONTH    
            CMPB   #2      
            BEQ   TSTLEAP  
                       
            CMPB   #8       
            BGE   AUTUMN   
            LDAA   MONTH     
            ASRA 
            BCC     D30
            LDAA    #31      
            RTS
AUTUMN:     
            LDAA   MONTH     
            ASRA 
            BCS     D30
            LDAA    #31
            RTS
D30:        
            LDAA    #30
            RTS
TSTLEAP:
            LDD   YEAR
            LDX   #4
            IDIV
            TBNE   D,NOTLEAP
            LDAA   #29
            RTS
NOTLEAP:
            LDAA   #28
            RTS

2009-11-28

Монгол хэл дээрх wikibook төслийг устгах гэж байна

wikibook төсөл нь wikipedia-гийн дүү төсөл бөгөөд хэрэглэгчдэд нээлттэй эх (дан ганц програм хангамж биш) дээр тулгуурласан ном хамтарч бичих боломж олгоно. Энэхүү төсөл нь дэлхийн олон хэл дээр байдаг ба амжилттай хэргэжиж олон ном бий болж хүн бүр үнэ төлбөргүй уншиж болно. Харин энэ төслийн Монгол хэл дээрх төсөл устгах гэж байна. Учир нь манайхнаас хэн ч юу ч бичиж эхлүүлэхгүй байжээ. М.Эрдэнэчимэг багшийн орчуулсан "Open Source" номын өмнөх үгийг уншиж байлаа. Тэнд энэ орчуулгаа mn.wikibooks.org сайтад тавинаа гэж байна, тэгэхээр нь гоё санаа төрөөд энэний өмнө бичсэн "Линүксийн цөмийн програмчлал" бичлэгээ бас тэнд тавиад аажим аажимаар ном болгьё гэж бодлоо. Тэгээд сайтанд бүртгүүлээд шинэ хуудас нээх гэсэн болсонгүйээ. Хэн ч ямарч өөрчлөлт гаргаж болохгүй юм байна. Учир нь энэ оны 4-р сарын байдлаар Монгол хэл дээрх төслийг хаахаар болсон байна. Бүгдээрээ энэ талаар хамтарч үгээ хэлж байгаад буцааж нээх хэрэгтэй байна. Бас чадах чинээгээрээ ном нэмж байх хэрэгтэй байна. Бид чинь бүхэл бүтэн нэг үндэстэн улс шүү дээ.

2009-11-27

Линүксийн цөмийн програмчлал

Юникс (Unix) үйлдлийн систем нь маш их алдар хүндийг олсон боловч академээс гадуур хэрэглэхэд маш их өндөр өртэгтэй худалдагддаг байсан бөгөөд лиценз нь AT&T, Novell зэрэг томоохон компаниудын гар дамждаг байж л дээ. Тиймд хакерууд нээлттэй эх буюу үнэгүй тараагддаг "Юникстэй төстэй" (Unix-like) үйлдлийн системүүдийг хийж эхэлжээ. Ингээд Minix, BSD, Linux, Darwin гэх мэт үйлдлийн системүүд гарч ирлээ. Эдгээрээс Линүкс (Linux) нь нээлттэй эхийн хамт олны дунд маш их амжилтийг олж хөгжүүлэгдэж иржээ. Анхлан Линүкс үйлдлийн системийн цөмийг бичсэн, тухайн үедээ Финланд улсад оюутан байсан Лайнус Тровалдс нь одоог хүртэл Линүксийн цөмийг хөгжүүлэх явцад идэвхтэй оролцсоор байгаа юм.

Линүксийн хөгжүүлэлтэнд бусад нээлттэй эхийн хөгжүүлэлтийн үйл явцын адил байнгын оролцогч цөөн тооны мэргэжилийн хакерууд байх ба илүү олон тооны мэргэжилийн болон сонирхогч програмистууд оролцоно. Гэхдээ эдгээр нь Линүксийн цөм буюу kernel-ийг програмчлан нээлттэй эх кодыг нь kernel.org вэбсайтаар тараана. Үүн дээр үндэслээд хувь хүмүүс, албан байгууллагууд, ашгийн бус байгууллагууд, товчхондоо бол хүссэн хэн боловч өөрийн гэсэн Линүксийг бий болгон хэрэглэж болно. Эдгээрийн жишээ гэвэл: Red Hat Enterprise Linux, Mandriva, Debian, Ubuntu, ArchLinux, Puppy Linux, Knoppix, Damn Small Linux, Backtrack гээд өчнөөнийг дурдаж болно.

Цөмийг нь шинээр суулгахдаа өөрчилж болно. Энд нэгэн жишээг авч үзье.

Эхлээд зарим нэгэн юмыг тодорхой болгъё:

Програм нь хэрэглэгчийн түвшинд ажиллаж болно, эсвэл системийн түвшинд ажиллаж болно. Тиймч учраас хэрэглээний програм болон систеийн програм гэж нэршил байдаг боловуу. Хэрэглээний програм нь системийн дуудлага (system call) ашиглан системийн хэсэг болон техник хангамжтай харьцана. Жишээ нь энгийн C програманд fopen, printf, scanf зэрэг коммандууд нь цаанаа open, write, read системийн дуудлагуудыг ашиглан файл нээх, дэлгэцэнд бичих, дэлгэцнээс үсэгт авах зэрэг үйлдлийг хийнэ.

Юниксийн төрлийн үйлдлийн системүүдэд top гэсэн комманд ашиглаж санамжинд суурьлагдсан процессуудыг харж болдог билээ. Энэ нь Виндовс үйлдлийн системийн Task Manager гэсэн үг л дээ.

Тэгэхээр нэг ийм юм хийж туршиж үзье; системийн дуудлага ашиглан ажилж буй процессийг top дээр харагддаггүй болгодог.

Би Дэбиан (Debian) үйлдлийн систем дээр ажиллаж байгаа. Ингээд доорх коммандуудаар зарим програмуудыг татаж авья. # гэсэн тэмдэг нь root хэрэглэгчээр орсон гэсэн үг. Ер нь бол бүх юмаа тэгж хийсэн.

Програмуудынхаа листийг шинэчилэнэ:

# apt-get update

Линүксийн цөмийг татаж авна. Миний цөм Linux kernel 2.6.26 учир мөн адил цөмийг татна. Хэрэв таны ажилж буй Линүксийн цөм нь өөр бол тохирох цөмийг татаж авна уу.

# apt-get install linux-source

Цөмийг суулгахад хэрэглэгдэх багцыг татаж авна.

# apt-get install kernel-package

Мөн доорх туслах багажуудыг татаж авна:

# apt-get install fakeroot
# apt-get install libncurses5-dev
Ингээд хэрэгтэй зүйлсээ татаад суулгачихлаа. Линүксийн цөмийн эх код /usr/src/ хавтасанд хадгалагдсан байгаа. Түүнийг задална:
# tar xjvf linux-source-2.6.26.tar.bz2
# cd linux-source-2.6.26
/usr/src/linux-source-2.6.26 хавтас үүсэх бөгөөд энд Линүксийн хэрэгтэй файлууд бий. Одоо бидэнд тохиргооны .config файл хэрэгтэй. Энэ файлын тусламжтайгаар үйлдлийн систем маань ямар, ямар файл системийг дэмжих үү, ямар ямар техник хангамж дэмжих вэ гэдгийг тохируулж болно. Та өөрийн урьтаж бэлдсэн .config файлыг хэрэглэж болно, эсвэл үйлдлийн системийн /boot/ хавтасанд орших config-2.6.26-x-xxx файлыг хуулж тавиад нэрийг нь .config болгож өөрчилсний дагуу хэрэглэж болно.
mv /boot/config-2.6.26-2-686 /usr/src/linux-source-2.6.26/.config
Одоо кодоо өөрчилж эхэлье. Туршилтаа одоо илүү нарийн дэтальчилж доорх шатуудад хуваая:
  1. Процессийн бүтцэд visible гэдэг шинж чанар өгөөд анхны утгыг 1 гэж өгье
  2. Тодорхой нэгэн ажилж буй процессийн pid нь өгөгдсөн байхад visible утгыг нь 0 эсвэл 1 болгодог системийн дуудлага хийе
  3. Ажилж буй процессуудын visible утгуудыг нь шалгаад 1 байвал л top дээр харагддаг болгьё
  4. Хэрэглээний түвшинд ажиллаад шинэ системийн дуудлагыг ашигладаг шалгах програм бичье
Доорх алхамууд дээр /usr/src/linux-source-2.6.26 хавтасан дотор ажиллана. Жишээ нь include/linux/ гэдэг нь үнэндээ /usr/src/linux-source-2.6.26/include/linux/ хавтас юм. Харин / тэмдэгтээр эхэлсэн бол Линүкс үйлдлийн системийн үндсэн (/) файлаас эхэлж байна гэж ойлгоно уу.

1-р шатны ажилаа хийе. Процессийн бүтэц нь include/linux/sched.h файлан доторх "struct task_struct {}" тодорхойлолтонд багтана. Тэр бүтцийн тодорхойлолтын хамгийн дор нь "int visible;" гээд нэмнэ. Ингэснээр доорх шиг харагдах болно.

struct task_struct {
    volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
    void *stack;
    atomic_t usage;
    unsigned int flags;
        ...
        int visible;
};
Шинэ процесс үүсэхэд kernel/fork.c файлан доторх copy_process() функц хэрэглэгдэнэ. Тэнд visible утгаа 1 гэж зааж өгнө. Ингэснээр доорх шиг харагдах болно.
static struct task_struct *copy_process(unsigned long clone_flags,
     unsigned long stack_start,
     struct pt_regs *regs,
     unsigned long stack_size,
     int __user *child_tidptr,
     struct pid *pid)
{
    ...
    struct task_struct *p;
    ...
    p = dup_task_struct(current);
    p->visible = 1;
    ...
}

2-р шатны ажилаа хийе.

  • Интэл (Intel) чиптэй компьютерт arch/x86/kernel/syscall_table_32.S файлд доорхыг нэмнэ.
    long sys_set_visibility
  • include/linux/syscalls.h файлд системийн дуудлагын прототипийг нэмнэ.
    asmlinkage int sys_set_visibility(pid_t pid, int flag);
  • arch/x86/include/asm/unistd_32.h файланд системийн дуудлагын бүртгэлийг хамгийн сүүлийн бүртгэлийг нэгээр нэмэгдүүлж оруулна.
    #define __NR_...            332
    #define __NR_set_visibility 333
    
  • mycall хавтасыг үүсгээд set_visibility.c файлыг үүсгэж доорхыг нэмнэ.
    #include <linux/kernel.h>
    #include <linux/sched.h>
    asmlinkage long sys_set_invisibility(pid_t pid, int flag) {
    
         struct task_struct *task = &init_task;
     
         do {
             if(task->pid == pid){
                  task->visible = flag;
                  return 0;
             }
         } 
         while ( (task = next_task(task)) != &init_task );
         return -1;
    }
    
  • Эцэст нь цөмийг компайл хийхэд ашиглагдах Makefile-уудад өөрчлөлтүүдээ мэдэгдэнэ. /usr/src/linux-source-2.6.26/Makefile файлд доорхыг нэмнэ.
    core-y := ... mycall/
    
    mycall/Makefile үүсгэж доорхыг нэмнэ.
    obj-y := set_visibility.o
    

3-р шатны ажилаа хийе. Ажиллаж байгаа хэсгүүдийн /proc хавтасанд үүссэн мэдээллийг авдаг хэсгийн код нь fs/proc/base.c файлын proc_pid_readdir() функцэнд байна. Доорх мэдээллийг нэмж бичнэ:

...
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
    ...
    struct tgid_iter iter;
    ...
    iter.task = NULL;
    ...
    for (iter = next_tgid(ns, iter);
        iter.task;
        iter.tgid += 1, iter = next_tgid(ns, iter)) {
            if (iter.task->visible == 1) {
                filp->f_pos = iter.tgid + TGID_OFFSET;
                if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
                    put_task_struct(iter.task);
                    goto out;
                }
            }
     }
     ...
}
...

4-р шатны ажилаа хийе. Шалгах програмыг (test.c) бичээд Desktop дээр хадгалаад компайл хйинэ. test.c

#include <sys/unistd.h>
#include <stdio.h>
#define __NR_set_invisibility 328

int main(void) {
    int x,y,z=-1;
    while (1) {
        printf("Hello! You can set visibility of a process with this program.\n");
        printf("Enter '<pid> <flag>' and hit! : Process ID, : 0 to make invisible ");
        printf("and 1 to make it visible again.\n");
        scanf("%d %d", &x, &y);
  
        z = syscall(__NR_set_invisibility, x, y);  
        if (z == 0) {
             printf(">>> Your modification was successful! Please review with 'top'!\n");
        } else {
             printf(">>> Error! There was a problem. Most probably, the process with this pid doesn't exist!");  
        }
    }
}
Дээрх кодоо компайл хийгээд програм болгочихье.
/home/dagvadorj/Desktop # gcc test.c -o test
Ингээд Линүкс цөм дээр хийх өөрчлөлтүүдээ хийж дууслаа. Одоо ингээд Линүкс цөмөө компайл хийе. Эхлээд цөм дээрээ тохиргоогоо хийнэ. Энд Линүксийн ямар техник хангамж, файлын систем дэмжих вэ гэдгийг тохируулж болно.
# cd /usr/src/linux-source-2.6.26
# make menuconfig
Жич: Дараа дараагийн алхмуудын дараа шинэ Линүксийн үйл ажиллагаанд ямарваа нэгэн алдаа гарвал хуучин тохиргоогоо make oldconfig гэсэн коммандаар сэргээж болно. Дараагийн алхамд хуучин компайлаас үлдсэн зүйлийг устгана.
# make-kpkg clean
Жич: Анх удаа компайл хийж буй тохиолдолд ингэж хийх шаардлагагүй гэдгийг анхаарна уу. Дараа нь Линүксийг компайл хийнэ. Доорх нь 20 минутаас 1 цаг үргэлжилж болно. Энэ хугацаа нь Линүксийн ямар техник хангамж, файл систем дэмжиж ажиллахаар тохируулагдсанаас шалтгаална. Илүү олон зүйл дэмжвэл илүү удна гэсэн үг. "harbin" гэдэг үгийн оронд таны өөрийн дурын нэр байж болно. Монгол хэл дээрх анхны сонин Харбинд хэвлэгдэж байсан, тэнд Гадаад Монголын мэргэжилтэн гар бие оролцож байсныг санан ийн нэрлэсэн билээ.
# fakeroot make-kpkg -initrd -append-to-version=-harbin linux_image linux_headers
Ингэсний дараа /usr/src хавтасанд 2 ширхэг .deb өргөтгөлтэй файл үүснэ. Тэдгээрийг доорх коммандуудаар суулгана.
# dpkg -i linux-image-2.6.26-harbin-2.6.26-harbin-10.00.Custom_i386.deb
# dpkg -i linux-headers-2.6.26-harbin-2.6.26-harbin-10.00.Custom_i386.deb
/boot хавтасанд Линүкс асахад хэрэгтэй initrd.img-2.6.26-harbin, vmlinuz-2.6.26-harbin ба бусад файлууд үүссэн байна. Зарим тохиолдолд /boot/initrd.img-2.6.26-harbin файл үүсээгүй байж болно. Энэ үед:
mkinitramfs -o /boot/initrd.img-2.6.26-harbin
/boot/grub/menu.lst файлд доорх эхлүүлэх сонголт нэмэгдсэн байгаа.
title   Debian/GNU Linux, kernel 2.6.26-harbin
root    (hd0,1)
kernel  /boot/vmlinuz-2.6.26-harbin root=/dev/hda2 ro quiet
initrd  /boot/initrd.img-2.6.26-harbin
Одоо компьютерээ reboot хийхэд эхлэх сонголт дээр harbin гарч ирэх бөгөөд сонгоод орно уу! top програмыг ажиллуулна уу!
# top
Доорх дэлгэц гарч ирнэ: Desktop дээр байгаа test програмыг ажиллуулсны дараа: 1,2,3 бүхий процессууд харагдахгүй байгааг анхаарна уу! За ингээд Линүксийн цөмийг жаахан ч гэсэн өөрчилөөд ажиллуулж үзлээ.