kk Blog —— 通用基础


date [-d @int|str] [+%s|"+%F %T"]
netstat -ltunp
sar -n DEV 1

CentOS各种设置

centos个人目录文件夹路径中文转英文

方法1. 修改系统语言环境

1
2
3
export LANG=en_US
xdg-user-dirs-gtk-update
export LANG=zh_CN.UTF-8

方法2. 修改系统配置文件

1
vim ~/.config/user-dirs.dirs

centos 8 重启网络命令

https://blog.csdn.net/weixin_54626591/article/details/135974971

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
nmcli c reload ens33        (不会立即生效)  # 重新载入网卡配置文件

nmcli c up ens33            (立即生效)      # 重启网卡ens33

两条命令一起执行, 如果不行,可尝试以下命令

# 重载所有ifcfg或route到connection(不会立即生效)
nmcli c reload  ifcfg-xxx

# 重载指定ifcfg或route到connection(不会立即生效)
nmcli c load etc/sysconfig/network-scripts/ifcfg-ethX
nmcli c load etc/sysconfig/network-scripts/route-ethX

# 立即生效connection,有3种方法
nmcli c up ethX
nmcli d reapply ethX
nmcli d connect ethX

Centos7系统rc.local不起作用

chmod +x /etc/rc.d/rc.local

开头加 #!/bin/bash

启动此项服务:

systemctl list-units –type=service #来查看一下所有的开启启动项目里面有没有这个rc-local这个服务。

systemctl status rc-local.service #来查看一下当前是怎么个状态

systemctl enable rc-local.service

systemctl start rc-local.service


使用gcc时,总是按中文提示。回归英文的提示,方法是: 首先使用env查看,发现LANGUAGE=zh_CN.UTF-8,接着执行export LANG=en_US.UTF-8就可以,以后的编译是就按英文来提示


1
2
lsattr /etc/passwd /etc/group /etc/shadow /etc/gshadow
chattr -i /etc/passwd /etc/group /etc/shadow /etc/gshadow

英文:E437: terminal capability “cm” required
中文:e437 终端需要能力 cm

这个错误一般是环境变量TERM没有配置或者配置错误所致, 用 export TERM=linux 或者 export TERM=xterm


上传是用rz -be,并且去掉弹出的对话框中“Upload files as ASCII”前的勾选。 -a, –ascii -b, –binary 用binary的方式上传下载,不解释字符为ascii -e, –escape 强制escape 所有控制字符,比如Ctrl+x,DEL等


nginx

http://nginx.org/packages/rhel/7/x86_64/RPMS/


binkernel.spec

1
2
3
4
5
6
7
8
9
10
11
12
%pre
mkdir -p /usr/local/kernel/etc/
echo "version=%{version}-%{release}" > /usr/local/kernel/etc/install.conf

%post
/sbin/new-kernel-pkg --package kernel --mkinitrd --depmod --install 2.6.32-358.6.1.ws5.b.5.1.11t25

%preun
rm -rf /usr/local/kernel/

%postun
/sbin/new-kernel-pkg  --remove 2.6.32-358.6.1.ws5.b.5.1.11t25

更改 bash_history 默认历史记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
vim ~/.bashrc

# 忽略[连续]重复命令
HISTCONTROL=ignoredups

# 清除重复命令
# HISTCONTROL=erasedups

# 忽略特定命令
HISTIGNORE="[   ]*:ls:ll:cd:vi:pwd:sync:exit:history*"

# 命令历史文件大小10M
HISTFILESIZE=1000000000

# 保存历史命令条数10W
HISTSIZE=1000000

以上配置可以通过 set | grep HIST 查看可选项.


多终端追加
当打开多个终端,关闭其中一个终端时会覆盖其他终端的命令历史,这里我们采用追加的方式避免命令历史文件.bash_history 文件被覆盖。

shopt -s histappend

更多 shopt 可选项可以通过 echo $SHELLOPTS 命令查看。

关闭CentOS6启动进度条,显示详细自检信息。vim /boot/grub/grub.conf,将"rhgb"和 “quiet"去掉,保存即可


vmware虚拟机mkinitrd提示no module ehci-hcd 错误的话,加:

1
--builtin=ehci-hcd --builtin=ohci-hcd --builtin=uhci-hcd

CentOS6.0 下默认开selinux时出现httpd 报“SELinux policy enabled; httpd running as context unconfined_u:system”的解决方案

1
2
3
4
5
yum install policycoreutils-python

