Pages

2011-11-09

In general, those <linux/*> headers are not intended for direct inclusion by apps. If they're needed, one of the standard headers will generally include them, or else will just duplicate the info from them, perhaps in a slightly different way.
But, glibc and the rest of user-space is working off those standard headers, so those are the ones you want to be using.
The <linux/*> ones are typically straight out of the kernel source, and often aren't appropriate for user-space.
                    -- referenced here.

So <netinet/tcp.h> <netinet/udp.h> <netinet/icmp.h> are what we want.

If on x86 or x86_64, little-endian will set to macro __BIT_ORDER in <endian.h>.
In <netinet/tcp.h>:

 # else /* !__FAVOR_BSD */
struct tcphdr
  {
    u_int16_t source;
    u_int16_t dest;
    u_int32_t seq;
    u_int32_t ack_seq;
#  if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int16_t res1:4;
    u_int16_t doff:4;
    u_int16_t fin:1;
    u_int16_t syn:1;
    u_int16_t rst:1;
    u_int16_t psh:1;
    u_int16_t ack:1;
    u_int16_t urg:1;
    u_int16_t res2:2;
#  elif __BYTE_ORDER == __BIG_ENDIAN
    u_int16_t doff:4;
    u_int16_t res1:4;
    u_int16_t res2:2;
    u_int16_t urg:1;
    u_int16_t ack:1;
    u_int16_t psh:1;
    u_int16_t rst:1;
    u_int16_t syn:1;
    u_int16_t fin:1;
#  else
#   error "Adjust your  defines"
#  endif
    u_int16_t window;
    u_int16_t check;
    u_int16_t urg_ptr;
};
# endif /* __FAVOR_BSD */
I've tested and checked that __BYTE_ORDER == __LITTLE_ENDIAN.

_FILE_OFFSET_BITS

Be careful when using _FILE_OFFSET_BITS=64 to compile a program that calls a library or a library if any of the interfaces uses off_t. With _FILE_OFFSET_BITS=64 glibc will change the type of off_t to off64_t. You can either change the interface to always use off64_t, use a different function if _FILE_OFFSET_BITS=64 is used (like glibc does). Otherwise take care that both library and program have the same _FILE_OFFSET_BITS setting. Note that glibc is aware of the _FILE_OFFSET_BITS setting, there's no problem with it but there might be problems with other libraries.

@淘宝雕梁:nginx中定义了_FILE_OFFSET_BITS=64, 这个宏会导致off_t为8个字节(32位系统),而这个宏并没有通过gcc的编译参数传递进来,只是定义在ngx_linux_config.h的开头。于是如果编写模块,在模块的代码中必须把nginx的头文件包含在最上面,否则会导致在模块的代码中off_t的大小和在nginx中的大小不一致。

2011-11-06

Hotplug cpu

There's a way to make specified cpus online -- maxcpus=N as an initialization argument. The shortcoming is obvious that every time have to reboot.

We can change dynamically if the current kernel has CONFIG_HOTPLUG_CPU set. After that:
% ll /sys/devices/system/cpu/cpu1
total 0
 4498 drwxr-xr-x 5 root root    0 Nov  6 17:38 cache
10292 drwxr-xr-x 2 root root    0 Nov  6 16:29 cpufreq
10185 drwxr-xr-x 5 root root    0 Nov  6 17:38 cpuidle
  201 -r-------- 1 root root 4.0K Nov  6 17:38 crash_notes
  200 -rw-r--r-- 1 root root 4.0K Nov  6 17:38 online
 7337 drwxr-xr-x 2 root root    0 Nov  6 17:38 topology
$ su -c 'echo 0 > /sys/devices/system/cpu/cpu1/online'
to shutdown cpu1.

There must be at least one cpu, so that cpu0 has no online
% ll /sys/devices/system/cpu/cpu0
total 0
 4467 drwxr-xr-x 5 root root    0 Nov  6 17:43 cache
10276 drwxr-xr-x 2 root root    0 Nov  6 16:29 cpufreq
10140 drwxr-xr-x 5 root root    0 Nov  6 17:43 cpuidle
  198 -r-------- 1 root root 4.0K Nov  6 17:43 crash_notes
 7330 drwxr-xr-x 2 root root    0 Nov  6 17:43 topology

Simple calculations in vim

From here.
In insert mode, <C-r>= to input calculations.
But only + - * / supported. And result auto converted to decimal when meeting hex.
Useful for hex to decimal.

Exchange capslock and left-ctrl using xmodmap

remove Lock = Caps_Lock
remove Control = Control_L
keysym Caps_Lock = Control_L
keysym Control_L = Caps_Lock
add Lock = Caps_Lock
add Control = Control_L
Save in a normal file, then:
$ xmodmap ./caps-ctrl

Or save as a shell script:
xmodmap -e "remove Lock = Caps_Lock"
xmodmap -e "remove Control = Control_L"
xmodmap -e "keysym Caps_Lock = Control_L"
xmodmap -e "keysym Control_L = Caps_Lock"
xmodmap -e "add Lock = Caps_Lock"
xmodmap -e "add Control = Control_L"

That's pretty cool for *nix working, like shell control & emacs & vim and so forth.

2011-10-28

strtod and atof

#include <stdio.h>

