中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行lxcfs read /proc/meminfo源碼流程的解析

發布時間:2021-12-28 15:11:19 來源:億速云 閱讀:421 作者:柒染 欄目:云計算

本篇文章為大家展示了如何進行lxcfs read /proc/meminfo源碼流程的解析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

git repo: https://git-sa.nie.netease.com/whale/lxcfs

首先,lxcfs作為用戶態的文件系統,所有對文件的操作定義在 lxcfs.c

const struct fuse_operations lxcfs_ops = {
 .getattr = lxcfs_getattr,
 .readlink = NULL,
 .getdir = NULL,
 .mknod = NULL,
 .mkdir = lxcfs_mkdir,
 .unlink = NULL,
 .rmdir = lxcfs_rmdir,
 .symlink = NULL,
 .rename = NULL,
 .link = NULL,
 .chmod = lxcfs_chmod,
 .chown = lxcfs_chown,
 .truncate = lxcfs_truncate,
 .utime = NULL,

 .open = lxcfs_open,
 .read = lxcfs_read,
 .release = lxcfs_release,
 .write = lxcfs_write,

 .statfs = NULL,
 .flush = lxcfs_flush,
 .fsync = lxcfs_fsync,

 .setxattr = NULL,
 .getxattr = NULL,
 .listxattr = NULL,
 .removexattr = NULL,

 .opendir = lxcfs_opendir,
 .readdir = lxcfs_readdir,
 .releasedir = lxcfs_releasedir,

 .fsyncdir = NULL,
 .init = NULL,
 .destroy = NULL,
 .access = lxcfs_access,
 .create = NULL,
 .ftruncate = NULL,
 .fgetattr = NULL,
};

此處我們分析一個完整的讀 /proc/meminfo 的流程

lxcfs_read

// 在這個函數根據參數 *path 判斷,執行 do_cg_read 還是 do_proc_read
static int lxcfs_read(const char *path, char *buf, size_t size, off_t offset,
  struct fuse_file_info *fi)
{
 int ret;
 fprintf(stderr, "lxcfs_read ...... path: %s\r\n", path);
 if (strncmp(path, "/cgroup", 7) == 0) {
  up_users();
  ret = do_cg_read(path, buf, size, offset, fi);
  down_users();
  return ret;
 }
 if (strncmp(path, "/proc", 5) == 0) {
  up_users();
  ret = do_proc_read(path, buf, size, offset, fi);
  down_users();
  return ret;
 }

 return -EINVAL;
}

do_proc_read --> proc_read

// 根據 fuse_file_info判斷 f->type 執行對 proc_meminfo_read、proc_cpuinfo_read、proc_uptime_read、proc_stat_read、proc_diskstats_read、proc_swaps_read、proc_loadavg_read 相應的文件進行讀操作 
int proc_read(const char *path, char *buf, size_t size, off_t offset,
  struct fuse_file_info *fi)
{
 struct file_info *f = (struct file_info *) fi->fh;
 fprintf(stderr, "proc_read  ...... path: %s, file_info: %c \r\n", path, f->type);
 switch (f->type) {
 case LXC_TYPE_PROC_MEMINFO:
  return proc_meminfo_read(buf, size, offset, fi);
 case LXC_TYPE_PROC_CPUINFO:
  return proc_cpuinfo_read(buf, size, offset, fi);
 case LXC_TYPE_PROC_UPTIME:
  return proc_uptime_read(buf, size, offset, fi);
 case LXC_TYPE_PROC_STAT:
  return proc_stat_read(buf, size, offset, fi);
 case LXC_TYPE_PROC_DISKSTATS:
  return proc_diskstats_read(buf, size, offset, fi);
 case LXC_TYPE_PROC_SWAPS:
  return proc_swaps_read(buf, size, offset, fi);
 case LXC_TYPE_PROC_LOADAVG:
  return proc_loadavg_read(buf, size, offset, fi);
 default:
  return -EINVAL;
 }
}

