2015年(100)
分类: LINUX
2015-06-04 07:04:18
/* namespaces */ struct nsproxy *nsproxy;该结构体的定义如下:
/* * A structure to contain pointers to all per-process * namespaces - fs (mount), uts, network, sysvipc, etc. * * The pid namespace is an exception -- it's accessed using * task_active_pid_ns. The pid namespace here is the * namespace that children will use. * * 'count' is the number of tasks holding a reference. * The count for each namespace, then, will be the number * of nsproxies pointing to it, not the number of tasks. * * The nsproxy is shared by tasks which share all namespaces. * As soon as a single namespace is cloned or unshared, the * nsproxy is copied. */ struct nsproxy { atomic_t count; struct uts_namespace *uts_ns; struct ipc_namespace *ipc_ns; struct mnt_namespace *mnt_ns; struct pid_namespace *pid_ns_for_children; struct net *net_ns; };其中第一个属性count表示的是该命名空间被进程引用的次数。后面的几个分别是不同类型的命名空间。以pid_namespace为例。 其结构如下所示:
struct pid_namespace { struct kref kref;//引用计数 struct pidmap pidmap[PIDMAP_ENTRIES];//用于标记空闲的id号 struct rcu_head rcu; int last_pid;//上一次分配的id号 unsigned int nr_hashed; struct task_struct *child_reaper;//相当于全局的init进程,用于对僵尸进程进行回收 struct kmem_cache *pid_cachep; unsigned int level;//namespace的层级 struct pid_namespace *parent;//上一级namespace指针 #ifdef CONFIG_PROC_FS struct vfsmount *proc_mnt; struct dentry *proc_self; #endif #ifdef CONFIG_BSD_PROCESS_ACCT struct bsd_acct_struct *bacct; #endif struct user_namespace *user_ns; struct work_struct proc_work; kgid_t pid_gid; int hide_pid; int reboot; /* group exit code if this pidns was rebooted */ unsigned int proc_inum; };内核中的pid结构表示:
struct pid { atomic_t count; unsigned int level;//pid对应的级数 /* lists of tasks that use this pid */ struct hlist_head tasks[PIDTYPE_MAX];//一个pid可能对应多个task_struct struct rcu_head rcu; struct upid numbers[1];//该结构是namespace中的具体的pid,从1到level各级别的namesapce,这里相当于一个指针,只不过不需要再分配空间 };上面的结构体就是内核中进程的标示符,可以用于标识内核中的tasks、process groups和sessions。这个结构体和具体的task通过hash来关联,通过具体的task对应的pid的值可以获得绑定的pid结构体。 属于具体的namespace的pid结构upid:
struct upid { /* Try to keep pid_chain in the same cacheline as nr for find_vpid */ int nr; struct pid_namespace *ns; struct hlist_node pid_chain; };该结构体是用来获得结构体pid的具体的id,它只对特定的namespace可见。会通过函数find_pid_ns(int nr,pid_namespace *ns)函数来获得具体的PID结构。 整体结构如下图:
yan@yan-Z400:/sys/fs/cgroup$ ls blkio cpu cpuset freezer memory systemd cgmanager cpuacct devices hugetlb perf_event可以看到cgroup的不同子系统目录。 在CPU文件夹中新建一个geekcome目录,默认ubuntu已经将子系统全部挂载了: 进入cpu文件夹新建一个geekcome文件夹,然后查看:
yan@yan-Z400:/sys/fs/cgroup/cpu$ ls cgroup.clone_children cgroup.sane_behavior cpu.shares lxc tasks cgroup.event_control cpu.cfs_period_us cpu.stat notify_on_release cgroup.procs cpu.cfs_quota_us geekcome release_agent新建文件夹后在文件夹里会自动生成相应的文件:
geekcome ├── cgroup.clone_children ├── cgroup.event_control ├── cgroup.procs ├── cpu.cfs_period_us ├── cpu.cfs_quota_us ├── cpu.shares ├── cpu.stat ├── notify_on_release └── tasks下面就跑一个死循环程序,导致CPU使用率到达100%。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND yan 20 0 25928 4848 2324 R 100.0 0.1 0:22.47 python现在执行如下的命令:
echo "50000" >/sys/fs/cgroup/cpu/geekcome/cpu.cfs_quota_us echo "5046" >/sys/fs/group/cpu/geekcome/tasks再top查看一下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND yan 20 0 25928 4844 2324 R 49.8 0.1 0:49.27 python进程5046的cpu使用率从100%降低到50%。在Cgroup里,可以使用cpu.cfs_period_us和cpu.cfs.quota_ua来限制在单位时间里可以使用的cpu时间。这里cfs的含义是Completely Fair Scheduler(完全公平调度器)。cpu.cfs_period_us是时间周期,默认是100000(百毫秒)。cpu.cfs_quota_us是在这期间可以使用的cpu时间,默认-1(无限制)。 在上面的实例中,通过修改cpu.cfs_period_us文件,将百毫秒修改为一半,成功将CPU使用率降低到50%。cfs.quota_us文件主要对于多核的机器,当有n个核心时,一个控制组的进程最多能用到n倍的cpu时间。 Cgroup除了资源控制功能外,还有资源统计功能。云计算的按需计费可以通过它来实现。这里只实例CPU的控制,其他的子系统控制请自行实验。
lxc-create -n name [-f config_file] [-t template] sudo lxc-create -n ubuntu01 -t ubuntu-n就是虚拟机的名字,-t是创建的模板,保存路径在/usr/lib/lxc/templates。模板就是一个脚本文件,执行一系列安装命令和配置(穿件容器的挂载文件系统,配置网络,安装必要软件,创建用户并设置密码等)。
lxc-ls
lxc-start -n name [-f config_file] [-s KEY=VAL] [command]启动一个容器,可以指定要执行的命令,如果没有指定,lxc-start会默认执行/sbin/init命令,启动这个容器。
lxc-stop -n name
lxc-execute -n name [-f config_file] [-s KEY=VAL ] [--] command它会按照配置文件执行lxc-create创建容器,如果没有指定的配置文件,则选择默认。该命令一般用于快速使用容器环境执行摸个任务,任务执行完毕后删除掉容器。 (完)