当前位置: 首页 > news >正文

中山网站建设文化公司做网站要主机还是服务器

中山网站建设文化公司,做网站要主机还是服务器,互联网行业数据分析,网站建设前端技术一、简介 Docker 内核实现容器的功能用了linux 内核中的三个特性 Namespace、Cgroup、UnionFs#xff0c;今天我们来说一下UnionFs。 linux UnionFs 实现的是overlay 文件系统 OverlayFs 文件系统分为三层#xff0c; lower 是只读层 Upper 是可读写 Merged 是 lower 和U…一、简介 Docker 内核实现容器的功能用了linux 内核中的三个特性 Namespace、Cgroup、UnionFs今天我们来说一下UnionFs。 linux UnionFs 实现的是overlay 文件系统 OverlayFs 文件系统分为三层 lower 是只读层 Upper 是可读写 Merged 是 lower 和Upper 合并的目录 挂载方式可以使用mount 命令挂载 mount -t overlay overlay -o lowerdirlower1:lower2,upperdirupper,workdirwork merged 二、源码分析 1.挂载overlay 设备初始化 当我们使用 mount -t overlay overlay -o lowerdirlower1:lower2,upperdirupper,workdirwork merged linux 内核层overlay 结构体声明类型 static struct file_system_type ovl_fs_type {.owner THIS_MODULE,.name overlay,.fs_flags FS_USERNS_MOUNT,.mount ovl_mount,.kill_sb kill_anon_super, }; 当我们使用overlay设备的时候会触发结构体上挂载的mount函数指针这个函数触发linux内核中的ovl_mount static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags,const char *dev_name, void *raw_data) {return mount_nodev(fs_type, flags, raw_data, ovl_fill_super); } 核心是使用ovl_fill_super填充overlay 文件系统的超级块申请一个ovl_fs,然后填充到 sb-s_fs_info ofs; 详细代码: static int ovl_fill_super(struct super_block *sb, void *data, int silent) {struct path upperpath { };struct dentry *root_dentry;struct ovl_entry *oe;struct ovl_fs *ofs;struct ovl_layer *layers;struct cred *cred;char *splitlower NULL;unsigned int numlower;int err;// 如果当前用户的namespace不是超级块的ns那么返回错误 -EIOerr -EIO;if (WARN_ON(sb-s_user_ns ! current_user_ns()))goto out;// 目录操作结构体赋值sb-s_d_op ovl_dentry_operations;err -ENOMEM;// 申请ovl_fs并且对ovl_fs进行填充ofs kzalloc(sizeof(struct ovl_fs), GFP_KERNEL);if (!ofs)goto out;err -ENOMEM;ofs-creator_cred cred prepare_creds();if (!cred)goto out_err;/* Is there a reason anyone would want not to share whiteouts? */ofs-share_whiteout true;ofs-config.index ovl_index_def;ofs-config.uuid true;ofs-config.nfs_export ovl_nfs_export_def;ofs-config.xino ovl_xino_def();ofs-config.metacopy ovl_metacopy_def;// 装载选项err ovl_parse_opt((char *) data, ofs-config);if (err)goto out_err;err -EINVAL;if (!ofs-config.lowerdir) {if (!silent)pr_err(missing lowerdir\n);goto out_err;}err -ENOMEM;splitlower kstrdup(ofs-config.lowerdir, GFP_KERNEL);if (!splitlower)goto out_err;err -EINVAL;numlower ovl_split_lowerdirs(splitlower);if (numlower OVL_MAX_STACK) {pr_err(too many lower directories, limit is %d\n,OVL_MAX_STACK);goto out_err;}err -ENOMEM;layers kcalloc(numlower 1, sizeof(struct ovl_layer), GFP_KERNEL);if (!layers)goto out_err;ofs-layers layers;/* Layer 0 is reserved for upper even if theres no upper */ofs-numlayer 1;sb-s_stack_depth 0;sb-s_maxbytes MAX_LFS_FILESIZE;atomic_long_set(ofs-last_ino, 1);/* Assume underlying fs uses 32bit inodes unless proven otherwise */if (ofs-config.xino ! OVL_XINO_OFF) {ofs-xino_mode BITS_PER_LONG - 32;if (!ofs-xino_mode) {pr_warn(xino not supported on 32bit kernel, falling back to xinooff.\n);ofs-config.xino OVL_XINO_OFF;}}/* alloc/destroy_inode needed for setting up traps in inode cache */sb-s_op ovl_super_operations;if (ofs-config.upperdir) {struct super_block *upper_sb;err -EINVAL;if (!ofs-config.workdir) {pr_err(missing workdir\n);goto out_err;}err ovl_get_upper(sb, ofs, layers[0], upperpath);if (err)goto out_err;upper_sb ovl_upper_mnt(ofs)-mnt_sb;if (!ovl_should_sync(ofs)) {ofs-errseq errseq_sample(upper_sb-s_wb_err);if (errseq_check(upper_sb-s_wb_err, ofs-errseq)) {err -EIO;pr_err(Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n);goto out_err;}}err ovl_get_workdir(sb, ofs, upperpath);if (err)goto out_err;if (!ofs-workdir)sb-s_flags | SB_RDONLY;sb-s_stack_depth upper_sb-s_stack_depth;sb-s_time_gran upper_sb-s_time_gran;}oe ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers);err PTR_ERR(oe);if (IS_ERR(oe))goto out_err;/* If the upper fs is nonexistent, we mark overlayfs r/o too */if (!ovl_upper_mnt(ofs))sb-s_flags | SB_RDONLY;if (!ofs-config.uuid ofs-numfs 1) {pr_warn(The uuidoff requires a single fs for lower and upper, falling back to uuidon.\n);ofs-config.uuid true;}if (!ovl_force_readonly(ofs) ofs-config.index) {err ovl_get_indexdir(sb, ofs, oe, upperpath);if (err)goto out_free_oe;/* Force r/o mount with no index dir */if (!ofs-indexdir)sb-s_flags | SB_RDONLY;}err ovl_check_overlapping_layers(sb, ofs);if (err)goto out_free_oe;/* Show indexoff in /proc/mounts for forced r/o mount */if (!ofs-indexdir) {ofs-config.index false;if (ovl_upper_mnt(ofs) ofs-config.nfs_export) {pr_warn(NFS export requires an index dir, falling back to nfs_exportoff.\n);ofs-config.nfs_export false;}}if (ofs-config.metacopy ofs-config.nfs_export) {pr_warn(NFS export is not supported with metadata only copy up, falling back to nfs_exportoff.\n);ofs-config.nfs_export false;}if (ofs-config.nfs_export)sb-s_export_op ovl_export_operations;/* Never override disk quota limits or use reserved space */cap_lower(cred-cap_effective, CAP_SYS_RESOURCE);sb-s_magic OVERLAYFS_SUPER_MAGIC;sb-s_xattr ofs-config.userxattr ? ovl_user_xattr_handlers :ovl_trusted_xattr_handlers;sb-s_fs_info ofs;sb-s_flags | SB_POSIXACL;sb-s_iflags | SB_I_SKIP_SYNC;// 把 overlay 文件系统的根目录设置到 upperDir里err -ENOMEM;// 创建root的inode并且指向新建的inode对象root_inoderoot_dentry ovl_get_root(sb, upperpath.dentry, oe);if (!root_dentry)goto out_free_oe;mntput(upperpath.mnt);kfree(splitlower);sb-s_root root_dentry;return 0;out_free_oe:ovl_entry_stack_free(oe);kfree(oe); out_err:kfree(splitlower);path_put(upperpath);ovl_free_fs(ofs); out:return err; } 操作overlay 文件系统的目录操作结构体实现: static const struct dentry_operations ovl_dentry_operations {.d_release ovl_dentry_release,.d_real ovl_d_real,.d_revalidate ovl_dentry_revalidate,.d_weak_revalidate ovl_dentry_weak_revalidate, }; 数据结构图: 参考网址: Linux源码剖析——OverlayFS 源码分析_linux overlay-CSDN博客 2、描述符操作结构体  如果你做过kernel module 读过linux设计实现.就很容易理解了 描述符操作结构体定义: const struct file_operations ovl_dir_operations {.read generic_read_dir,.open ovl_dir_open,.iterate ovl_iterate,.llseek ovl_dir_llseek,.fsync ovl_dir_fsync,.release ovl_dir_release, };当我们使用linux 系统调用打开overlay 设备文件的时候会触发操作结构体的函数 open 函数: static int ovl_dir_open(struct inode *inode, struct file *file) {struct path realpath;struct file *realfile;struct ovl_dir_file *od;enum ovl_path_type type;od kzalloc(sizeof(struct ovl_dir_file), GFP_KERNEL);if (!od)return -ENOMEM;type ovl_path_real(file-f_path.dentry, realpath);realfile ovl_dir_open_realfile(file, realpath);if (IS_ERR(realfile)) {kfree(od);return PTR_ERR(realfile);}od-realfile realfile;od-is_real ovl_dir_is_real(file-f_path.dentry);od-is_upper OVL_TYPE_UPPER(type);file-private_data od;return 0; } struct ovl_dir_file {bool is_real; // 是否需要合并bool is_upper; // 是否需要从upper读取struct ovl_dir_cache *cache; // 缓存目录struct list_head *cursor; // 遍历游标struct file *realfile; // 真实文件struct file *upperfile; // overlay 里 在upper目录所在位置 }; 这里主要做的操作是初始化ovl_dir_file并且把他挂载到万能指针private_data中。 读的操作是通过getdents我们看迭代器 static int ovl_iterate(struct file *file, struct dir_context *ctx) {struct ovl_dir_file *od file-private_data;struct dentry *dentry file-f_path.dentry;struct ovl_cache_entry *p;const struct cred *old_cred;int err;old_cred ovl_override_creds(dentry-d_sb);if (!ctx-pos)ovl_dir_reset(file);//是否需要读取真实路径if (od-is_real) {// 不需要合并直接读取真实路径/** If parent is merge, then need to adjust d_ino for .., if* dir is impure then need to adjust d_ino for copied up* entries.*/if (ovl_xino_bits(dentry-d_sb) ||(ovl_same_fs(dentry-d_sb) (ovl_is_impure_dir(file) ||OVL_TYPE_MERGE(ovl_path_type(dentry-d_parent))))) {err ovl_iterate_real(file, ctx);} else {err iterate_dir(od-realfile, ctx);}goto out;}// 创建目录缓存if (!od-cache) {struct ovl_dir_cache *cache;cache ovl_cache_get(dentry);err PTR_ERR(cache);if (IS_ERR(cache))goto out;od-cache cache;ovl_seek_cursor(od, ctx-pos);}// 直接把合并后的目录缓存遍历返回用户层while (od-cursor ! od-cache-entries) {p list_entry(od-cursor, struct ovl_cache_entry, l_node);if (!p-is_whiteout) {if (!p-ino) {err ovl_cache_update_ino(file-f_path, p);if (err)goto out;}}/* ovl_cache_update_ino() sets is_whiteout on stale entry */if (!p-is_whiteout) {if (!dir_emit(ctx, p-name, p-len, p-ino, p-type))break;}od-cursor p-l_node.next;ctx-pos;}err 0; out:revert_creds(old_cred);return err; }
http://www.dnsts.com.cn/news/133581.html

