Ubuntu 12.04 64 bit LTS


* git 을 설치


* server가 실행될 때 항상 실행되도록 Upstart Script 등록

/etc/init/<script name>.conf


<참고>

xxxx.conf : upstart script

xxxx.override : 기존의 xxxx.conf를 override함.


* /etc/init/git-daemon.conf 작성 (git project directory = /work/.prjrepo/)


start on runlevel [2345]                                                                        

stop on runlevel [!2345]                                                                        


expect fork                                                                                     

respawn                                                                                         


exec /usr/bin/git daemon --user=gitro --group=gitro --reuseaddr --base-path=/work/.prjrepo/ /work/.prjrepo/


* export하고자 하는 git repository안에 magic file인 git-daemon-export-ok 파일 생성 (size 0인 dummy file - 그냥 touch로 생성하면 된다.)


* client에서 test.

git clone git://<host>/<project>

<9418 포트 사용>

'Domain > Linux' 카테고리의 다른 글

[Linux] mmap and memory...  (0) 2013.10.07
CoW(Copy on Write) on ARM  (0) 2013.09.26
atime 대신에 strictatime을 사용하자!  (0) 2013.05.31
[Shell] Variable Name Expansion  (0) 2013.03.28
[Linux][Shell] Cleaning PATH environment variable.  (0) 2011.09.15

Ubuntu의 경우 default mount option이 'relatime'으로 되어 있는데, 이것을 바꾸기 위해서 "mount -o remount,atime,xxxx" 식으로 해도 relatime 에서 atime으로 mount상태가 바뀌지 않는다.

대신 strictatime을 사용하면, 정상적으로 원하는 형태로 mount할 수 있다.

(mount의 man page에 상세하게 설명이 나와있긴 하나... atime이상 동작하지 않는다는 설명은 찾을 수 없었다.)


요점은 atime 대신 strictatime을 사용하라!


Variable operator

Action 

Description 

${varname}

Nonambiguous variable substitution 

Simple variable substitution occurs with the value of varname being substituted

${varname:=value}

Assign a default value for the variable if a value does not exist.

If varname does not have a value or is set to null, then varname is set to value.

Varname is then substituted in the statement.

${varname:+value} 

Utilize value if varname is set 

If the variable, varname, contains a value and is not null, then the alternate value, value, is substituted instead of the value of the variable varname. Otherwise nothing is substituted.

${varname:-value} 

Assign a temporary default value for a variable if one does not exist 

If the variable, varname, contains a value and is not null, then it is substituted; otherwise the value, value, is substituted but is not assigned to varname. (different from = operator)

${varname:?value} 

Issue an error message if the value of variable is not set to any value. 

If the variable, varname, containsa value and is not null, then it is substituted; otherwise an error message containing the value, value, is printed and the Shell exits.

