centos结束共享?centos怎么创建文件

大家好,关于centos结束共享很多朋友都还不太明白,今天小编就来为大家分享关于centos怎么创建文件的知识,希望对各位有所帮助!

CentOS下共享内存使用的常见陷阱详解

所谓共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。其他进程能把同一段共享内存段“连接到”他们自己的地址空间里去。所有进程都能访问共享内存中的地址。如果一个进程向这段共享内存写了数据,所做的改动会即时被有访问同一段共享内存的其他进程看到。共享内存的使用大大降低了在大规模数据处理过程中内存的消耗,但是共享内存的使用中有很多的陷阱,一不注意就很容易导致程序崩溃。

超过共享内存的大小限制?

在一个linux服务器上,共享内存的总体大小是有限制的,这个大小通过SHMMAX参数来定义(以字节为单位),您可以通过执行以下命令来确定 SHMMAX的值:

# cat/proc/sys/kernel/shmmax

如果机器上创建的共享内存的总共大小超出了这个限制,在程序中使用标准错误perror可能会出现以下的信息:

unable to attach to shared memory

解决方法:

1、设置 SHMMAX

SHMMAX的默认值是 32MB。一般使用下列方法之一种将 SHMMAX参数设为 2GB:

通过直接更改/proc文件系统,你不需重新启动机器就可以改变 SHMMAX的默认设置。我使用的方法是将以下命令放入/>etc/rc.local启动文件中:

# echo"2147483648">/proc/sys/kernel/shmmax

您还可以使用 sysctl命令来更改 SHMMAX的值:

# sysctl-w kernel.shmmax=2147483648

最后,通过将该内核参数插入到/etc/sysctl.conf启动文件中,您可以使这种更改永久有效:

# echo"kernel.shmmax=2147483648">>/etc/sysctl.conf

2、设置 SHMMNI

我们现在来看 SHMMNI参数。这个内核参数用于设置系统范围内共享内存段的最大数量。该参数的默认值是 4096。这一数值已经足够,通常不需要更改。

您可以通过执行以下命令来确定 SHMMNI的值:

# cat/proc/sys/kernel/shmmni

4096

3、设置 SHMALL

最后,我们来看 SHMALL共享内存内核参数。该参数控制着系统一次可以使用的共享内存总量(以页为单位)。简言之,该参数的值始终应该至少为:

ceil(SHMMAX/PAGE_SIZE)

SHMALL的默认大小为 2097152,可以使用以下命令进行查询:

# cat/proc/sys/kernel/shmall

2097152

SHMALL的默认设置对于我们来说应该足够使用。

注意:在 i386平台上 Red Hat Linux的页面大小为 4096字节。但是,您可以使用 bigpages,它支持配置更大的内存页面尺寸。

多次进行shmat会出现什么问题?

当首次创建共享内存段时,它并不能被任何进程所访问。为了使共享内存区可以被访问,则必须通过 shmat函数将其附加( attach)到自己的进程空间中,这样进程就与共享内存建立了连接。该函数声明在 linux/shm.h中:

#include

#include

void*shmat(int shmid, const void*shmaddr, int shmflg);

参数 shmid是 shmget()的返回值,是个标识符;

参数 shmflg是存取权限标志;如果为 0,则不设置任何限制权限。在中定义了几个权限:

#define SHM_RDONLY 010000/* attach read-only else read-write*/

#define SHM_RND 020000/* round attach address to SHMLBA*/

#define SHM_REMAP 040000/* take-over region on attach*/

如果指定 SHM_RDONLY,那么共享内存区只有读取权限。

参数 shmaddr是共享内存的附加点,不同的取值有不同的含义:

?如果为空,则由内核选择一个空闲的内存区;如果非空,返回地址取决于调用者是否给 shmflg参数指定 SHM_RND值,如果没有指定,则共享内存区附加到由 shmaddr指定的地址;否则附加地址为 shmaddr向下舍入一个共享内存低端边界地址后的地址(SHMLBA,一个常址)。

Ø通常将参数 shmaddr设置为 NULL。

shmat()调用成功后返回一个指向共享内存区的指针,使用该指针就可以访问共享内存区了,如果失败则返回-1。

其映射关系如下图所示:

图1.1共享内存映射图