int main(int argc, const char *argv[])
{
        double d = strtod("10.04", NULL);
        double e = atof("200.04");
        printf("%f\n", d);
        printf("%f\n", e);
        return 0;
}

% gcc b.c -Wall
b.c: In function ‘main’:
b.c:33:9: warning: implicit declaration of function ‘strtod’
b.c:34:9: warning: implicit declaration of function ‘atof’
% ./a.out
267386.000000
590151.000000

It's using corresponding ones in gcc, not glibc, but the result is misleading.
Then add
#include <stdlib.h>

it's correct.
% ./a.out
10.040000
200.040000

2011-10-20

NIC's errors and dropped

Use ifconfig, like
% ifconfig eth0              
eth0      Link encap:Ethernet  HWaddr 00:24:8C:A1:10:E6  
          inet addr:192.168.9.117  Bcast:192.168.9.255  Mask:255.255.255.0
          inet6 addr: fe80::224:8cff:fea1:10e6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3556177 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1232256770 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:661235707 (630.6 MiB)  TX bytes:3049861888 (2.8 GiB)
          Interrupt:43 Base address:0x2000

Some info come from /proc/net/dev, like errors and dropped

What's the meaning of them ?

In net/core/dev.c:
static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
{
        const struct net_device_stats *stats = dev_get_stats(dev);

        seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
               "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
               dev->name, stats->rx_bytes, stats->rx_packets,
               stats->rx_errors,
               stats->rx_dropped + stats->rx_missed_errors,
               stats->rx_fifo_errors,
               stats->rx_length_errors + stats->rx_over_errors +
               stats->rx_crc_errors + stats->rx_frame_errors,
               stats->rx_compressed, stats->multicast,
               stats->tx_bytes, stats->tx_packets,
               stats->tx_errors, stats->tx_dropped,
               stats->tx_fifo_errors, stats->collisions,
               stats->tx_carrier_errors +
               stats->tx_aborted_errors +
               stats->tx_window_errors +
               stats->tx_heartbeat_errors,
               stats->tx_compressed);
}

and struct net_device_stats is:
struct net_device_stats
{
        unsigned long rx_packets;  /* total packets received */
        unsigned long tx_packets;  /* total packets transmitted */
        unsigned long rx_bytes;  /* total bytes received  */
        unsigned long tx_bytes;  /* total bytes transmitted */
        unsigned long rx_errors;  /* bad packets received  */
        unsigned long tx_errors;  /* packet transmit problems */
        unsigned long rx_dropped;  /* no space in linux buffers */
        unsigned long tx_dropped;  /* no space available in linux */
        unsigned long multicast;  /* multicast packets received */
        unsigned long collisions;

        /* detailed rx_errors: */
        unsigned long rx_length_errors;
        unsigned long rx_over_errors;  /* receiver ring buff overflow */
        unsigned long rx_crc_errors;  /* recved pkt with crc error */
        unsigned long rx_frame_errors; /* recv'd frame alignment error */
        unsigned long rx_fifo_errors;  /* recv'r fifo overrun  */
        unsigned long rx_missed_errors; /* receiver missed packet */

        /* detailed tx_errors */
        unsigned long tx_aborted_errors;
        unsigned long tx_carrier_errors;
        unsigned long tx_fifo_errors;
        unsigned long tx_heartbeat_errors;
        unsigned long tx_window_errors;

        /* for cslip etc */
        unsigned long rx_compressed;
        unsigned long tx_compressed;
};

Field errors is rx_errors, which is bad packets received, with any invalid fields in ip header, like length or checksum.
Field dropped is rx_dropped (no space in buffers) + rx_missed_errors (receiver missed packet),

When the machine got a lot of packets, such as under ddos attack, the dropped field of the IN port will increase quickly.


Reference:
http://stackoverflow.com/questions/3521678/linux-what-are-means-of-fields-in-proc-net-dev

2011-08-16

THREE


人有三样东西是无法隐瞒的,咳嗽、穷困和爱;你想隐瞒越欲盖弥彰。
人有三样东西是不该挥霍的,身体、金钱和爱;你想挥霍却得不偿失。
人有三样东西是无法挽留的,时间、生命和爱;你想挽留却渐行渐远。
人有三样东西是不该回忆的,灾难、死亡和爱;你想回忆却苦不堪言。

《洛丽塔》

2011-08-13

Store extra info in pointer

A pointer is at least align to 4 bytes, in all architectures.
That means, the lowest 2 bits are always 0 :)
For example in kernel standard rbtree (include/linux/rbtree.h),

struct rb_node
{
    unsigned long  rb_parent_color;
#define    RB_RED       0
#define    RB_BLACK    1
    struct rb_node *rb_right;
    struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));



rb_parent_color is a pointer to it's parent, while bit 0 represents the color of the parent.


They've defined a macro to say hello world to it's parent,
#define rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))

2011-08-10

sshd config

/etc/ssh/ssh_config and /etc/ssh/sshd_config
In the latter, set some to control remote ssh login.
I.e.

Port 22
Protocol 2
PermitEmptyPasswords no
PermitRootLogin no  # can't login as root
AllowUsers xxx        # nobody can login except for xxx

For the last 2, login from a remote host, the server'll say 
'Permission denied, please try again.'
As u didn't input the right password.