Browsed by
Tag: wine

将内核编译到自定义的目录下

将内核编译到自定义的目录下

参考wiki: https://wiki.archlinux.org/index.php/Kernels/Traditional_compilation 使用ArchLinux作为构建Linux的环境 方法如下 假设我们的customized directory为kernel-build 我们必须在kernel-tree目录结构下对内核进行编译,假设kernel-tree目录名为linux-kernel 下面是具体的操作: make menuconfig # Change the local version in General Settings make -j8 make modules -j8 sudo make modules_install 在 make menuconfig 的时候,最好对内核版本进行修改,使之不会在make modules_install的时候覆盖掉现有内核的modules 修改途径为General Setup里的Local Version项 这样执行之后,应该在arch/ARCH/boot/下面存在bzImage内核镜像,并且modules应该被安装在了/lib/modules/<linux-version>-<localversion> 下 下一步操作, 修改linux.preset文件,并创建initrd文件 ## Change to kernel-build directory cp ../arch/<arch>/boot/bzImage [image-name] cp /etc/mkinitcpio.d/linux.preset . 修改linux.preset文件, 修改完毕后的内容类似下面 # mkinitcpio preset file for the ‘linux’ package ALL_config=”/etc/mkinitcpio.conf” ALL_kver=”/home/void001/linux-kernel/kernel-build/vmlinuz” PRESETS=(‘default’ ‘fallback’) #default_config=”/etc/mkinitcpio.conf” default_image=”/home/void001/linux-kernel/kernel-build/initramfs-linux.img” #default_options=”” #fallback_config=”/etc/mkinitcpio.conf” fallback_image=”/home/void001/linux-kernel/kernel-build/initramfs-linux-fallback.img” fallback_options=”-S autodetect” 我们需要修改ALL_kver, default_image, fallback_image三个选项,使其将image保存到指定的目录下 然后使用 mkinitcpio -p ./linux.preset 创建initrd, initrd-fallback,目前kernel-build目录应该有如下文件: ╰─➤ ls…

Read More Read More

多进程&多线程 echo server实现

多进程&多线程 echo server实现

本文为 高性能网络编程学习 系列文章的第1篇   多进程版本 本文承接上文的单进程 echo server 建立一个多进程的echo server。代码的改动不多,下面贴一下完整的代码 /************************************************************************* > File Name: server.c > Author: VOID_133 > A very simple tcp echo server illustrate use of socket > Ver1 only accept single connection, no multiple connection allowed > Mail: ################### > Created Time: Wed 21 Dec 2016 04:03:25 PM HKT ************************************************************************/ #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include<string.h> #include<sys/errno.h> #define MAX_BUF_SIZE 1000 void usage(char *proc_name) { printf(“%s [port]\n”, proc_name); exit(1); } int main(int argc, char** argv) { int sockfd, clifd; //sockaddr_in…

Read More Read More

Linux 下C语言简单echo server的实现

Linux 下C语言简单echo server的实现