其中,shmaddr表示的是物理内存空间映射到进程的虚拟内存空间时候,虚拟内存空间中该块内存的起始地址,在使用中,因为我们一般不清楚进程中哪些地址没有被占用,所以不好指定物理空间的内存要映射到本进程的虚拟内存地址,一般会让内核自己指定:

void ptr= shmat(shmid, NULL,0);

这样挂载一个共享内存如果是一次调用是没有问题的,但是一个进程是可以对同一个共享内存多次 shmat进行挂载的,物理内存是指向同一块,如果shmaddr为NULL,则每次返回的线性地址空间都不同。而且指向这块共享内存的引用计数会增加。也就是进程多块线性空间会指向同一块物理地址。这样,如果之前挂载过这块共享内存的进程的线性地址没有被shmdt掉,即申请的线性地址都没有释放,就会一直消耗进程的虚拟内存空间,很有可能会最后导致进程线性空间被使用完而导致下次shmat或者其他操作失败。

解决方法:

可以通过判断需要申请的共享内存指针是否为空来标识是否是第一次挂载共享内存,若是则使用进行挂载,若不是则退出。

void* ptr= NULL;

...

if(NULL!= ptr)

return;

ptr= shmat(shmid,ptr,0666);

附:

函数shmat将标识号为shmid共享内存映射到调用进程的地址空间中,映射的地址由参数shmaddr和shmflg共同确定,其准则为:

(1)如果参数shmaddr取值为NULL,系统将自动确定共享内存链接到进程空间的首地址。

(2)如果参数shmaddr取值不为NULL且参数shmflg没有指定SHM_RND标志,系统将运用地址shmaddr链接共享内存。

(3)如果参数shmaddr取值不为NULL且参数shmflg指定了SHM_RND标志位,系统将地址shmaddr对齐后链接共享内存。其中选项SHM_RND的意思是取整对齐,常数SHMLBA代表了低边界地址的倍数,公式“shmaddr–(shmaddr% SHMLBA)”的意思是将地址shmaddr移动到低边界地址的整数倍上。

Shmget创建共享内存,当key相同时,什么情况下会出错?

shmget()用来创建一个共享内存区,或者访问一个已存在的共享内存区。该函数定义在头文件 linux/shm.h中,原型如下:

#include

#include

int shmget(key_t key, size_t size, int shmflg);

参数 key是由 ftok()得到的键值;

参数 size是以字节为单位指定内存的大小;

参数 shmflg是操作标志位,它的一些宏定义如下:

IPC_CREATE:调用 shmget时,系统将此值与其他共享内存区的 key进行比较,如果存在相同的 key,说明共享内存区已存在,此时返回该共享内存区的标识符,否则新建一个共享内存区并返回其标识符。

IPC_EXCL:该宏必须和 IPC_CREATE一起使用,否则没意义。当 shmflg取 IPC_CREATE| IPC_EXCL时,表示如果发现内存区已经存在则返回-1,错误代码为 EEXIST。

注意,当创建一个新的共享内存区时,size的值必须大于 0;如果是访问一个已经存在的内存共享区,则置 size为 0。

一般我们创建共享内存的时候会在一个进程中使用shmget来创建共享内存,

Int shmid= shmget(key, size, IPC_CREATE|0666);

而在另外的进程中,使用shmget和同样的key来获取到这个已经创建了的共享内存,

Int shmid= shmget(key, size, IPC_CREATE|0666);

如果创建进程和挂接进程key相同,而对应的size大小不同,是否会shmget失败?

Ø已经创建的共享内存的大小是可以调整的,但是已经创建的共享内存的大小只能调小,不能调大

如:

shm_id= shmget(key,4194304,IPC_CREAT);

创建了一个4M大小的共享内存,如果这个共享内存没有删掉,我们再使用

shm_id= shmget(key,10485760,IPC_CREAT);

来创建一个10M大小的共享内存的时候,使用标准错误输出会有如下错误信息:

shmget error: Invalid argument

但是,如果我们使用:

shm_id= shmget(key,3145728,IPC_CREAT);

来创建一个3M大小的共享内存的时候,并不会输出错误信息,只是共享内存大小会被修改为3145728,这也说明,使用共享内存的时候,是用key来作为共享内存的唯一标识的,共享内存的大小不能区分共享内存。