${#varname}
(Korn and Bash only) 

Return the length of the value contains in varname or the number of positional parameters.

If varname is set, the length of the value of varname is returned. If the special variable * or @ is used as varname then the number of positional parameters are returned. 

${varname#pattern}

${varname##pattern}

(Korn and Bash only) 

Substitue varname with pattern removed from the beginning of varname .

If the pattern matches the begining of varname, then pattern is removed from varname. If the # form is used, then the shortest match is removed. If the ## form is used, then the longest match is replaced. 

${varname%pattern}

${varname%%pattern}

(Korn and Bash only) 

Substitute varname with pattern removed from the end of varname. 

If the pattern matches the end of varname, then pattern is removed from varname. If the % form is used, then the shortest match is removed. If the %% form is used, then the longest match is replaced. 

${#arrayname[*]}
(Korn only) 

Substitute the number of elements in the array. 

The number of elements in the array arrayname is substituted. 


<From : UNIX Shell Programming, FOURTH EDITION, LOWELL JAY ARTHUR, TED BURNS - WILEY COMPUTER PUBLISHING>

With using terminal for a long time, PATH variable tends to be longer and longer due to duplicated path.
Here is simple sample script - with Perl - to resolve this.

# remove duplication at give PATH-format-string
unique_path() {
perl -w -e '
    my %path_hash;
    exit unless (defined $ARGV[0]);
    foreach $p (split (/\:/, $ARGV[0])) {
        unless (defined $path_hash{$p}) {
            $path_hash{$p} = 1;
            push @newpath, $p;
        }
    }
    print join ":", @newpath;
' $1
}
...(skip)...
PATH=$(unique_path "$PATH")
...(skip)

Done :-).

This is due to flow control.
C-s and C-q is reserved key sequence for flow control.
So, by disabling it - just type 'stty -ixon' - you can use C-s and C-q key sequence.

Model : HP EliteBook 8530w
Host : Linux hbg683-laptop 2.6.35-24-generic-pae #42-Ubuntu SMP Thu Dec 2 03:21:31 UTC 2010 i686 GNU/Linux

Current state : 'nvidia-xxx' is installed at 'synaptic package manager'. And then driver is updated by 'NVIDIA-Linux-x86-260.19.12.run' installer.
=> visual effect doesn't work.

Actions done : uninstall all 'nvidia-xxx' packages from 'synaptic package manager'. And then install driver by running 'NVIDIA-Linux-x86-260.19.12.run' installer.
=> Some errors are raised. (something like cannot copy xxx-260.19.06 bla... bla...)

Now visual effect works very well!!

This is a kind of reminder.
(On Android)

Source code.

linux/input.h
    struct input_event;
: write 'struct input_event' to input event node.
ex.
    struct input_event ev;
    ...
    write(fd, &ev, sizeof(ev));
    ...

File system

/dev/input/*, /proc/bus/input/*

Touch event 
 

   type  code  value
<common> EV_ABS
EV_ABS
ABS_X
ABS_Y 
<value>
<value> 
Press (or Drag)Release EV_KEY
EV_KEY
BTN_TOUCH
BTN_TOUCH
1
0
<common>  EV_SYN 0 0

Key event

  type code value
Press EV_KEY <key code> 1
Release EV_KEY <key code> 0

Done. 

Sometimes, we want to access framebuffer directly.
Here is template and simple description to do this (on Android  as an example.)
(Note: This is just template. Some modification may be required according to driver.)
(Below way works on Android 2.3 ~ 4.1 emulator by turning off 'Use Host GPU' option at AVD Manager.)

Things used in this example.
(Refer kernel source code for details - comments in code.)
linux/fb.h
    - struct fb_var_screeninfo
        xres, yres, xres_virtual, yres_virtual, xoffset, yoffset, bits_per_pixel
    - struct fb_fix_screeninfo
        smem_len
    - FBIOGET_FSCREENINFO, FBIOGET_VSCREENINFO, FBIOPUT_VSCREENINFO
    - FB_ACTIVATE_NOW, FB_ACTIVATE_FORCE
See fbmem.c as your starting point of source analysis.

...
int                      fd;
struct fb_var_screeninfo vi;
struct fb_fix_screeninfo fi;
void*                    bits;
int                      bpp;    /* byte per pixel */
int                      stride; /* size of stride in pixel */

...
/* Open framebuffer */
if(0 > (fd = open("/dev/graphics/fb0", O_RDWR)) {
    printf("Fail to open fb\n");
    return -1;
}

/* Get fixed information */
if(0 > ioctl(fd, FBIOGET_FSCREENINFO, &fi)) {
    printf("Fail to get fixed info\n")
    return -1;
}

/* Get variable information */
if(0 > ioctl(fd, FBIOGET_VSCREENINFO, &vi)) {
    printf("Failed to get variable info\n");
    return -1;
}

/* Get raw bits buffer */
if(MAP_FAILED == (bits = mmap(0, fi.smem_len,
                              PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))) {
    printf("Failed to mmap fb\n");
    return -1;
}

/* Calculate useful information */
bpp = vi.bits_per_pixel >> 3;
stride = fi.line_length / bpp;

...
/* Getting raw-image snapshot of current framebuffer */
void* curbits; /* current framebuffer raw data */
curbits = (unsigned char*)bits + (vi.xoffset + vi.yoffset*vi.xres_virtual)*bpp;
memcpy(raw_image_buffer, curbits, vi.yres*stride*bpp);

...
/* Modifying directly */
do_something(curbits...); /* change buffer directly... */

/* Refresh buffer manually */
vi.activate |= FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
if(0 > ioctl(fd, FBIOPUT_VSCREENINFO, &vi)) {
    printf("Failed to refresh\n");
    return -1;
}

Linux usually use 'double buffer'.
For this, usually,

vi.yres_virtual == vi.yres * 2
vi.yoffset == 0 or vi.yres
(0 for 1st buffer, vi.yres for 2nd buffer)

But, it's totally dependent on driver. So, to get portability, we should not assume those.

alacarte의 한계를 넘어설 수 있다.
(이하는 Ubuntu 10.10에서의 내용이다.)

아래의 장소들과 깊은 관계되어 있다.
System default value가 들어 있는 곳 :

* /etc/xdg/ -> menus

User value가 들어 있는 곳

* ~/.config/ -> menus
 * ~/.local/share/ -> desktop-directories(- Directory), applications(- Menu Items)

.desktop 들어 있는 standard location

* /usr/share/applications/

크게 '.directory'와 '.desktop' 두 개의 확장자를 기억해 둘 필요가 있다.
'.directory'는 메뉴의 directory정보이고, '.desktop'은 메뉴 item의 정보라는 것 정도만 기억하자.

실험적으로, alacarte로 directory와 item을 만들어 보자.

pannel -> Application -> right click -> Edit Menus

로 들어가면 쉽게 만들어 볼 수 있다. GUI환경이라 skip...

만들었으면,  "~/.local/share/desktop-directories"로 가 보자. 그러면,  alacarte-madexx.directory 라는 file들이 새로 생겼을 것이고, 이 파일을 열어보면, GUI환경에서 새로 추가한 directory정보들과 일치함을 알 수 있다.
그리고 이번에는 "~/.local/share/applications"로 가 보자. alacarte-madexx.desktop 이라는 새로운 파일들을 볼 수 있고, 내용은 GUI환경에서 추가한, menu item정보임을 쉽게 알 수 있다.
이제 "~/.config/menus/"로 가서 applications.menu를 열어보자. 그러면, 위에서 봤던, '.directory' 파일과  '.desktop'파일의 이름이 나오는 메뉴 tag가 새로이 생성된 것을 알 수 있다.
간단히 정리하면, alacarte로 새로운 메뉴와 메뉴 item을 만들면 다음과 같은 파일이 생성/수정 된다.
(alacarte로 첫 메뉴/item을 만들었을 경우를 가정.)

* ~/.local/share/desktop-directories/alacarte-made.directory (추가) -- *1
* ~/.local/share/applications/alacarte-made.desktop (추가) -- *2
* ~/.config/menus/applications.menu (수정) -- *3

*1, *2는 메뉴/item 의 내용에 대한 정보이고, *3이 메뉴 구조에 대한 정보이다.

이제 case study로 실습해보자.
Ubuntu 10.10에서 Ubuntu Software Center에서 wine을 설치하고 이를 Applications 메인 메뉴에 등록해보자.
설치는 간단하니 skip하고...
설치가 끝나면 "/usr/share/applications"에  'wine.desktop, wine-xxxx.desktop' file들이 새롭게 생긴 것을 볼 수 있다. 이제 우리는 이걸 main menu에 잘 등록해 주기만 하면 된다.
그냥 하나씩 등록해도 되겠으나, 일반적으로 wine의 메뉴는 아래의 구조를 가진다.

wine
 +- Programs
 |    +- Accessories
 |        +- Notepad
 |
 |- Browse C: Drive
 |- Configure Wine
 +- Uninstall Wine Software

"각 '.desktop' 파일을 열어보면, category항목들이 보일 것이다. 특히 'wine-notepad.desktop'을 모면 "Categories=Wine-Programs-Accessories;"를 볼 수 있다.  즉 Category구조가 메뉴의 구조가 되고 있다. 이런 사항을 반영해서, *3 를 수정하면 된다.
그냥 direct로 수정해도 되겠으나, 차후 maintenance를 위해서 wine 메뉴는 따로 빼서 만들고 이를 *3에 merge하는 방식이 더 나아 보인다.
아래는 필자가 manual하게 추가한 결과이다.

*3에 추가

<Menu>
  <Name>Wine</Name>
  <MergeFile>wine.menu</MergeFile>
  <Directory>Wine.directory</Directory>
  <Include>
    <Category>Wine</Category>
    <Filename>wine.desktop</Filename>
  </Include>
  <Exclude>
    <Filename>wine.desktop</Filename>
  </Exclude>
  <AppDir>/home/hbg683/.local/share/applications</AppDir>
</Menu>

~/.config/menu/wine.menu 추가

<Menu>
  <Name>Wine</Name>
  <Directory>Wine.directory</Directory>
  <Include>
    <Category>Wine</Category>
     <Filename>wine.desktop</Filename>
  </Include>
  <AppDir>/home/hbg683/.local/share/applications</AppDir>
  <Menu>
    <Name>Programs</Name>
    <Directory>Wine-Program.directory</Directory>
    <DefaultLayout inline="false"/>
    <Menu>
      <Name>Accessories</Name>
      <Directory>Wine-Programs.Accessories.directory</Directory>
      <Include>
        <Category>Wine-Programs-Accessories</Category>
      </Include>
    </Menu>
    <DirectoryDir>/home/hbg683/.local/share/desktop-directories</DirectoryDir>
  </Menu>
  <DefaultLayout inline="false"/>
  <Exclude>
    <Filename>wine.desktop</Filename>
  </Exclude>
</Menu>

'~/.local/share/desktop-directories'에 각종 '.directory'파일 추가

Wine.directory
[Desktop Entry]
Name=Wine
Comment=Wine Windoes Program Loader
Type=Directory
Icon=wine
X-Ubuntu-Gettext-Domain=gnome-menus
Wine-Programs.directory, Wine-Programs-Accessories.directory 추가 (내용은 생략)

끝.

What is stdout, stdin and stderr?
Actually, I am using these without deep understanding.
Now, it's time to deep-dive to it.

Let me focus on stdout. (other twos are similar.)
What type of file default stdout is? Is it normal file? No, definitely. It's device file.
So, two different processes can write data to same stdout directly.
(Normal file doesn't allow this! )
I can easily know which device is used as stdout by checking devices.
(By entering following command in console.

ls -al /dev | grep stdout
    -> stdout -> /proc/self/fd/1

Interesting isn't it?
Let me move forward.

ls -al /proc/self/fd/1
    -> 1 -> /dev/pts/7

Right!.
Even if every process access standard output device with same name 'stdout', it branches to appropriate devices by symbolic link - '/proc/self' is used.
Now I can guess what redirecting stdout is. Let me check it.

# redirecting stdout with sample program.
# something like this.
# main() { for(int i=0; i<10000000; i++) { sleep(1); printf("+"); fflush(stdout); }}
$ ./a.out > t &
$ ls -al /proc/<child pid>/fd/1
    -> 1 -> /xxxx/xxx.../t <= path of target file 't'

Done!

+ Recent posts