linux 笔记 / 2.文件系统

上一篇介绍了分区格式,相比于主流的分区格式 MBR 和 GPT,文件系统的格式要多很多。

在完成磁盘分区后,每个空白的分区就是给操作系统保存文件的仓库,操作系统为了管理文件需要以特定的格式保存文件,这个格式需要支持文件的读写,检索,权限,日志记录等功能,也就是为操作系统提供管理磁盘空间以及其中的文件的机制。

下表列举了常用操作系统使用的文件系统。

文件系统 开发者发布年份原操作系统
FAT32Microsoft1996Windows 95
exFATMicrosoft2006Windows CE 6.0 / XP SP3 / Vista SP1
NTFSMicrosoft1993Windows NT 3.1
ext4开源2006Linux
HFS+Apple1998Mac OS 8.1
常见的文件系统

常见文件系统的特性

分区格式最大单个文件最大支持分区
FAT324G2TB
exFAT127 PB64 ZB
NTFS16 EB16 EB
ext416 TB1 EB
HFS+8 EB8 EB
常见文件系统特性,在不同簇大小以及不同版本上上述参数可能会不一样,且部分数据仅为理论值


1ZB = 1024EB,1EB = 1024PB,1PB = 1024TB,1TB = 1024GB

FAT (File Allocation Table)

FAT文件系统系列包括 FAT、FAT16、FAT32 和 exFAT ,目前仍旧常见的是FAT32 和 exFAT,源于它良好的兼容性目前在U盘上用的比较多。其中exFAT 就是一种适用于闪存的文件系统。2019年8月,微软公开了exFAT 的技术文档,并支持将 exFAT 功能集成到 Linux内核中。Linux内核于版本5.4中提供初步支持。

NTFS (New Technology File System)

NTFS 包含多个版本,最早为 1993 年发布的 1.0 版本,以及最新的于 Window XP 发布的 3.1 版本,对应系统中 NTFS.sys 文件的版本号 5.1,需要注意区别。
在 linux 系统上,完整并安全的对 NTFS 的读写功能由 NTFS-3G 驱动程序提供。这是一个由 Tuxera 公司开发并维护的自由软件项目,采用GNU通用公共许可证发布,旨在为非微软Windows NT 系的操作系统提供安全快速、具备读写功能的NTFS文件系统驱动程序。

ext (extended filesystem)

ext 系列文件系统包括 ext、ext2、ext3 和 ext 4。其中的 ext或ext1 发表于1992年4月,它是第一个利用虚拟文件系统实现出的文件系统,在linux核心0.96c版中首次加入支持,最大可支持2GB的文件系统。后续版本特性如下表,

名称开发者发布时间最大文件最大分区
ext2Rémy Card19932TB32TB
ext3Stephen Tweedie19992TB32TB
ext4多人[1]200616 TB1 EB

其中 ext4 于 2008年12月25日在 Linux 2.6.29 版公开发布之后成为 Linux 官方建议的默认文件系统。

参考资料
文件系统的对比 – 维基百科,自由的百科全书 (wikipedia.org)
NTFS – 维基百科,自由的百科全书 (wikipedia.org)
exFAT – 维基百科,自由的百科全书 (wikipedia.org)
ext4 – 维基百科,自由的百科全书 (wikipedia.org)

linux 笔记 / 1.磁盘分区

本文的内容并不特定于 linux,只是作为后续学习的一个基础。

一块磁盘需要分区后才能被操作系统使用,那么分区具体是什么样的呢?
目前两种最主流的分区格式是 MBR(Master Boot Record) 和 GPT(GUID Partition Table)。下面这张表说明了两种分区格式的主要特点。

分区分区数量最大分区容量始于固件支持
MBR4个主分区+扩展分区2TiB1983BIOS
GPT128个主分区512B扇区磁盘8ZiB
4KB扇区磁盘64ZiB
20世纪90年代后期UEFI

在创建特定的分区后会在磁盘上写入分区表信息,其中 MBR 分区表的长度为512字节,从磁盘的0柱面,0磁头,1扇区开始写入。在这512字节的数据中,前446字节为引导程序代码,之后的64字节即为MBR的分区信息,最后还有两位结束标志(55AA)。具体可参考下面两张图,一张为MBR位于磁盘位置示意,另一张为MBR数据结构图。

磁盘数据结构示意
MBR数据结构

在介绍 GPT 格式之前先介绍 LBA 概念,磁盘的一个扇区为512字节,现在由于 4K 扇区磁盘的出现,所以引入逻辑区块地址(LBA, Logical Block Address)概念, LBA 在一般磁盘是 512字节,在 4K 磁盘上就是 4K。
GPT 使用34个LBA来记录信息,其中的第一部分 LAB0 为 Protectiv MBR, 这块区域是为了提供最基本的向后兼容 ,不至于在旧系统上让系统认为这块磁盘还未被分区,以减少意外删除。
之后的LAB1称为 Primary GPT Header,它保存了磁盘以及分区表的信息。之后的 LBA2~LAB34 都用于保存分区表,每个LBA 可保存四个分区信息,总共可保存128个分区的信息。

GPT 分区信息格式
Primary GPT Header 数据结构

对于GPT分区信息相对于 MBR 有一点比较特殊,GPT 分区会在磁盘的尾部,即 LBA-1 至 LBA-34 备份一份 GPT 分区信息以提高分区信息的完整性和健壮性。

GPT 分区信息的 bootloader code 并不是保存在分区信息中的,对于作为启动盘的 GPT 磁盘会有一个专门的 EFI 分区来保存启动程序。

除了 MBR 和 GPT,还有一些历史上的或者并不常见的分区格式,有兴趣的可参考下图再深入研究。

