【问题标题】:How do you swap /dev/sda with /dev/sdb? [closed]如何将 /dev/sda 与 /dev/sdb 交换? [关闭]
【发布时间】:2013-08-27 15:59:18
【问题描述】:

男孩,就是这样。一种。琐碎的。问题,但似乎没有人能够正确回答。

如何将 /dev/sda 与 /dev/sdb 交换?

有人可以建议使用永久标签(例如 /dev/disk/by-* ),但尽管本意是最好的,但这确实回答了这个问题。是的,永久性标签适用于您可以使用它们的地方,但如果程序被硬编码以使用例如。 /dev/sda,这个问题仍然存在。

为了进一步说明我在互联网上发现的问题: http://ubuntuforums.org/showthread.php?t=1569238&page=2(让我想起了'幸灾乐祸')

这个小伙子似乎找到了解决方案,只是没有分享(嘘!): http://ubuntuforums.org/showthread.php?t=944515

而且,我也有类似的潜在危险。我使用 CloneZilla,如果一个程序问:Would you like to backup /dev/sda to /dev/sdb or /dev/sdb to /dev/sda ?,猜猜我知道 linux 似乎是随机分配磁盘顺序时有多紧张。我还没有用自己的备份覆盖我的数据,但这只是等待发生。

Linux 中是什么将 /dev/sd* 分配给磁盘,你如何影响这个过程?这与 udev (/etc/udev/, udevadm) 有关系吗?我的操作系统是 CentOS,但对于 Ubuntu 和 CloneZilla (http://clonezilla.org),我也需要知道这一点,而且这个问题发生在所有系统上,所以我的猜测是这个问题与发行版无关,而是与内核有关,内核模块,或者非常接近内核的东西。请帮忙!

------------------ 编辑:2013 年 8 月 25 日 在建议 ypnos 提供的链接后,我通读了一遍,尝试了一个命令,内核只是在我的屏幕上“呕吐”了 udev 规则。然后提示输入root密码以允许维护,或退出以重新启动。这证明这东西确实不适合新手。

我也查了一下。我不明白 linux 内核如何或何时加载,但互联网上的几条消息表明 BIOS(不管你信不信)正在将可引导磁盘列表传递给 grub,然后使用 device.map 文件将哪些设备分配给哪些 grub (hd*,)。注意 /dev/sd 在这个阶段已经被定义了,因为你可以使用永久的开发符号链接。这些设备映射似乎以某种方式传递到实际的根文件系统。那么现在这是引导加载程序吗?

回到 udev 作为一个潜在的解决方案,我在 google http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=578826 上发现了一个错误报告,导致解决方案不建议更改 udev NAME(我们知道最终将变为 /dev/sd*它)。

对于建议的 udev MAN 页面:

| The following keys can get values assigned:
| 
| NAME
|  The name of the node to be created, or the name the network
|  interface should be renamed to.
   NOTE: changing the kernel-provided name of device nodes
   (except for network devices) is not supported and can result
   in unexpected behavior.
   Today, the kernel defines the device nodes names, and udev
   is expected to only manage the node's permissions and
   additional symlinks.

...但无论如何我还是以稍微改变的方式去做了。

# vi /etc/udev/rules.d/00-corrections.rules

KERNEL=="sd?", ATTRS{model}=="SAMSUNG SP0411N", NAME="sda"
KERNEL=="sd??", ATTRS{model}=="SAMSUNG SP0411N", NAME="sda%n"
KERNEL=="sda", ATTRS{model}!="SAMSUNG SP0411N", NAME="sdb"
KERNEL=="sda?", ATTRS{model}!="SAMSUNG SP0411N", NAME="sdb%n"

本质上,它的作用是“如果型号是三星,则将其指定为 NAME sda*。如果型号不是三星,但已指定为 sda*,则将其指定为 NAME sdb*。”这条规则尽可能地放在所有其他规则之前。请注意,我对此不确定,因为似乎也有一些“不可见”的规则文件,并且尽管您已重命名设备,但“内核加载内存”中某处的内核仍可能引用错误。当您查看 /var/log/boot.log 文件时,这可能很明显,在我的例子中,它的开头说:

%G      Welcome to [0;36mCentOS[0;39m 
Starting udev: %G[60G[[0;32m  OK  [0;39m]Setting hostname UncleFloServer:  [60G[[0;32m  OK  [0;39m]ERROR: asr: seeking device "/dev/sda" to 5999998795264
ERROR: ddf1: seeking device "/dev/sda" to 5999998795264
ERROR: ddf1: seeking device "/dev/sda" to 5999998664192
ERROR: hpt45x: seeking device "/dev/sda" to 5999998790144
ERROR: isw: seeking device "/dev/sda" to 5999998794752
ERROR: jmicron: seeking device "/dev/sda" to 5999998795264
ERROR: lsi: seeking device "/dev/sda" to 5999998795264
ERROR: nvidia: seeking device "/dev/sda" to 5999998794752
ERROR: pdc: seeking device "/dev/sda" to 137438913024
ERROR: pdc: seeking device "/dev/sda" to 137438920192
ERROR: pdc: seeking device "/dev/sda" to 137438927360
ERROR: pdc: seeking device "/dev/sda" to 137438934528
ERROR: sil: seeking device "/dev/sda" to 5999998795264
ERROR: via: seeking device "/dev/sda" to 5999998795264
Setting up Logical Volume Management:   No volume groups found
[60G[[0;32m  OK  [0;39m]Checking filesystems
_CentOS-6.4-x86_: clean, 85517/655360 files, 662649/2621440 blocks
/dev/sda1: clean, 56/65536 files, 33367/262144 blocks
[60G[[0;32m  OK  [0;39m]Remounting root filesystem in read-write mode:  [60G[[0;32m  OK  [0;39m]Mounting local filesystems:  [60G[[0;32m  OK  [0;39m]Enabling local filesystem quotas:  [60G[[0;32m  OK  [0;39m]Enabling /etc/fstab swaps:  [60G[[0;32m  OK  [0;39m]

在这里,我的三星设备是 40GB(我想要 /dev/sda),而我的大型 Areca Raid 是 6TB(我想要 /dev/sdb)。

还有一些问题

  1. 这些错误是什么意思?

  2. 这些错误是内核的原因,还是在我的 udev 的 00-corrections.rules 之前仍在运行的规则文件的原因?

  3. 这些错误是否表明存在数据威胁? Areca 分区在我的 fstab 中的一个文件夹上安装没有问题。

  4. 有没有更好、更早的设备分配方法?

【问题讨论】:

  • 实际上,这听起来确实非常接近我的需要。但是如何使用呢? en.wikipedia.org/wiki/Udev
  • 对不起,我忘了提:除了提到的错误之外,我在 8 月 25 日的编辑中最终描述的 00-corrections.rules 似乎有效。
  • 与其尝试使用 udev 获得稳定的设备名称,通常使用标签或 ID 来挂载文件系统而不是设备名称更容易。 (或者使用也有静态命名的 lvm 卷)。

标签: linux linux-kernel device


【解决方案1】:

如今,Linux 内核根据 UDEV 规则动态填充 /dev/。

让我先解释一下设备文件的工作原理。每个设备文件,通常是块设备文件,都有一个主设备号和一个次设备号。这些数字实际上描述了文件指向的设备。名称在其中没有任何作用。让我们看看我们的磁盘的具体情况:

# ls -l sd*
brw-rw---- 1 root disk 8, 0 Aug 22 15:45 sda
brw-rw---- 1 root disk 8, 1 Aug 22 15:45 sda1
brw-rw---- 1 root disk 8, 2 Aug 22 15:45 sda2
brw-rw---- 1 root disk 8, 3 Aug 22 15:45 sda3
brw-rw---- 1 root disk 8, 5 Aug 22 15:45 sda5
brw-rw---- 1 root disk 8, 6 Aug 22 15:45 sda6

在这里您可以看到我的第一个磁盘有多个分区,并且我在 8 月 22 日下午 3 点启动,这是内核根据规则创建文件的时间。您还可以看到主编号为 8,次编号用于访问分区(0 指向整个磁盘)。每行开头的 'b' 表示其中每一个都是一个特殊的“块设备”文件。

正如我所说,内核“这些天”动态地创建文件。它并不总是这样,在其他 Unix 系统上也不像那样。在那里,文件将被静态创建,并且用户将创建或操作这些文件。

完全可以使用您自己的名称和主要/次要编号创建您自己的设备文件。请参阅 mknod (man mknod)。但是,再次启动后,您的自定义文件将消失。

第二种可能性是更改 UDEV 规则。这些规则将在系统引导期间进行处理,并保证您的行为永久一致。可以在此处找到有关这些规则的良好指南:http://www.reactivated.net/writing_udev_rules.html

您将看到,在给定与您的设备匹配的特定硬件信息的情况下,可以定义创建“sda*”的规则。您将需要用您的规则替换将创建 sda 的原始规则。其工作原理取决于您的发行版。

由于我认为这对新手来说是一项危险的业务,因此我不会向您解释具体步骤;我上面链接的文档将为您提供所需的所有信息,您确实应该阅读所有内容。

【讨论】:

  • 请注意,我会废弃 CloneZilla 并使用 dd 代替。然后就可以使用by-label等方式,灵活,简单,没有麻烦。克隆分区很容易!您甚至可以将 dd 与 nc 结合使用来远程克隆...
  • 我一直在阅读一些关于 udev 的内容,我认为这个答案是正确的,是的。让我们不讨论我为什么使用 CloneZilla,而是简单地说:您至少需要一个操作系统来运行 dd。我可以安装第二个操作系统,但也很有可能将该操作系统用于其他用途。 Clonezilla 安装在一个单独的分区中,它以人类可读的格式(除了 /dev/sd*)提出正确的问题,它非常可靠,而且它就在那里。虽然你说得有道理,但我更喜欢这个而不是使用 dd 和 CD 操作系统来备份我的宝贵数据。
  • 如果你开始弄乱 UDEV,那么 dd 已经是小菜一碟了。你也可以在分区上抛出类似grml.org 的东西。使用 dd :-)。
  • 你希望这很容易。根据bugs.debian.org/cgi-bin/bugreport.cgi?bug=578826,建议在 udev 规则手册中添加名称分配:注意:不支持更改内核提供的设备节点名称(网络设备除外),并且可能导致意外行为。今天,内核定义了设备节点名称,而 udev 预计只管理节点的权限和附加符号链接。 所以它不是 udev,它又是内核中的其他东西。我尝试分配名称,它给出了一堆规则尝试和错误,然后内核崩溃。
  • 好的,我尝试了以下方法:# vi /etc/udev/rules.d/00-corrections.rules\nKERNEL=="sd?", ATTRS{model}=="SAMSUNG SP0411N", NAME="sda"\n KERNEL=="sd??", ATTRS{model}=="SAMSUNG SP0411N", NAME="sda%n"\n KERNEL=="sda", ATTRS{model}!="SAMSUNG SP0411N", NAME="sdb"\n KERNEL=="sda?", ATTRS{model}!="SAMSUNG SP0411N", NAME="sdb%n" 时间会证明这是否可靠以及是否适用于其他操作系统。我会写一个更详细的指南。
【解决方案2】:

我在交换sdasdb 磁盘名称时遇到了同样的问题。我尝试在我自己的 HP 服务器上用上述帖子编写一些类似的 udev 规则。但是我在/etc/udev/rules.d/00-corrections.rules使用了磁盘的大小

KERNEL=="sd?", ATTR{size}=="781357232", NAME="sda"
KERNEL=="sd??", ATTRS{size}=="781357232", NAME="sda%n"
KERNEL=="sda", ATTR{size}=="3125515952", NAME="sdb"
KERNEL=="sda?", ATTRS{size}=="3125515952", NAME="sdb%n"

在此规则之前,我通过cat /sys/block/sda/sizecat /sys/block/sdb/size 找到设备的大小,如下所述:Finding information from sysfs

但是当我尝试通过 udevadm test /sys/block/sdb 测试 udev 规则时,我在输出中看到了这一行:

NAME="sda" 被忽略,内核设备节点不能重命名;请在 /etc/udev/rules.d/00-corrections.rules:1 中修复它

我有 ubuntu 18.04,我发现 这是不可能的(至少在 ubuntu 18.04 中)基于这篇文章:Is there a way to change device names in /dev directory?

【讨论】:

    【解决方案3】:

    请不要听我的回答。

    如果您不知道自己在做什么,您可能无法恢复地杀死您的数据,如果您需要这个答案,您可能不需要。

    ...但是如果您出于某种原因真的没有其他方法,那么您可以这样做。注意:几十年来我没有遇到一个需要它的案例。

    因此,Linux 内核中的设备不是通过它们的路径来识别的,而是通过它们的主要和次要编号来识别的。例如,ls -l /dev/sda 表示:

    brw-rw-rw- 1 user group 8, 0 Nov 26 20:53 /dev/sda
    

    8,0 是主要和次要数字。 sdb 有主次编号8,16

    您可以使用mknod 命令创建设备文件,因此

    mknod /dev/sda b 8 16; mknod /dev/sdb b 8 0
    

    将根据需要(重新)创建设备文件。

    如果您在 chroot-ed(容器化)环境中执行此操作,风险会小得多,只有您的问题应用可以看到这些被覆盖的设置。

    【讨论】:

      【解决方案4】:

      为什么不使用 UUID 而不是依赖动态分配?标清?始终是动态的,而 UUID 是固定值且不会更改,即使您更改、发行版或将硬盘驱动器安装在其他 Linux 机器上,UUID 也是相同的。

      sudo blkid 将向您显示 UUID,然后您可以在 fstab 上使用它来将分区挂载到您想要的任何位置。

      【讨论】:

      • OP 明确指出某些程序需要使用 /dev/sd# 分配。在不依赖 /dev/sd# 分配的情况下将特定 UUID 挂载到文件系统挂载点(例如在 /etc/fstab 中)时,您的建议很有用。 OP 希望直接控制 /dev/sd# 分配。
      【解决方案5】:

      据我所知,这是不可能的。系统将选择 SATA 端口 1 作为 SDA,依此类推。但是,您可以使用 smartctl 来识别 SDA/B 的序列号或在可能的情况下使驱动器 LED 闪烁。

      【讨论】:

      • 我的系统根据我插入驱动器的顺序分配了 sda、sdb、stc 等。它们与 SATA 端口完全不同。
      猜你喜欢
      • 1970-01-01
      • 2014-04-06
      • 2022-01-27
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多