这样会导致什么问题?

当多个进程都能创建共享内存的时候,如果key出现相同的情况,并且一个进程需要创建的共享内存的大小要比另外一个进程要创建的共享内存小,共享内存大的进程先创建共享内存,共享内存小的进程后创建共享内存,小共享内存的进程就会获取到大的共享内存进程的共享内存,并修改其共享内存的大小和内容(留意下面的评论补充),从而可能导致大的共享内存进程崩溃。

解决方法:

方法一:

在所有的共享内存创建的时候,使用排他性创建,即使用IPC_EXCL标记:

Shmget(key, size,IPC_CREATE|IPC_EXCL);

在共享内存挂接的时候,先使用排他性创建判断共享内存是否已经创建,如果还没创建则进行出错处理,若已经创建,则挂接:

Shmid= Shmget(key, size,IPC_CREATE|IPC_EXCL);

If(-1!= shmid)

{

Printf("error");

}

Shmid= Shmget(key, size,IPC_CREATE);

方法二:

虽然都希望自己的程序能和其他的程序预先约定一个唯一的键值,但实际上并不是总可能的成行的,因为自己的程序无法为一块共享内存选择一个键值。因此,在此把key设为IPC_PRIVATE,这样,操作系统将忽略键,建立一个新的共享内存,指定一个键值,然后返回这块共享内存IPC标识符ID。而将这个新的共享内存的标识符ID告诉其他进程可以在建立共享内存后通过派生子进程,或写入文件或管道来实现,即这种方法不使用key来创建共享内存,由操作系统来保证唯一性。

ftok是否一定会产生唯一的key值?

系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。

ftok原型如下:

key_t ftok( char* pathname, int proj_id)

pathname就时你指定的文件名,proj_id是子序号。

在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。如指定文件的索引节点号为65538,换算成16进制为0×010002,而你指定的proj_id值为38,换算成16进制为0×26,则最后的key_t返回值为0×26010002。

查询文件索引节点号的方法是: ls-i

但当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。

根据pathname指定的文件(或目录)名称,以及proj_id参数指定的数字,ftok函数为IPC对象生成一个唯一性的键值。在实际应用中,很容易产生的一个理解是,在proj_id相同的情况下,只要文件(或目录)名称不变,就可以确保ftok返回始终一致的键值。然而,这个理解并非完全正确,有可能给应用开发埋下很隐晦的陷阱。因为ftok的实现存在这样的风险,即在访问同一共享内存的多个进程先后调用ftok函数的时间段中,如果pathname指定的文件(或目录)被删除且重新创建,则文件系统会赋予这个同名文件(或目录)新的i节点信息,于是这些进程所调用的ftok虽然都能正常返回,但得到的键值却并不能保证相同。由此可能造成的后果是,原本这些进程意图访问一个相同的共享内存对象,然而由于它们各自得到的键值不同,实际上进程指向的共享内存不再一致;如果这些共享内存都得到创建,则在整个应用运行的过程中表面上不会报出任何错误,然而通过一个共享内存对象进行数据传输的目的将无法实现。

所以如果要确保key_t值不变,要么确保ftok的文件不被删除,要么不用ftok,指定一个固定的key_t值。

如果存在生成key_t值的文件被删除过,则很有可能自己现在使用的共享内存key_t值会和另外一个进程的key_t值冲突,如下面这种情况:

进程1使用文件1来ftok生成了key10000,进程2使用文件2来ftok生成了key 11111,此时如果进程1和进程2都需要下载文件,并将文件的内容更新到共享内存,此时进程1和2都需要先下文件,再删掉之前的共享内存,再使用ftok生成新的key,再用这个key去申请新的共享内存来装载新的问题,但是可能文件2比较大,下载慢,而文件1比较小,下载比较慢,由于文件1和文件2都被修改,此时文件1所占用的文件节点号可能是文件2之前所占用的,此时如果下载的文件1的ftok生成的key为11111的话,就会和此时还没有是否11111这个key的进程2的共享内存冲突,导致出现问题。

解决方法:

方法一:

在有下载文件操作的程序中,对下载的文件使用ftok获取key的时候,需要进行冲突避免的措施,如使用独占的方式获取共享内存,如果不成功,则对key进行加一操作,再进行获取共享内存,一直到不会产生冲突为止。