proc_meminfo_read

proc_meminfo_read(char *buf, size_t size, off_t offset,
  struct fuse_file_info *fi)

 // 如果在容器中 cat /proc/meminfo,這里的 initpid為容器/sbin/init 進程號,
 // 如果在主機中 cat /usr/local/var/lib/lxcfs/proc/meminfo  initpid為主機的進程號1, 這里getpid為lxcfs進程號
 fprintf(stderr, "proc_meminfo_read .... initpid:%d, pid:%d, getpid:%d \r\n", initpid, fc->pid, getpid());
 cg = get_pid_cgroup(initpid, "memory");

 fprintf(stderr, "proc_meminfo_read .... CG: %s\n", cg);
 if (!cg)
  return read_file("/proc/meminfo", buf, size, d);
 prune_init_slice(cg);

 // 獲取cgroup目錄及其子目錄中 memory.limit_in_bytes的最小值
 memlimit = get_min_memlimit(cg, "memory.limit_in_bytes");
 if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", &memusage_str))
  goto err;
 if (!cgfs_get_value("memory", cg, "memory.stat", &memstat_str))
  goto err;

... 
  中間省略各種 meminfo數據獲取并計算的邏輯
...

 // 打印結果就是cat取到的內容
 fprintf(stderr, "proc_meminfo_read .... buf: %s\n", buf);
 rv = total_len;

get_min_memlimit

在bindings.c 實現了所有 proc_meminfo_read、proc_cpuinfo_read、proc_uptime_read、proc_stat_read、proc_diskstats_read、proc_swaps_read、proc_loadavg_read的邏輯。

//獲取cgroup目錄及其子目錄中 memory.limit_in_bytes的最小值
static unsigned long get_min_memlimit(const char *cgroup)
{
 char *copy = strdupa(cgroup);
@@ -2951,12 +2952,20 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
 pid_t initpid = lookup_initpid_in_store(fc->pid);
 if (initpid <= 0)
  initpid = fc->pid;
  
    //如果在容器中cat /proc/meminfo,則這里initpid為容器/sbin/init進程號,如果在主機中cat /usr/local/var/lib/lxcfs/proc/meminfo
    //initpid為主機的進程號1,  這里的getpid為lxcfs進程號
 cg = get_pid_cgroup(initpid, "memory");
 
 if (!cg)
  return read_file("/proc/meminfo", buf, size, d);
  prune_init_slice(cg);
 memlimit = get_min_memlimit(cg); //獲取cgroup目錄及其子目錄中 memory.limit_in_bytes的最小值
 if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", &memusage_str))
  goto err;
 if (!cgfs_get_value("memory", cg, "memory.stat", &memstat_str))

 d->size = total_len;
 if (total_len > size ) total_len = size;
 memcpy(buf, d->buf, total_len);
  //打印結果就是cat獲取到的內容
    //fprintf(stderr, "zy test .....buf:%s\n", buf);
 rv = total_len;
err:
 if (f)

修改lxcfs的動態鏈接庫路徑的方法

在 ./configure 階段 加--prefix /home/cld 就可以指定動態鏈接庫的路徑 為 /home/cld/var/lxcfs/liblxcfs.so

上述內容就是如何進行lxcfs read /proc/meminfo源碼流程的解析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

伊川县| 常德市| 禹城市| 白河县| 宜兰市| 北辰区| 那坡县| 孟州市| 建平县| 灵寿县| 那坡县| 辽阳市| 宜宾县| 屯留县| 西华县| 成安县| 南平市| 德钦县| 尼勒克县| 霍山县| 丹凤县| 义乌市| 巫溪县| 黄山市| 谷城县| 醴陵市| 潮安县| 黄冈市| 永城市| 金山区| 饶河县| 扎鲁特旗| 黑山县| 阿鲁科尔沁旗| 黔西县| 怀化市| 宁波市| 潞西市| 桐柏县| 麦盖提县| 新蔡县|