# To allow httpd to use nfs dirs in CentOS-6
setsebool -P httpd_use_nfs 1
setsebool -P httpd_enable_homedirs 1

CentOS 关闭防火墙

1) 永久性生效,重启后不会复原
开启:

1
2
chkconfig iptables on
chkconfig ip6tables on

关闭:

1
2
chkconfig iptables off
chkconfig ip6tables off

2) 即时生效,重启后复原
开启:

1
2
service iptables start
service ip6tables start

关闭:

1
2
service iptables stop
service ip6tables stop

CentOS安装软件:/lib/ld-linux.so.2: bad ELF interpreter 解决

是因为64位系统中安装了32位程序, 解决方法:

1
yum install glibc.i686

其他包

1
yum install libstdc++.i686

gcc, c++

1
2
3
4
yum install glibc
yum install glibc-devel
yum install gcc-c++
yum install libstdc++

tc模拟丢包率时延

tc 的最最基本的使用

1
2
3
4
tc qdisc show    # 显示
tc qdisc add dev eth0 root ...... # 加入
tc qdisc change dev eth0 root ...... # 修改存在的 qdisc ,记的,加入同一条后只能用 change 来修改
tc qdisc del dev eth0 root  # 删除

Linux 中延时模拟

设置延时 3s :

1
tc qdisc add dev eth0 root netem delay 3000ms

可以在 3000ms 后面在加上一个延时,比如 3000ms 200ms 表示 3000ms ± 200ms ,延时范围 2800 – 3200 之间.

Linux 中丢包模拟

设置丢包 50% ,iptables 也可以模拟这个,但一下不记的命令了,下次放上来:

1
tc qdisc change dev eth0 root netem loss 50%

上面的设丢包,如果给后面的 50% 的丢包比率修改成 50% 80% 时,这时和上面的延时不一样,这是指丢包比率为 50-80% 之间。

Linux TCP发送数据tcp_write_xmit

http://blog.csdn.net/youxin2012/article/details/27175253

__tcp_push_pending_frames 该函数将所有pending的数据,全部发送出去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
			 int nonagle)
{
	/* If we are closed, the bytes will have to remain here.
	 * In time closedown will finish, we empty the write queue and
	 * all will be happy.
	 */
	/* 该socket已经关闭,那么直接返回 */
	if (unlikely(sk->sk_state == TCP_CLOSE))
		return;

	/* 发送数据 */
	if (tcp_write_xmit(sk, cur_mss, nonagle, 0, GFP_ATOMIC))
		tcp_check_probe_timer(sk); //发送数据失败,使用probe timer进行检查。
}

发送端 tcp_write_xmit 函数

版本:2.6.33.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* This routine writes packets to the network.  It advances the
 * send_head.  This happens as incoming acks open up the remote
 * window for us.
 *
 * LARGESEND note: !tcp_urg_mode is overkill, only frames between
 * snd_up-64k-mss .. snd_up cannot be large. However, taking into
 * account rare use of URG, this is not a big flaw.
 *
 * Returns 1, if no segments are in flight and we have queued segments, but
 * cannot send anything now because of SWS or another problem.
 */