相关文章:

  • 网站的布局怎么做深圳网站设计推荐刻
  • 哪个网站免费h5模板多房屋竣工验收备案表网上查询
  • 网站开发 会员模块国内最好的视频剪辑培训机构
  • 有名设计网站温州高端网站建设公司
  • 怎么建立网站 个人热点网站建设平台有哪些 谢谢平台建站
  • 企业网站建设是什么90设计是免费下载吗
  • 最大的地方门户网站源码h5企业网站只做
  • 网站地图 wordpress利用网络媒体营销来做电商网站论文
  • 丰润网站建设现在什么网站做推广比较好
  • 企业网站建设晋升嘉兴网站建设公司电话
  • 网站域名登录做防护用品的网站
  • 国内精美网站农林牧渔行业网站建设
  • 网站怎么做展现量安徽做网站公司哪家好
  • 做公司中文网站需要注意什么怎么查有做网站的公司
  • 专业购物网站建设设计服务网络建设方案
  • 做大数据和网站开发的前景网站做百度竞价利于百度优化
  • vs做网站添加背景linux服务器怎么做网站
  • 有什么网站可以免费做图长沙房地产交易中心
  • 做网站给不给源代码wordpress网站程序
  • 芜湖市建设厅网站个人网站怎么命名
  • 网站建设w亿码酷1流量订制网页设计模板图片并排显示
  • 免费设计app的网站建设wordpress菜单图教
  • 网站改版重新收录wordpress头像本地化0字节
  • 知名网站建设公司电话服装公司电商网站建设规划
  • 网站建设地基本流程企业如何做网站建站
  • 东莞网站公司建设网站十万pv的网站建设
  • 网站被黑刚恢复排名又被黑了哈尔滨网站设计
  • 焦作做网站优化wordpress建立视频网站
  • 手机网站建设liedns海南网站建设中心
  • 好的网站设计机构河南免费网站建设