本文为 高性能网络编程学习 系列文章的第0篇 本文目的为讲述简单的echo server的实现, echo server的含义如字面意思, 客户端发送什么数据,服务器就返回什么数据作为响应,本系列文章的目的不在于实现复杂的服务器端业务逻辑,在于学习如何开发出高性能的网络通信程序,因而所有的代码均为echo server的实现 Linux下用C进行网络通信的话, 需要使用socket, 即Linux socket interface, socket是一种IPC(Inter Process Communication进程间交互)的方式,同时socket还可以允许跨host,即在不同的主机上的进程之间进行通信,在Linux上,所有的IO操作都是通过对文件的写入读出实现的,socket也作为一种文件存在,可以通过read, write进行IO 客户端我们采用的是一个benchmark程序,即1000个client,每一个client发送1000个请求,客户端为了简洁和快速编写,使用golang开发,之后所有的server都使用这个benchmark进行测试,代码如下 package main import ( “flag” “fmt” “io” “net” “sync” “time” ) var wg sync.WaitGroup var okCliCnt = 0 var okIPCCnt = 0 var mu sync.Mutex var ( ConnType = “tcp” ConnAddr = “” ClientCnt = 1000 RequestCnt = 1000 ) func init() { flag.StringVar(&ConnAddr, “S”, “127.0.0.1:5210”, “specify the address to connect”) flag.IntVar(&ClientCnt, “cno”, 1000, “number of clients to request”) flag.IntVar(&RequestCnt, “rno”, 1000, “number…

Read More Read More

My Yearly Goals

My Yearly Goals

—–BEGIN PGP MESSAGE—– Version: GnuPG v2 hQIOA2jnx9T3JM9SEAf/VSB3nCEOzyJEf9RRSI76xw4kv9VS7IJmeg80fNAcViYQ sn2PaRSYMC1X0nqOzpqOzYW5LIArSEehrr/Z085gOjNi/2rkDwSD3WGGXgUdSZRZ 10gRLoRE/CZw212CNZi0AV0GT7Zw5jizpJt4kh5Zn/RnrdxHCtSMaTJpIbOYhmca FQJfcLRp5unSUooOY1PREESA4tpaUy9kz4dgttnCPnq8DLeshkD5xMAloAFR13li TBeG/tqHKjNUZT5oLUSLxs9EXnG9LTLB+lJ4C0sdY6KW7Ad7SMzymTWSnjeYHxp+ 4FDhqGhrJwrBC3Gh63YLTLXALc2NBQ5s32trpSPV5wgAj2LKcSiiBxXh8LgjT+Em mGYIgs6drCwowBi/A6RDxA7kdnMVT9cSk6XjMIQjb0mG3JGnNYWEjRHx+5P4ZlsM tfv153RAbRaGCOSoJ8pm2NOmaGs7wgTv9yKRUGIFzROWsPOTx+Q1UGnurIFFa9LG lU42EXsIa7lzxsCgNx8vXqonTwRPinspfRUea/URgbCkIpnyVSIkFXujY+HAdRRo V8WRxq6Rm78YNMigt3lim7NLmYIk8K3CAz92+q5oRolIgCbqwN6dGHpJSDLBoKX8 7nFQQsrFOh5lSv/ZO0upjuye0JJTwU1yzcYRH7B0r2aMzxxMWu0ZB6kilq/RaDp9 nNLpAVHBo6oXX5j8+2k22F2vZVSTUl1SJgKahHOzTUQTK+rIESX5XTwJctJ0Eb/c jjaHV3GDZSGZBK6Ib+Ez+4SIqXZg26d5bnXbBS/iHL2baErZE4sFzEf8JsYbq3ZO 5Xk3eBURiLwwrl3ftu2O7/Mv6AUFyYSaWJWanYPMGm0I3NDYmaMWWIRPRD6wE32R bklG/xvktnLkp75nk0FKqVPXlci0aeAzxVYvsvd9CnkcDxeEi3WdLRlyhE5xsLRv CL4KpQzw7d6Rg2TZ0kn7gHYmS0HJHLDf7VrUndLcDMjiF/wrBfxH/ZsfIKxmfzMd LgIWYefwVWndpejO5FMlzl+7NFFy+Uc036iWUXcfScbyChujdYRGyyJy8B9zJmhf pBescXTzjpCp7yySmz11FpBUNpfA6Bg44T8t2ERlNMae4ZuL+U25y8E0QgiUJTHe guDWpdhxLESXRi7TF9D0k0DWWguUAsJlioQJZDRMZze+pLOwMa0bdgqbJFMexQQk IKs9rzobcM1a0aeIEyytCiVdDiEmcc/PEwJ7yDaZ7aQvknP92p9xDZl0flzlLbbp 6bjxHySKV13QKoE1ymmsZjqLqqLlHLDz3lOs2gb0ZEG64N/8grRimGCOhNj+U7pH rvuBR3lJMFyjI8MKmEPViupXXoYr8tDQC+f11CccT5IS65gqJ5pwNDBRU4BMkg6A 7Z7wnNvZzt5aNKW+tYYqknR//qTpEYgFCxoEp24n =CB7d —–END PGP MESSAGE—–  

[DFS #0] HDFS论文解读

[DFS #0] HDFS论文解读

参考论文: The Hadoop Distributed File System 分布式文件系统HDFS作为HBase的下层服务,以及众多存储服务的支持项目,已经被广泛使用,下面通过解读上述论文来记录并介绍一下HDFS的架构,以及功能,还有设计 整体架构 Overview 如图所示     每一个HDFS集群由一个NameNode,多个DataNode,以及BackupNode, CheckpointNode组成,上图中的三角形为使用HDFS的客户端,客户端和DataNode之间的线表示客户端到DataNode的物理距离,对于这个架构,有下面几点要说的 一个集群的NameNode只有一个,客户端想要使用这个HDFS的时候,一定是先和NameNode进行交流,获得需要的DataNode信息之后,才能和DataNode进行通信 因为NameNode只有一个,所以NameNode如果出现单点故障可就不好玩惹,而且对于存储这种要求数据一致性很高的系统,也不能容忍NameNode出故障系统就瘫痪这种情况,因而使用CheckpointNode和BackupNode对NameNode进行备份,他们的区别和备份方式下文会详细说 NameNode不会主动去和DataNode通信,他们之间的通信是这样的: DataNode每隔一定时间发送heartbeat到NameNode(默认3s)(通知NameNode他还活着可以干活=w=(划掉 ,然后NameNode在这个时候会将要发送到DataNode的指令通过Response的形式发送到DataNode Client对数据的操作精简来看,无非是读写两种,当Client想要读取HDFS的数据的时候,首先Client先去询问NameNode,哪些DataNode有他要的数据,并且选择距离他最近的DataNode,然后Client直接连接距离最近的DataNode并获取数据 e.g: 如上图的ClientA想要获取一个数据,且数据在DataNode A B C内都有存放,那么ClientA首先要和NameNode进行通信,获得DataNode列表(ordered by distance to the client)然后选择距离它最近的DataNode B进行通信获取数据 当Client想要向一个文件写入数据的时候(无论文件存不存在),其他的Client会无法对此文件进行写入操作(以此来保证文件不会因为同时写而corrupt data)写入完毕之后,会将Block进行Replica复制到不同的DataNode上(默认为复制3份),具体会在下面介绍   模块 & 术语 NameNode HDFS Namespace ,是存储着所有DataNode以及每一个DataNode上的文件的元信息的一个目录结构,NameNode通过inode的方式来表示每一个文件和文件夹。Namespace 就可以理解为Linux的目录树的inode list,每一个inode指向一个datablock,datablock存在datanode上 HDFS将整个Namespace放在RAM内,完整的文件系统信息(包含inode信息,以及每一个inode对应的Datablock list 元信息)称为Image, Image持久存储在NameNode本地存储里,称为一个Checkpoint, NameNode同时维护了数据操作的日志journal DataNode 显然,这就是数据真正存放的地方,每一个Datablock由两个文件组成,该Block的数据,和该Block的[checksum,创建时间]信息组成的元数据 如下图 一个占3个Block的文件存放在DataNode里的情况简图,该文件有三个block,每一个block的信息含有Data & MetaData,三个Block组成了整个文件file1, 然后在NameNode的某一个inode存储着信息对应着文件名file1,block数3,物理位置在该DataNode上 DataNode的Startup   当DataNode Startup时,会和NameNode进行handshake,进行namespaceID(每一个HDFS都有一个唯一的NamespaceID,在创建HDFS的时候就确定了)&version的认证,二者必须均与NameNode完全一致,如果不一致的话,该DataNode就会停止工作。保证了不会因为错误的NameNode或者软件版本不兼容而导致数据出问题, 如果这个DataNode没有保存任何Namespace信息,说明这是一个新的DataNode,没有任何Block数据,因而允许加入此HDFS cluster。 当DataNode握手成功之后,会register自己到该NameNode,如果为第一次加入该NameNode,则会被NameNode分配一个唯一的StorageID,并且永远不会改变,DataNode会将此ID持久存在自己的storage中,这个StorageID保证了就算IP变动或者端口变动,NameNode仍然可以识别该DataNode的身份 DataNode与NameNode的通信 Block Report: Block Report是DataNode用于通知NameNode自己所持有的Block的信息(如blockid,block大小,generation stamp)的一种数据,因为这个数据是会随时改变的,所以需要定期发送Block Report给NameNode,使得NameNode能得到整个Block分布的信息。当DataNode注册到NameNode时,会立即发送一个Block Report,之后会每隔一段时间(1h)发送一次BlockReport HeartBeat:  DataNode通过定期的心跳与NameNode进行通信,使NameNode确认DataNode存活,并且同时carry其他信息,如存储可用量,目前正在传输的数据量等信息,用于NameNode进行负载均衡。 NameNode则在收到DataNode心跳,对DataNode进行Response的时候进行通信,可以发送的指令有: 将自己持有的数据块复制到其他DataNode 移除该DataNode上的数据块 重新注册、或者停止该DataNode 使DataNode立即发送一个Block Report Block Scanner 每一个DataNode都有一个BlockScanner,周期性地对Block的完整性进行认证 当Block…

Read More Read More

Effective Go & GoFAQ 阅读笔记

Effective Go & GoFAQ 阅读笔记

Effective go: https://golang.org/doc/effective_go.html Go FAQ: https://golang.org/doc/faq 下面是对以上两篇文章内相关内容的记录与解释/总结 Interface 某一个 type “implement” 这个 interface 的话,只要实现这个interface的全部方法即可 不过这里有一些容易产生误区的地方,看下面这个例子   type T int interface Equaler { Equal(Equaler) bool } Equaler是一个interface, 下面看这两个例子 func (t T) Equal(u T) bool { return t == u } type T并没有实现Equaler interface 因为参数类型不是 Equaler 而是一个具体的类型 T 这个问题很容易理解, 试想一下其他某一个type implement了Equaler类型(假设为Q) 而 t.Equal(Q) 是不合法的 因为Q不是T类型, 所以 T 并没有实现Equaler这个interface 因为Equaler接口要求只要满足type为Equaler就都可以作为参数传递给Equal 下面这个才是T implement Equaler的例子 func (t T) Equal(u T) bool { return t == u.(T) }   interface 的 value = nil 不代表interface为nil, interface的结构为type, value两部分 下面这个代码永远会返回错误…

Read More Read More

APUE 3e 部分习题整理 Chap5

APUE 3e 部分习题整理 Chap5

Chapter5 5.1 使用setvbuf实现setbuf 根据 man手册 setbuf(FILE *stream, char *buf) 中如果指定 buf == NULL 那么就是关闭 buf,  如果指定 buf != NULL 那么就创建一个 BUFSIZ 大小的 buffer 供流使用 因而实现的代码如下 // 5.1 Answer void mysetbuf(FILE *stream, char *buf) { setvbuf(stream, buf, buf ? _IOFBF :_IONBF, BUFSIZ); } 5.5 对标准I/O流如何使用fsync fsync 需要的参数是 fd 描述符,因而只要能获得文件 FILE 结构体的 fd 值即可 这里一定要注意: 在使用fsync的时候一定要fflush流的缓冲区 fsync是将内核里的缓存数据写入磁盘/文件, 而对于打开的文件 是全缓冲的,也就是说没有写满IO缓冲区之前是不会去写入内核缓冲区的 因而就算调用fsync也没有什么用呢~ 你需要先把数据从 IO buffer中写入内核buffer然后fsync才有用 所以一定要fflush   P.S.:天真的窝以为这题只是考察能不能把FILE结构体给找到,并拿出来相应的fileno,没想到我太天真了=o= #include<stdio.h> #include<unistd.h> int fsync_stream(FILE *stream); int main(void) { FILE *fp = fopen(“demo.txt”, “w+”); fprintf(fp, “I love…

Read More Read More

tmux 终端效率利器

tmux 终端效率利器

重度终端使用者的话如果没有一个好的终端多任务管理的工具是非常痛苦的, tmux是一个非常好用的终端多任务多session多窗口管理工具 功能十分强大 具体的介绍可以看这里 https://raw.githubusercontent.com/tmux/tmux/master/FAQ 效果图     tmux的manpage十分长,不是所有的功能都会常用到,这里有一个cheatsheet记录了常用的功能 https://tmuxcheatsheet.com/ tmux-powerline 非常美观实用的一个tmux工具 github repo  https://github.com/erikw/tmux-powerline 下面是各种个人配置的tip 修改tmux默认Ctrl b为其他键位 set-option -g prefix C-a 修改tmux窗口的名字 并保持名字不会更改 echo “export DISABLE_AUTO_TITLE=true” >> ~/.zshrc 然后source配置文件让设置生效 在tmux中开启新的窗口的时候,默认以最初启动tmux的时候的路径开启,这样很不方便,配置~/.tmux.conf让其以当前目录创建新的窗口和分割,增加如下三行配置 bind c new-window -c “#{pane_current_path}” bind ‘”‘ split-window -c “#{pane_current_path}” bind % split-window -h -c “#{pane_current_path}” 向所有当前window的pane(窗口)内输入同样的指令 :set-option synchronize-panes on/off  

[Docker] 新建一个Docker Image并push到dockerhub

[Docker] 新建一个Docker Image并push到dockerhub

Preface 软件开发测试过程中的环境配置一直是令人头疼的事情,Docker正是为了解决这种问题而诞生的一套工具,现在已经发展成为了一个生态,使用Docker,可以轻松的部署你的项目,并且保证不同slave机器的环境配置完全一致,当你提交一个patch(commit)之后,想要测试项目的运行的时候, 只需要docker run <your-image>就可以轻松的搭建好项目运行环境,并且访问配置好的服务器端口,就可以访问到刚刚修改后的项目了~ 同时docker结合DroneCI TravisCI等CI平台,使得软件测试也变得十分容易 NEUOJ的健壮性测试,就是在自建的私有DroneCI服务器上运行的 但是因为之前我是直接使用的centos的镜像,没有进行修改,所以之前我们每一次运行测试,都需要下载一大堆软件包,然后才开始运行代码测试, 既费时又费流量(每一次都需要安装200MB的东西) 因而自己新建一个Docker镜像包含这些所有的软件包能省去很多时间以及流量 新建一个Docker镜像 使用docker build命令可以轻松的创建Docker Image 创建docker image需要Dockerfile, Dockerfile描述了这个image要用到的base镜像, 你可以从一个已经存在的镜像开始创建, 也可以Build From Scratch Dockerfile的每一个指令的格式如下 INSTRUCTION args 常用的INSTRUCTION有 FROM: 表示镜像的base是什么,scratch的话表示无base RUN: 执行Shell命令,并将结果打包到images中 CMD: docker run images的时候执行的命令 MAINTAINER: 维护者 以下是一个示例Dockerfile # NEUOJ Test Script Ver1.0 FROM centos:7 MAINTAINER VOID001 <[email protected]> #- uname -a RUN yum install wget -y RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm RUN yum install git -y RUN yum install openssh-clients -y RUN rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm # Add php7 Source RUN yum repolist…

Read More Read More