方法二:

下载文件之前,将之前的文件进行mv一下,先“占”着这个文件节点号,防止其他共享内存申请key的时候获取到。

另外:

创建进程在通知其他进程挂接的时候,建议不使用ftok方式来获取Key,而使用文件或者进程间通信的方式告知。

共享内存删除的陷阱?

当进程结束使用共享内存区时,要通过函数 shmdt断开与共享内存区的连接。该函数声明在 sys/shm.h中,其原型如下:

#include

#include

int shmdt(const void*shmaddr);

参数 shmaddr是 shmat函数的返回值。

进程脱离共享内存区后,数据结构 shmid_ds中的 shm_nattch就会减 1。但是共享段内存依然存在,只有 shm_attch为 0后,即没有任何进程再使用该共享内存区,共享内存区才在内核中被删除。一般来说,当一个进程终止时,它所附加的共享内存区都会自动脱离。

我们通过:

int shmctl( int shmid, int cmd, struct shmid_ds*buf);

来删除已经存在的共享内存。

第一个参数,shmid,是由shmget所返回的标记符。

第二个参数,cmd,是要执行的动作。他可以有三个值:

命令描述

IPC_STAT设置shmid_ds结构中的数据反射与共享内存相关联的值。

IPC_SET如果进程有相应的权限,将与共享内存相关联的值设置为shmid_ds数据结构中所提供的值。

IPC_RMID删除共享内存段。

第三个参数,buf,是一个指向包含共享内存模式与权限的结构的指针,删除的时候可以默认为0。

如果共享内存已经与所有访问它的进程断开了连接,则调用IPC_RMID子命令后,系统将立即删除共享内存的标识符,并删除该共享内存区,以及所有相关的数据结构;

如果仍有别的进程与该共享内存保持连接,则调用IPC_RMID子命令后,该共享内存并不会被立即从系统中删除,而是被设置为IPC_PRIVATE状态,并被标记为”已被删除”(使用ipcs命令可以看到dest字段);直到已有连接全部断开,该共享内存才会最终从系统中消失。

需要说明的是:一旦通过shmctl对共享内存进行了删除操作,则该共享内存将不能再接受任何新的连接,即使它依然存在于系统中!所以,可以确知,在对共享内存删除之后不可能再有新的连接,则执行删除操作是安全的;否则,在删除操作之后如仍有新的连接发生,则这些连接都将可能失败!

Shmdt和shmctl的区别:

Shmdt是将共享内存从进程空间detach出来,使进程中的shmid无效化,不可以使用。但是保留空间。

而shmctl(sid,IPC_RMID,0)则是删除共享内存,彻底不可用,释放空间。

在Hyper-V中实现windows与linux共享上网

相信不少读者都会做(或者曾经做过)这么一项活动——把一个Linux系统安装到Windows系统下的虚拟机软件中,然后在Windows这个大环境中对Linux进行学习或者一些实验操作。在进行这么一项活动时,不知道各位读者是否感受到网络连通的重要性(这里指外网的Internet),而事实上,无论是在虚拟机中还是在真实的物理机上“玩”Linux,(外网)网络都扮演着一个非常重要的角色。试想一下,当我们的Linux无法(外网)网路,这时我们又需要安装一个gcc编译器,各位读者会怎么做?采用源码编译?我想,gcc的编译安装这并不是一般人所能够做到的。采用rpm包安装?那光解决rpm包的依赖性就可能要折腾不少的时间。采用yum,并且把源指向安装光盘?这,确实是可以解决gcc的安装问题。但是,各位读者是否又想过这么一个问题,虽然Linux的安装光盘确实已经为我们提供了不少的软件包,但是一个安装光盘才有多大呀,CentOS 6.4的安装光盘也就只有那个四个来G,这就意味着,光盘并不是万能的,还会有不少的软件我们是无法从光盘中获取的,比如Mono,我们就必须自己从官网中下载一个并自己编译安装。(外网)网络是如此的重要,我们是不能够失去它的,哪怕是在虚拟机中也不例外。

