擁抱自由,使用 linux !

在Linux底下真是太幸福了,有好多東西可以玩。想從windows解脫就是現在!

Mar-22-10

disable dhcp_client_id in gpxe

posted by Thomas

gpxe 預設會送出 client_id ,這個小小的動作與PXE不相容(因為大部份PXE都不會送出)。這樣的結果會造成DHCP Serevr 送不同的IP給同一台主機(再瑣MAC address以前),第一次gpxe要一個,之後應該是initram裏面又要一次,兩次不一樣,所以拿到不一樣的IP(大概是這樣啦),解決方式應該是要從 DHCP Server 下手,如果真的是同一台就嘗試給一個固定的 IP,另外,gpxe也不應該送dhcp_client_id。

小小 hack 一下,把 gpxe 預設送出 client_id 的動作,改由可以透過其他方式決定(#ifdef XXX),所以使用者只要連上config的網頁,從網頁的configuration,”Customize image configuration options”
接著Uncheck
SEND_DHCP_CLIENT_ID
Add DHCP client identifier. Required for Infiniband, and doesn’t hurt
other link layers.

產生出來的image預設就不會送出client_id

另外,gpxe 預設送出的 client_id 字串通常是
01(protocol):網路卡ID(xx:xx:xx:xx:xx:xx)

過程中學到一些經驗:
抓 dhcp client 封包
tcpdump -i eth1 -vvv -s 0 -n port 67 and port 68 (ref)

DHCP 行為 http://layer3.wordpress.com/2010/01/01/dhcppart1/

以及 程式設計師的堅持 http://etherboot.org/pipermail/gpxe/2010-March/000641.html

結果:http://lab.libthomas.org/gpxe-rom/

Tags: , , ,
Apr-27-09

get partition size

posted by Thomas

一直不希望 partclone 用外部程式去抓partition size,也沒有什麼 library 可以用!

但其實也沒有多難

主要就是:

ioctl(fd, BLKGETSIZE, &numblocks);

或是

ioctl(*ret, BLKGETSIZE64, &partition_size)

unsigned long long get_partition_size(int* ret){

    unsigned long long dest_size = 0;
    unsigned long dest_block;
    struct stat stat;
    int debug = 1;

    if (!fstat(*ret, &stat)) {
        if (S_ISFIFO(stat.st_mode)){
            dest_size = 0;
        } else if (S_ISREG(stat.st_mode)){
            dest_size = stat.st_size;
        } else {

#ifdef BLKGETSIZE64
            if (ioctl(*ret, BLKGETSIZE64, &dest_size) < 0) {
                printf("get device size error\n");
            }
            printf( "get device size %lli by ioctl BLKGETSIZE64,\n", dest_size);
            return dest_size;
#endif

#ifdef BLKGETSIZE
            if (ioctl(*ret, BLKGETSIZE, &dest_block) >= 0) {
                dest_size = (unsigned long long)(dest_block * 512);
            }
            printf( "get block %li and device size %lli by ioctl BLKGETSIZE,\n", dest_block, dest_size);
            return dest_size;
#endif
        }

    return dest_size;
}

reference:

1. http://linuxproblem.org/art_20.html

2. source code of ntfsclone

Tags: ,
Aug-28-07

about Endianness

posted by Thomas

常在一些程式裏面看到 Endianness ,指的就是資料在記憶體排列的狀況。一般有分 Little-Endian, Big-Endian, Bi-Endian三種。

依照 CPU 設計的不同, 當資料寬度超過一個位元組 (BYTE) 以上時:

  • 低位元組的部份,存放在記憶體的低位址處,稱為 Little-ENDIAN
  • 高位元組的部份放在低位址處,稱為 Big-ENDIAN.

範例 C output on big-endian machines

00000000 66 6f 6f 00 12 34 56 78 62 61 72 00 |foo..4Vxbar.|
0000000c

範例 C output on little-endian machines

00000000 66 6f 6f 00 78 56 34 12 62 61 72 00 |foo.xV4.bar.|
0000000c

注意 12 34 56 78 排列的順序…

一個簡單的轉換範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
short reverseShort (short s) {
 
    unsigned char c1, c2;    if (is_bigendian()) {
 
        return s;
 
    } else {
 
        c1 = s & 255;
 
        c2 = (s >> 8) & 255;
 
return (c1 < < 8) + c2;
 
    }
 
}

更多 endian 的說明

http://www.ibm.com/developerworks/aix/library/au-endianc/index.html?ca=drs-

http://www.cs.umass.edu/~verts/cs32/endian.html

Tags:
Jul-18-07

C/C++ 使用動態記憶體

posted by Thomas

之前常遇到不知道怎麼動態的使用記憶體

例如當我有這樣的需求

1
2
3
4
5
6
7
#include <stdio.h>
define magic_size=15
struct{
    char * magic[magic_size];
    int count;
    int* number[count];
}

我需要一個陣列,它的大小是依據 count 變數而產生,也就是一個動態的陣列。
一般寫法如第 4 行,宣告振列順便給大小,先把記憶體空出來。
但我需要的是第 6 行,動態大小的陣列,但是這行是錯誤的,編譯的時候 count 還不知道到底是多少!
動態陣列好處就是不會浪費記憶體空間,因為不需要事先預估一個大小,萬一用不到又浪費記憶體;反之,不夠用又很麻煩

參考了一些書籍和實作之後,發現可以用 指標+字串+記憶體 來解決

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
define magic_size=15
struct{
    char * magic[magic_size];
    int count;
    int* number;
} member;
 
int main(){
    int t = 0;
    member.count = 10;
    member.number = (int*)malloc(sizeof(int)*member.count);
    for (t = 0; t&lt;=member.count; t++){
        member.number[t]=0;
    }
    free(member.number);
}

在結構中先宣告成 int* number
實際要用到的時候才去跟系統要記憶體,這時候必須要知道自己要多大的區塊
member.number = (int*)malloc(sizeof(int)*member.count);
因為宣告的時候是 int* 所以要強制轉型
大小則是 sizeof(int)*count ,和陣列一般大小
使用就當一般陣列用啦!
要記得 free 掉就是了!

Tags:
Jul-17-07

用 vi/vim 寫 C 的時候

posted by Thomas

set cin ai softtabstop=4 shiftwidth=4

syntax on

——–說明——–

set cin
autoindent for C program

set ai
autoindent

set softtabstop=4
and
set shiftwidth=4

幾乎所有的 OS 及軟體都設定 Tab 就是 8 個字元長,這已經是個公認值,您硬要去改變它的話恐怕帶來許多不便,但實際上關於程式風格,許多人又認為 8 個字元太長了,幾個巢狀迴圈下來就需折行,反而不方便。因此 vim 體貼您,內建了 softtabstop 的功能,就是由 vim 來代您製造出一個假的 Tab,實際上是空白字元組成的 Tab。

舉個例子來說明比較清楚。

set softtabstop=4
set shiftwidth=4

這樣會由 4 個空白字元取代一個 Tab,您按 Tab 鍵 vim 就跳 4 格,需注意的是,如果您按了三次 Tab 鍵,那就是一個實際的 Tab 加上四個空白字元,可不是 12 個空白字元喔!是混合 Tab 及 space 的。 問題來了!那我要按真正的 8 字元的 Tab 時怎麼辦?簡單,還記得怎麼按特殊字元嗎? Ctrl-v Tab 或 Ctrl-v I 就可以了,那就是如假包換的 8 字元長之 Tab。當然,您按兩次 Tab 不就得了!:-)

syntax on
語法顏色標示

ref: 大家來學VIM

Tags: ,