* content
{:toc}
#!/bin/bash
#ss.sh
sslocal -s ip -p portnum -k password -t 600 -m aes-256-cfb
先说说有关的数据结构,内核中的这个数据结构映射的是物理地址,里面
有个count
的数据域,它标记着这个页的使用的量。返回值是-1,就说明
这个页没有被使用。然而,内核中经常使用一个page_conut()
的函数来
检查这个页的使用情况,通常情况是等于0(空闲),大于0(个数就是真实的
使用量)。
与page
有关的一个概念就是zone
了,可以说page
被分成了zone
,
zone
没有物理上的意义,只是为了方便追踪对page
的管理,页中的zone
有以下几个方面的应用:
ZONE_DMA
ZONE_DMA32
ZONE_NORMAL
ZONE_HIGHMEM
这些东西是定义在<include/linux/mmzone.h>
中的。
根据你使用的不同情况,合理的使用的标记。还有,zone
是不能垮边界的。
最常用的一个函数是
void *alloc_pages(gfp_t fp_mask, unsigned int order)
这样会分配一个2的order次方大小数量的页。gfp_t
是关于你分配页的使用的
标志,定义在<linux/gfp.h>里,它是__get_free_page()
的缩写。使用上面的函数,
我们得到的页是物理地址,
还不能被进程使用,我们必须转换成进程使用的虚拟地址,才能够真正应用这个
物理页。利用:
void *page_address(struct page *page)
就可以将分配到的物理页转化为虚拟地址,也就是进程可以使用的地址。
unsigned long get_zeroed_page(
unsigned int gfp_mask)
在某些情况下等于,返回一个全部充满0的页。
__get_free_page()
这个函数是分配以字节为单位的内核空间,与用户空间的malloc
函数特别相似。
函数定义在<linux/slab.h>,分配的也是2的方的数值。
void *kmalloc(size_t size, gfp_t flag)
分配的最大数值为128KB.
说说这个标志。它被定义在<linux/types.h>中,分为action modifiers、zone modifiers ,定义在<linux/gfp.h>中。
仅仅 ~alloc_page`可以分配高内存。
这个函数直接从虚拟地址分配地址,定义在<linux/vmalloc.h>文件中,且与 vfree()函数配套使用。
前面的分配页的内存管理方法可以满足绝大多数对内存的需要,可是有一点, 就是消耗的时间太多,因为经过了两级映射,有的甚至是三级映射,所以, 内核的开发者又想出了一个折中的方案,把页连成一串,形成页缓存。 在它下面使用
kmem_cache_create()
类似的函数,这里我们只需要简单的了解,更详细的我会补充上。
alloc_bootmem_..()
这是在启动的时候分配内存的代码,在初始化完成后这个代码就会被擦除。
vfs(virtual filesystem)是内核给予用户空间、用于对内核文件操作的接口。
举个例子: sys_write()
或者sys_open()
.
- super block
关于文件系统的高级元数据的容器,存在于磁盘上,管理文件系统的参数:块的数量、空闲块和根索引节点,这是在磁盘上;内存中,每一个list??维护一个super_block 块。
这个块存放文件系统本身的结构信息。不同版本的Unix实现的具体内容不一样。
- i-node
linux使用这个数据结构管理文件系统的所有对象。该数据结构使用slab进行内存分配。里面有很多的列表,其中一个指向引用该inode的dentry;只存在于内存中;
存放有关文件的属性,比如大小,文件所有者和最近修改时间等
- dentry
文件系统中有一个根dentry,这也是唯一一个没有父对象的dentry.所有其他dentry都有父对象,并且一部分还有子对象。在这个结构体内,有一个super_block,注释说是这是该目录的root。该结构体仅能存在文件系统内存中,而不能存放在磁盘上,存放在磁盘上的,最终是inode。
- file
内核中打开的每个文件都是一个file对象。
内核中处理一个文件系统。重要的函数 syn(_fs());
内核中处理一个文件。
内核中处理一个目录项。
内核中处理一个打开的文件。
VFS的内部由一个调度层(提供文件系统抽象)和许多缓存(用于改善文件系统操作的性能 )。VFS中动态管理的两个对象是dentry和inode.缓存这两个对象,用来实现后面的功能 。
` /etc/init.d/mysql stop `
(您可能有其它的方法,总之停止mysqld的运行就可以了)
mysqld --skip-grant-tables &
`mysql -u root
mysql> update mysql.user set password=PASSWORD('newpassword') where User='root';
mysql> flush privileges;
mysql> quit
尤其注意这里的格式,你必须保没有警告。</br>
重新启动MySQL
/etc/init.d/mysql restart
就可以使用新密码 newpassword 登录了。
不要在原子上下文中休眠
禁止中断时,也不能休眠
要确保有进程能唤醒自己
4.休眠被唤醒之后仍要检查等待的条件是否为真,否则重新继续休眠.
我们休眠的代码必须能够唤醒(wake_up),我们需要维护一个称为等待队列的数据结构. 等待队列就是一个进程链表,其中包含了等待了某个特定事件的所有进程. linux维护一个”等待队列头”来管理,wait_queue_head_t,定义在<linux/wait.h>
这里结构体前面的”__“是系统调用的函数.
DECLARE_WAIT_QUEUE_HEAD(name)
色块内的是方法,这里,我把相关的代码放在了一起,以便于理解.
linux 中最简单的休眠方式是下面的宏:
wait_event(queue, condition); //uninterruptible sleep
wait_event_interruptible(queue, condition); //返回非0值表示 休眠被信号中断
在这两个Macro实现中,分别有一个might_sleep()
的使用.而且后者
在实现上比前者多了个int __ret = 0
;
wait_event_timeout(queue, condition, timeout);
wait_event_interruptible_timeout(queue, condition, timeout);
不得不说一下这个宏,上面这四个宏中都牵扯上它了.代码注释是这么说的:
might_sleep - annotation for function that can sleep
queue 是等待队列头,传值方式,condition是任意一个布尔表达式,在休眠前后多次 对condition求值,为真则唤醒.
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
实际上,一般是wait_event
和wake_up,
wait_event_interruptible和
wake_
u_interruptible`成对使用