参考资料:
MBR VS GPT | What’s the Difference and Which Is Better – EaseUS
GUID Partition Table – Wikipedia
Where is the bootloader located in GPT-based drives? – Quora

web存储技术简要

web 的浏览器端存储技术主要是 cookie,localStorage, sessionStorage, indexedDB, webSQL。

技术名称访问对象 大小限制
cookiedocument.cookie4KB
localStoragewindow.localStorage5MB(chrome)
sessionStoragewindow.sessionStorage5MB(chrome)
indexedDBwindow.indexedDB通常为2GB

其中 cookie 可通过服务器 set-cookie 响应标头进行设置;sessionStorage 存储的内容在用户关闭页面或浏览器窗口后被清楚;localStorage 和 sessionStorage 是协议敏感的,也就是说在分别使用 http 和 https 访问时, localStorage 和 sessionStorage 都是隔离的。

websql 并不是 w3c 的标准,不过chrome,edge 浏览器都是支持的, 它以 sqlite 作为后端的存储技术。

参考资料:
https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
https://developer.mozilla.org/zh-CN/docs/Web/API/Storage
https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API

输出 EF Core 执行的 sql 语句

首先引入 Microsoft.Extensions.Logging.Debug 包,然后在 DbContext 类中的 OnConfiguring 方法中添加如下代码:

public static readonly LoggerFactory LoggerFactory = new LoggerFactory(new[] { new DebugLoggerProvider() });  

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    //...
    optionsBuilder.UseLoggerFactory(LoggerFactory);
    //
}

这样在启动调试的时候,就可以在 Visual Studio 底部的调试输出中看到 EF Core 执行 sql 的信息了。

一行代码笔记-1

1.efcore 指定实体某个属性不更新

_db.Entry(note).Property(n => n.CreatedTime).IsModified = false;

2.去除input元素选中时的黑框(edge浏览器)

input {outline:none;}

3.angularjs 非上下文中获取 $scope 对象

$("[ng-app=mainApp]").scope()

4.powershell 重启网卡代码

#$net_adapter_name 为网卡/适配器名称
Get-NetAdapter -Name $net_adapter_name | Restart-NetAdapter

javascript 中 const,var,let 的区别

  • var,声明作用域为所在上下文即当前函数或全局范围的变量。
  • let,声明作用域为所在代码块的变量。
  • const,与 let 类似,但 const 声明变量的引用不能改变。

在ES6非严格模式下使用 let 声明的全局变量,不会成为window的属性。

参考资料:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const

k3s 中 let’s encrypt 配置示例

k3s 中默认使用 traefik,默认通过 helmchart config 来配置 traefik,配置文件需要放在目录 /var/lib/rancher/k3s/server/manifests/ , 推荐在该目录中添加配置文件 traefik-config.yaml,完整目录 /var/lib/rancher/k3s/server/manifests/traefik-config.yaml,k3s 会在该文件变更后自动重新部署 traefik。

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    securityContext: #指定traefik运行上下文以保证能正常访问 acme.json文件
      readOnlyRootFilesystem: true
      runAsGroup: 1000
      runAsNonRoot: true
      runAsUser: 1000
    deployment:
      additionalVolumes: # 添加用于保存 acme.json 的PVC
        - name: acme-storage
          persistentVolumeClaim:
            claimName: acme-pvc
    additionalVolumeMounts: # 添加用于保存 acme.json 的volumemount
      - name: acme-storage
        mountPath: /acme
    certResolvers:
      letsencrypt: #定义 letsencrpty证书resolvers
        email: example@email.com
        dnsChallenge:
          provider: tencentcloud #以dnspod为例
        storage: /acme/acme.json
    env: #用于 tencentcloud dnschallenge 所需的环境变量
      - name: TENCENTCLOUD_SECRET_ID
        value: idxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      - name: TENCENTCLOUD_SECRET_KEY
        value: keyxxxxxxxxxxxxxxxxxxxxxxxxxxx

关于更多的 dnsChallenge provider 可参考该文档: Traefik Let’s Encrypt Documentation – Traefik

traefik 配置完成后只需在 ingress route 中做如下简单配置便可使用 let’s encrypt 证书

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: argocd-websecure-ir
  namespace: xxxx
spec:
  entryPoints:
  - websecure
  tls:
    certResolver: letsencrypt # 指定certResolver

腾讯云主机遇到的 ipv6 连接问题

在使用腾讯云主机时多次碰到 ipv6 连接问题,多次在技术人员的支持下,目前比较快速稳定的解决方案是在 netplan 的配置文件中添加如下配置,针对的服务器镜像版本是 Ubuntu 22.04,配置文件为 /etc/netplan/50-cloud-init.yaml

# network: {config: disabled}
network:
    version: 2
    ethernets:
        eth0:
            dhcp4: true
            match:
                macaddress: 52:xx:00:xx:xx:12
            set-name: eth0
            nameservers:
                addresses: [183.60.83.19,183.60.82.98]
            addresses:
                - 2402:xxxx:xxxx:xxxx:0:xxxx:6e0f:xxxx/128 #实例面板中的ipv6地址
            gateway6: fe80::feee:ffff:feff:ffff #网关地址,联系技术人员获取

Visual Studio 调试 Doker 笔记

  • visual studio 在启动docker调试时不会使用dockerfile去生成镜像
  • 检查容器的环境变量是要考虑到base镜像中设置的环境变量
  • 调试时若需要设置容器环境变量可在launchSettings.json中的Docker段进行设置
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
      "environmentVariables": {
        "ASPNETCORE_URLS": "http://+:5000"
      },
      "publishAllPorts": true
    }