您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何進行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 的流程
// 在這個函數根據參數 *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; }
// 根據 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(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;
在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)
在 ./configure 階段 加--prefix /home/cld 就可以指定動態鏈接庫的路徑 為 /home/cld/var/lxcfs/liblxcfs.so
上述內容就是如何進行lxcfs read /proc/meminfo源碼流程的解析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。