在现实生活中,虚拟机软有非常多的种类,比较有名并且常用的有VM、VirtualBox等。如果各位正在阅读此文的读者是使用VM机作为自己的Linux虚拟机的,那么你们是幸福的,因为VM这款软件做得非常好,它自带的NAT技术一下子就可以帮各位读者解决联网问题,换句话说,只要作为大环境的Windows可以正常的访问网络,那么只需要在VM的网卡设置用选择“nat”选项或者采用“8号网卡(vmnet8)”,安装在VM中的Linux就已经获得了访问(外网)网络的权利了,用户完全无需为了网络的事情而烦恼和折腾。

   但是,既然在本文中是选择了Hyper-V作为虚拟机软件,那就代表着我们就没有VM那么幸福了,我们还得自己折腾一番才能争取到获得网络访问这个权利。

好的,正是进入主题,本文中,我们将讨论研究:

1、本文网络背景的介绍

2、如何在Linux中添加一张新网卡

3、如何实现Linux在Hyper-V中实现与Windows的共享宽带上网

4、TTL检测(路由封杀)网络环境的应对策略

1、当前实验网络背景的介绍

之前在网络中心常驻时,上网账号理论上是用不完的,当虚拟机中Linux想访问网络时,我们所采取的办法是正常的拨号上网,一台Linux要上网就拨一个号,十台Linux上网就拨十个号,通过这个方法,虚拟机中所有的Linux都能够访问网络。不过,这种方法是异常“奢侈”的,并且对于大部分读者来说也是非常不现实的。各位读者更多的则是像我当前的情况,从网络中心中撤离出来,回到宿舍,一共也就那么一个上网账号(还是自己花钱供养的),只能供一个主机同一时间访问网络的需要。

此外,当前的环境除了只有一个宽带账号的限制外,由于这里是一个校园网(包括许多高校的校园网、宽带小区或者部分地区电信、联通宽带用户),它们都会有防蹭网(路由器封杀)的这么一个功能,还真的只是一个宽带账号只能供一个主机访问网络(在这里,VM用户仍然不用担心这个问题)。

想要让Hyper-V中的Linux能够访问网络,各位读者可以通过一以下几个办法:

A、多开几个上网账号(非常耗费金钱)

B、买一个放封的路由(一次投资,多次回报,还是个不错的选择)

C、参考本文中的方法(虽不能保证一定能够成功,不过仍然值得一试,不行再采用前一种办法)

2、为Linux添加一块网卡

正式进入到我们的实验,为了不对当前的Linux环境造成干扰,我们决定采用为Linux添加一张新的网卡来进行我们当前的这个实验。

首先,先确保Hyper-V的“虚拟交换机管理器”中存在一个属性为“内部”适配器(如果没有,则需要自己添加一个,这里采用一张已有的网卡,各位读者不必为了这么长的名字而纠结)。

然后为Linux虚拟机添加一张网卡:

在这里,有几点是需要注意的:

(1)、虚拟交换机中请务必要选择“内部”属性的适配器(在这里选择的是刚刚新建的那张,名为:“Windows phone……”)

(2)、添加硬件时,建议选择“旧版的网络适配器”,以防止一些版本的Linux系统缺少对新版网卡的驱动。

然后启动我们的Linux系统,直接使用“setup”设置网卡:

我们发现刚才新增的网卡是并没有被Linux识别的(在这里,我们使用的是CentOS 6.4 X86_64版本,其他发行版的Linux可能会有所出入),我们需要手动的添加一个网卡配置文件。添加方法非常简单,进入“/etc/sysconfig/network-scripts/”目录,然后执行“cp ifcfg-eth0 ifcfg-eth1”(把eth0的配置文件再拷贝一份到eth1中),然后使用vi编辑器打开刚刚拷贝得到的“ifcfg-eth1”配置文件:

然后对该配置文件作出以下修改:

(1)、把“DEVICE”中由eth0改为eth1

(2)、删除“HWADDR”这一行(删除配置文件记录的网卡硬件地址)

(3)、删除“UUID”这一行(删除配置文件中硬件的唯一标识)

然后保存并退出。

继续使用vi编辑器打开“/etc/udev/rules.d/70-persistent-net.rules”,然后把里面的所有内容清空,保存并退出后重启Linux。

现在再setup就可以看到新添加的网卡了。

