文件或目录所在的设备

文件或目录所在的设备

如何识别文件或目录所在的设备?

有一个 stat 模块
结果中有一个“inode 所在的设备”

如何映射“inode 所在的设备”到分区?

答案1

首先需要了解inode 是什么设备?stat命令输出中的设备号

然后,作为示例调试输出

TASK [debug] *****
ok: [localhost] =>
  result:
    changed: false
    failed: false
    stat:
...
      dev: 2051

有一个2051十进制的设备 ID,但我们需要十六进制的。根据如何将十进制字符串转换为十六进制字符串?

  - debug:
      msg: "{{ '%#x' % result.stat.dev }}"

会报告

TASK [debug] *****
ok: [localhost] =>
  msg: '0x803'

这需要分为主要(8)和次要(3)设备。也许从

"{{ ('%#x' % result.stat.dev).split('x') | last }}"

在其他任务中,需要收集

~/test$ ls -al /dev/sd*
brw-rw----. 1 root disk 8,  0 Feb 29 00:01 /dev/sda
brw-rw----. 1 root disk 8,  1 Feb 29 00:01 /dev/sda1
brw-rw----. 1 root disk 8,  2 Feb 29 00:01 /dev/sda2
brw-rw----. 1 root disk 8,  3 Feb 29 00:01 /dev/sda3
brw-rw----. 1 root disk 8,  4 Feb 29 00:01 /dev/sda4
brw-rw----. 1 root disk 8,  5 Feb 29 00:01 /dev/sda5
brw-rw----. 1 root disk 8, 16 Feb 29 00:01 /dev/sdb
brw-rw----. 1 root disk 8, 32 Feb 29 00:01 /dev/sdc
brw-rw----. 1 root disk 8, 33 Feb 29 00:01 /dev/sdc1

并进行相应的解析,因为ansible_facts.device_links ansible_facts.devices我们不收集和保存此类信息。

仅依靠lsblk --output格式化的基础设施来获取必要的信息可能会更容易。

lsblk -o NAME,MAJ:MIN,MOUNTPOINT
NAME   MAJ:MIN MOUNTPOINT
sda      8:0
├─sda1   8:1   /boot/efi
├─sda2   8:2   /boot
├─sda3   8:3   /
├─sda4   8:4   /tmp
└─sda5   8:5   [SWAP]
sdb      8:16  /var/lib/pgsql/16/data
sdc      8:32
└─sdc1   8:33  /var
sr0     11:0

或者根据如何获取文件的设备/分区名称?只是

cat /proc/partitions
major minor  #blocks  name

  11        0    1234567 sr0
   8       32   12345678 sdc
   8       33   12345678 sdc1
   8        0  123456789 sda
   8        1     123456 sda1
   8        2     123456 sda2
   8        3   12345678 sda3
   8        4   12345678 sda4
   8        5    1234567 sda5
   8       16    1234567 sdb

从这里我们可以看到Major 8 (SCSI)和Minor 3是/dev/sda3。并且“如何找出主要数字背后的内容?",参见示例Linux:主设备号和次设备号或者分区的主编号和次编号

示例任务文本文件中的零填充字段

  - name: Gather Custom Fact - Partition major minor numbers
    shell:
      cmd: |
        tail -n +3 /proc/partitions | awk '{ printf "%s: %02i%02i\n", $4,$1,$2 }'
    check_mode: false
    changed_when: false
    register: partmajmin

  - debug:
      var: (partmajmin.stdout | from_yaml)

将导致输出

TASK [debug] *********************
ok: [localhost] =>
  (partmajmin.stdout | from_yaml):
    sda: 0800
    sda1: 0801
    sda2: 0802
    sda3: 0803
    sda4: 0804
    sda5: 0805
    sdb: 0816
    sdc: 0832
    sdc1: 0833
    sr0: 1100

这些数字也可以转换为整数,如下所示

  - debug:
      var: (partmajmin.stdout | from_yaml).sda3 | int(base=16)

输出结果为

TASK [debug] ************************************************
ok: [localhost] =>
  (partmajmin.stdout | from_yaml).sda3 | int(base=16): '2051'

最后,一个任务

  - name: Device an inode can reside on
    debug:
      msg: "{{ item.key }}"
    loop: "{{ lookup('dict', (partmajmin.stdout | from_yaml)) }}"
    loop_control:
      label: "{{ item.value | int(base=16) }}"

将报告

TASK [Device an inode can reside on] ******
ok: [localhost] => (item=2099) =>
  msg: sdc1
ok: [localhost] => (item=2098) =>
  msg: sdc
ok: [localhost] => (item=2052) =>
  msg: sda4
ok: [localhost] => (item=1100) =>
  msg: sr0
ok: [localhost] => (item=2053) =>
  msg: sda5
ok: [localhost] => (item=2050) =>
  msg: sda2
ok: [localhost] => (item=2048) =>
  msg: sda
ok: [localhost] => (item=2070) =>
  msg: sdb
ok: [localhost] => (item=2049) =>
  msg: sda1
ok: [localhost] => (item=2051) =>
  msg: sda3

答案2

补充:对于次要编号,必须取编号的最后两位


文件:/path/to/file1
linux stat:device 8/1
ansible 设备统计:dev: 2049

2049 (十进制) = 801 (十六进制) --> 8. 01--> 8/ 01(十六进制) = 8/ 1(十进制)


文件:/path/to/file2
linux stat:device 259/2
ansible 设备统计:dev: 66306

66306 (十进制) = 10302 (十六进制) --> 103. 02--> 103/ 02(十六进制) = 259/ 2(十进制)


文件:/path/to/file3
linux stat:device 254/1
ansible 设备统计:dev: 65025

65025 (十进制) = FE01 (十六进制) --> FE. 01--> FE/ 01(十六进制) = 254/ 1(十进制)


文件:/path/to/file4
linux stat:device 0/45
ansible 设备统计:dev: 45

45 (十进制) = 2D (十六进制) --> 0. 2D--> 0/ 2D(十六进制) = 0/ 45(十进制)

相关内容