static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
			  int push_one, gfp_t gfp)
{
	struct tcp_sock *tp = tcp_sk(sk);
	struct sk_buff *skb;
	unsigned int tso_segs, sent_pkts;
	int cwnd_quota;
	int result;

	/* sent_pkts用来统计函数中已发送报文总数。*/
	sent_pkts = 0;

	/* 检查是不是只发送一个skb buffer,即push one */
	if (!push_one) {
		/* 如果要发送多个skb,则需要检测MTU。
		 * 这时会检测MTU,希望MTU可以比之前的大,提高发送效率。
		 */
		/* Do MTU probing. */
		result = tcp_mtu_probe(sk);
		if (!result) {
			return 0;
		} else if (result > 0) {
			sent_pkts = 1;
		}
	}

	while ((skb = tcp_send_head(sk))) {
		unsigned int limit;

		/* 设置有关TSO的信息,包括GSO类型,GSO分段的大小等等。
		 * 这些信息是准备给软件TSO分段使用的。
		 * 如果网络设备不支持TSO,但又使用了TSO功能,
		 * 则报文在提交给网络设备之前,需进行软分段,即由代码实现TSO分段。
		 */
		tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
		BUG_ON(!tso_segs);

		/* 检查congestion windows, 可以发送几个segment */
		/* 检测拥塞窗口的大小,如果为0,则说明拥塞窗口已满,目前不能发送。
		 * 拿拥塞窗口和正在网络上传输的包数目相比,如果拥塞窗口还大,
		 * 则返回拥塞窗口减掉正在网络上传输的包数目剩下的大小。
		 * 该函数目的是判断正在网络上传输的包数目是否超过拥塞窗口,
		 * 如果超过了,则不发送。
		 */
		cwnd_quota = tcp_cwnd_test(tp, skb);
		if (!cwnd_quota)
			break;

		/* 检测当前报文是否完全处于发送窗口内,如果是则可以发送,否则不能发送 */
		if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
			break;

		/* tso_segs=1表示无需tso分段 */
		if (tso_segs == 1) {
			/* 根据nagle算法,计算是否需要发送数据 */
			if (unlikely(!tcp_nagle_test(tp, skb, mss_now,
							 (tcp_skb_is_last(sk, skb) ?
							  nonagle : TCP_NAGLE_PUSH))))
				break;
		} else {
			/* 当不止一个skb时,通过TSO计算是否需要延时发送 */
			/* 如果需要TSO分段,则检测该报文是否应该延时发送。
		   * tcp_tso_should_defer()用来检测GSO段是否需要延时发送。
			 * 在段中有FIN标志,或者不处于open拥塞状态,或者TSO段延时超过2个时钟滴答,
			 * 或者拥塞窗口和发送窗口的最小值大于64K或三倍的当前有效MSS,在这些情况下会立即发送,
			 * 而其他情况下会延时发送,这样主要是为了减少软GSO分段的次数,以提高性能。
			 */
			if (!push_one && tcp_tso_should_defer(sk, skb))
				break;
		}

		limit = mss_now;
		/* 在TSO分片大于1的情况下,且TCP不是URG模式。通过MSS计算发送数据的limit
		 * 以发送窗口和拥塞窗口的最小值作为分段段长*/
		 */
		if (tso_segs > 1 && !tcp_urg_mode(tp))
			limit = tcp_mss_split_point(sk, skb, mss_now,
							cwnd_quota);
		/* 当skb的长度大于限制时,需要调用tso_fragment分片,如果分段失败则暂不发送 */
		if (skb->len > limit &&
			unlikely(tso_fragment(sk, skb, limit, mss_now)))
			break;

		/* 以上6行:根据条件,可能需要对SKB中的报文进行分段处理,分段的报文包括两种:
		 * 一种是普通的用MSS分段的报文,另一种则是TSO分段的报文。
		 * 能否发送报文主要取决于两个条件:一是报文需完全在发送窗口中,而是拥塞窗口未满。
		 * 第一种报文,应该不会再分段了,因为在tcp_sendmsg()中创建报文的SKB时已经根据MSS处理了,
		 * 而第二种报文,则一般情况下都会大于MSS,因为通过TSO分段的段有可能大于拥塞窗口的剩余空间,
		 * 如果是这样,就需要以发送窗口和拥塞窗口的最小值作为段长对报文再次分段。
		 */

		/* 更新tcp的时间戳,记录此报文发送的时间 */
		TCP_SKB_CB(skb)->when = tcp_time_stamp;

		if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
			break;

		/* Advance the send_head.  This one is sent out.
		 * This call will increment packets_out.
		 */
		/* 更新统计,并启动重传计时器 */
		/* 调用tcp_event_new_data_sent()-->tcp_advance_send_head()更新sk_send_head,
		 * 即取发送队列中的下一个SKB。同时更新snd_nxt,即等待发送的下一个TCP段的序号,
		 * 然后统计发出但未得到确认的数据报个数。最后如果发送该报文前没有需要确认的报文,
		 * 则复位重传定时器,对本次发送的报文做重传超时计时。
		 */
		tcp_event_new_data_sent(sk, skb);

		/* 更新struct tcp_sock中的snd_sml字段。snd_sml表示最近发送的小包(小于MSS的段)的最后一个字节序号,
		 * 在发送成功后,如果报文小于MSS,即更新该字段,主要用来判断是否启动nagle算法
		 */
		tcp_minshall_update(tp, mss_now, skb);
		sent_pkts++;

		if (push_one)
			break;
	}
	/* 如果本次有数据发送,则对TCP拥塞窗口进行检查确认。*/
	if (likely(sent_pkts)) {
		tcp_cwnd_validate(sk);
		return 0;
	}
	/*
	 * 如果本次没有数据发送,则根据已发送但未确认的报文数packets_out和sk_send_head返回,
	 * packets_out不为零或sk_send_head为空都视为有数据发出,因此返回成功。
	 */
	return !tp->packets_out && tcp_send_head(sk);
}