好的。就这样,我们成功的为Linux添加了一张新网卡。

3、对Hyper-V中的Linux赋予网络访问的权利

上一个小节中,我们添加了一张“内部”属性的适配器,现在我们把Windows中的宽带连接共享到这张“内部”适配器,让Linux能够共享Windows中的网络。

打开Windows中的“网络连接”:

里面有非常之多的网络适配器,这些大家都不用管,只需要留意图中两个蓝色框起来的适配器,一个为“宽带连接”(也就是Windows中的宽带连接),另一个是“vEthement(Internal Ethernet……)”(也就是在Hyper-V中新建的那一张内部网络适配器)。

在“宽带连接”中点击右键,选择“属性”,打开设置窗口,打开“共享”这个选项卡,勾上“允许其他网络用户通过此计算机的Internet连接来连接”,“家庭网络连接”这个下拉菜单中选择刚刚我们新建的“内部”网络适配器。

点击确定保存退出,断开当前的Windows宽带连接,重新拨号之后,刚才的设置即可生效。

然后继续设置我们的“内部”适配器的IP,如图所示,只要随意的设置一个与宽带连接不同网段的IP即可

然后,在Linux中的eth1网卡设置中采用DHCP的方式获取IP地址(有兴趣的读者可以分别尝试使用静态IP的方式和DHCP的方式获取Linux的IP,然后再对比一下“/etc/resolv”中的不同)

保存退出,并执行“service network restart”重启网络配置

现在尝试一下看能不能解析“www.baidu.com”的域名

嗯,非常好,我们的百度域名能够正常的解析,由于域名解析需要连网到DNS服务器,现在能够看到解析,这就表示,我们的Linux已经能够连网,具有网络访问的能力了。

4、应对拨号服务器的TTL检测

或许有一些读者遇过这么一种情况:现在有一个宽带的上网账号,由于某些原因(比如添置了一些新电脑之类的),想让几台电脑都能够共享这个宽带账号来上网,结果从电脑城中买回来一个路由器,非常正确的设置好相关的参数之后,竟然发现没有办法浏览网页,从路由器中的数据包监控中还发现,数据包不断的发送出去,却一个数据包都没有办法接收到。把路由器拿回电脑城中,路由器在哪里又能够正常的使用。

如果各位读者遇到了这种现象,并且排除了路由器故障这一问题之后,那就只能证明了一件事:当前的网路环境中存在对路由器使用的封杀,也就是在拨号服务器中有TTL的检测(当然,想要封杀路由器的使用方法有很多种,比较常用而且比较流行的办法就是采用TTL的检测,在本文中也是只针对TTL检测采取解决措施)。

关于什么是TTL值,各位读者可以用网上搜索详细的资料。在这里我只简单的解说一下:我们的数据包在网络中的传输,从一个网段的网络传输到另外一个网段的网络,这是需要路由器在其中发挥作用的,但是一个由多网段所组成的网络往往是非常庞大的(比如Internet),如果数据包没有一个传输次数的限制,那么就有可能发生这么一个事件:“数据包不断的在网络中传来传去,走遍了整个网络,并且还不断的重复这个动作”。这样,不仅使得网络的拥塞程度一下子大增甚至把整个网络挤垮,并且发送这个数据包的主机还无法获知这个数据包是否可达(也就是是否找到接收方或者接收方到底是否存在)。因此,为了解决这么一个问题,我们在发送数据包的时候,都会在数据包中设置一个TTL值,每当这个数据包经过一个路由器进行转发,数据包中的TTL值就会减1,直到数据包中的TTL值变为0,路由器就会自动的认为这个数据包是不可达的并自把这个数据包丢弃。

针对TTL值的这一个特性,只要在拨号服务器中增加一个TTL值的检测,只要用户是采用路由器上网的(具有放封功能的或者刷了放封固件的除外),到达拨号服务器中的数据包的TTL值就不是默认的TTL值(Windows默认的TTL为128,Linux默认的TTL值为64),如果在拨号服务器中再做这么一个小动作:“把所有不是默认TTL值的数据包全部丢弃”,这样就达到了对路由器封杀的效果。也就是各位读者在路由器的数据包监测中所看到的不断有数据包发出却一个数据包都没有办法收到的原因。

在本文中所介绍的Hyper-V共享上网中就遇到了这么一个问题(不一定所有读者都会遇到),比如我想从网上下载一个东西:

虽然DNS能够解析域名,但是却无法从网上下载东西。造成此现象的其中的原因就是:共享上网的原理跟使用路由器一样,而当前的校园网对路由器的使用有封杀。

要解决TTL检测并封杀路由器使用的方法比较直接,那就是修改数据包从网卡送出时的TTL值。

针对本文中的配置,我用excel画了一个简单的原理图,当虚拟机中的Linux通过eth1发送出一个数据包,该数据包会被发送到“内部”适配器中,然后“内部”适配器会充当一个路由的功能,把数据包转发到宽带连接中,接着,宽带连接也同样的充当同样的功能,把数据包转发出去。这里就存在着一个简单的算术题:“Windows默认的TTL值为128,也就是从宽带连接中出来的数据包必须是128的才不会被拨号服务器丢弃,而数据包每经过一次路由的转发TTL值就会减1,问从eth0中出来的数据包是多少时数据包才不会被拨号服务器丢弃?”聪明的读者一定能给很快的计算得出答案——130!!!

好的,既然我们已经计算出合适的TTL值,我们二话不多说的去设置Linux的数据包TTL值。我们只需使用vi编辑器打开“/etc/sysctl.conf”,然后再最后的地方添加上这么一句“net.ipv4.ip_default_ttl=130”,然后保存退出并重启网络。

这样,我们就可以突破了当前网络对路由器使用的封杀了。

瞧,这就可以下载东西了。

同时,这里还有一项需要读者们非常注意的地方:要时时刻刻的警惕seLinux和iptables所产生的作用,在本文中,如果这两项开启了的话,同样是无法下载东西的。各位读者要切记了。

至此,Linux(CentOS)如何在Hyper-V中实现与Windows宽带共享上网就到此结束了。

CentOS下SWAP分区建立及释放内存详解

方法一:

一、查看系统当前的分区情况:

free-m

二、创建用于交换分区的文件:

dd if=/dev/zero of=/whatever/swap bs=block_size(10M)count=number_of_block(3000)

三、设置交换分区文件:

mkswap/export/swap/swapfile

四、立即启用交换分区文件:

swapon/whateever/swap

五、若要想使开机时自启用,则需修改文件/etc/fstab中的swap行:

/whatever/swap swap swap defaults 0 0

方法二

增加交换分区空间的方法:

1.查看一下/etc/fstab确定目前的分区

2.swapoff/dev/hd**

3.free看一下是不是停了.

4.fdisk删了停掉的swap分区

5.重新用FDISK建一个新的SWAP分区

6.mkswap/dev/hd**把新的分区做成swap

7.swapon/dev/hd**打开swap

8.修改/etc/fstab

操作实例:

1.查看系统Swap空间使用

# free

total used free shared buffers cached

Mem: 513980 493640 20340 0 143808 271780

-/+ buffers/cache: 78052 435928

Swap: 1052248 21256 1030992

2.在空间合适处创建swap文件

# mkdir swap

# cd swap

# dd if=/dev/zero of=swapfile bs=1024 count=10000

10000+0 records in

10000+0 records out

# ls-al

total 10024

drwxr-xr-x 2 root root 4096 7月 28 14:58.

drwxr-xr-x 19 root root 4096 7月 28 14:57..

-rw-r--r-- 1 root root 10240000 7月 28 14:58 swapfile

# mkswap swapfile

Setting up swapspace version 1, size= 9996 KiB

3.激活swap文件

# swapon swapfile

# ls-l

total 10016

-rw-r--r-- 1 root root 10240000 7月 28 14:58 swapfile

# free

total used free shared buffers cached

Mem: 513980 505052 8928 0 143900 282288

-/+ buffers/cache: 78864 435116

Swap: 1062240 21256 1040984

生成1G的文件

# dd if=/dev/zero of=swapfile bs=10M count=3000

创建为swap文件

#mkswap swapfile

让swap生效

#swapon swapfile

查看一下swap

#swapon-s

[root@cluster/]# swapon-sFilenameTypeSizeUsedPriority/dev/sda3               partition10201161728-1/state/partition1/swap/swapfile    file307199920-2

加到fstab文件中让系统引导时自动启动

#vi/etc/fstab

/state/partition1/swap/swapfil swap swap defaults 0 0

完毕。

二,LINUX释放内存

细心的朋友会注意到,当你在linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching.这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法.那么我来谈谈这个问题.

先来说说free命令

[root@cluster/]# free-m

total   used   free  shared buffers  cached

Mem:    31730  31590   139    0    37  27537

-/+ buffers/cache:   4015  27714

Swap:   30996    1  30994

其中:

total内存总数

used已经使用的内存数

free空闲的内存数

shared多个进程共享的内存总额

buffers Buffer Cache和cached Page Cache磁盘缓存的大小

-buffers/cache的内存数:used- buffers- cached

+buffers/cache的内存数:free+ buffers+ cached

可用的memory=free memory+buffers+cached

有了这个基础后,可以得知,我现在used为163MB,free为86,buffer和cached分别为10,94

那么我们来看看,如果我执行复制文件,内存会发生什么变化.

[root@cluster/]# cp-r/etc~/test/

[root@cluster/]# free-m

total   used   free  shared buffers  cached

Mem:    31730  31590   139    0    37  27537

-/+ buffers/cache:   4015  27714

Swap:   30996    1  30994

在我命令执行结束后,used为244MB,free为4MB,buffers为8MB,cached为174MB,天呐都被cached吃掉了.别紧张,这是为了提高文件读取效率的做法.

引用[url][/url]为了提高磁盘存取效率, Linux做了一些精心的设计,除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换),还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。

那么有人说过段时间,linux会自动释放掉所用的内存,我们使用free再来试试,看看是否有释放?

[root@cluster/]# free-m

total   used   free  shared buffers  cached

Mem:    31730  31590   139    0    37  27537

-/+ buffers/cache:   4015  27714

Swap:   30996    1  30994

MS没有任何变化,那么我能否手动释放掉这些内存呢???回答是可以的!

/proc是一个虚拟文件系统,我们可以通过对它的读写操作做为与kernel实体间进行通信的一种手段.也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整.那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存.操作如下:

[root@cluster/]# cat/proc/sys/vm/drop_caches

0

首先,/proc/sys/vm/drop_caches的值,默认为0

[root@cluster/]# sync

手动执行sync命令(描述:sync命令运行 sync子例程。如果必须停止系统,则运行 sync命令以确保文件系统的完整性。sync命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O和读写映射文件)

[root@server test]# echo 3/proc/sys/vm/drop_caches

[root@server test]# cat/proc/sys/vm/drop_caches

3

将/proc/sys/vm/drop_caches值设为3

[root@server test]# free-m

total   used   free  shared buffers  cached

Mem:     249    66   182    0    0    11

-/+ buffers/cache:    55   194

Swap:    511    0   511

再来运行free命令,发现现在的used为66MB,free为182MB,buffers为0MB,cached为11MB.那么有效的释放了buffer和cache.

有关/proc/sys/vm/drop_caches的用法在下面进行了说明

/proc/sys/vm/drop_caches(since Linux 2.6.16)

Writing to this file causes the kernel to drop clean caches,

dentries and inodes from memory, causing that memory to become free.

To free pagecache, use echo 1/proc/sys/vm/drop_caches;

to free dentries and inodes, use echo 2/proc/sys/vm/drop_caches;

to free pagecache, dentries and inodes, use echo 3/proc/sys/vm/drop_caches.

Because this is a non-destructive operation and dirty objects

这几天发现linux系统内存一直涨,即使把apache和mysql关闭了,内存也不释放,可以使用以下脚本来释放内存:

脚本内容:

#!/bin/sh

# cache释放:

# To free pagecache:

/bin/sync

/bin/sync

#echo 1/proc/sys/vm/drop_caches

# To free dentries and inodes:

#echo 2/proc/sys/vm/drop_caches

# To free pagecache, dentries and inodes:

echo 3/proc/sys/vm/drop_caches

利用系统crontab实现每天自动运行:

crontab-e

输入以下内容:

00 00***/root/Cached.sh

每天0点释放一次内存,这个时间可以根据自己需要修改设置

在运行./Cached.sh时如果提示错误:Permission denied权限的问题,可以运行

阅读剩余
THE END