我使用 ZFS 已经有一段时间没有问题了。我仍然对此感到兴奋,我非常信任它。但是时不时会出现新的问题(尤其是在阅读了一些文档之后,有时会增加而不是减少问题的数量)。
在这种情况下,我向根池添加了一个新的 vdev(镜像),因此已阅读 zpool 手册 ( man zpool
)。在本节的末尾zpool add
,它指出:
-o 属性=值
设置给定的池属性。有关可以设置的有效属性列表,请参阅“属性”部分。目前唯一支持的属性是 ashift。请注意,某些属性(其中包括 ashift)不是从以前的 vdev 继承的。它们是特定于 vdev 的,而不是特定于池的。
这意味着该ashift
属性不是特定于池的,而是特定于 vdev 的。但是我找不到任何命令或选项可以让我查看每个 vdev 的属性(或任何其他 vdev 特定属性)。
换句话说,例如,如果我有一个池,其中包含一个 vdev withashift=12
和一个 vdev with ashift=10
,我如何验证这一点?
我已经尝试过的:
root@cerberus:~# zpool list -v -o ashift rpool
ASHIFT
12
mirror 928G 583G 345G - 27% 62%
ata-ST31000524NS_9WK21HDM - - - - - -
ata-ST31000524NS_9WK21L15 - - - - - -
mirror 928G 74.4M 928G - 0% 0%
ata-ST31000524NS_9WK21FXE …
Run Code Online (Sandbox Code Playgroud) 请考虑采用标准安装和配置的 Linux 系统sudo
;即root
可以以其他用户的身份执行所有命令,请考虑以下命令:
sudo -u user1 -g group1 some_program
Run Code Online (Sandbox Code Playgroud)
当然,我希望使用 EUID和EGIDsome_program
执行。然而,我经过惨痛的教训才知道,只有当实际上是;的成员时,这才有效。我真的应该更深入地研究一下。从命令行选项的解释来看:user1
group1
user1
group1
man sudo
-g
[...] 只要未使用 -P 选项,sudoers 策略就允许通过 -g 选项指定任何目标用户组。
这是非常不方便的。我经常用于sudo
测试目的,特别是当服务或程序在任意 UID 和 GID 下运行时,相应的用户不是相应组的成员。在这种情况下,在使用 进行测试之前sudo
,我必须使相应的用户成为相应组的成员,并且一定不要忘记在测试完成后恢复该操作。
因此问题是:是否存在允许使用不匹配的任意 UID 和 GID 执行程序的root
设置或配置?我只对为所有程序、UID 和 GID提供通用机制的解决方案感兴趣。也就是说,将特定程序、UID 或 GID 的列表放入其中不是一个选项。sudo
/etc/sudoers
一种可能的解决方案可能是替代政策提供者,以sudo
实现这一点。然而,学习如何安装和配置它可能会非常困难,而且我不确定我是否会采取这条路线,即使没有其他解决方案。而且,到目前为止我还没有发现这样的事情。
更新1 (2022-01-27)
相关系统运行 Debian buster,在撰写本文时已更新了所有可用补丁。未安装SELinux 。这是我的文件(只/etc/sudoers
留下注释和空行):
Defaults env_reset
Defaults mail_badpass
Defaults …
Run Code Online (Sandbox Code Playgroud) 我已经在 ZFS 上成功设置了 Debian 伸展,包括根文件系统。事情按预期进行,我认为我已经理解了基本概念 - 直到我重新阅读了 Sun 的 ZFS 文档。
我的场景是:
我想防止(更准确地说:检测)无声位腐烂
目前,我已经设置了一个带有一个 vdev 的根池,它是两个相同磁盘的镜像
当然,我确实打开(即没有关闭)校验和
现在我遇到了这个文件。在页面的末尾,他们显示了zpool status
示例配置的命令输出,
[...]
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
c1t0d0 ONLINE 0 0 0
c1t1d0 OFFLINE 0 0 0 48K resilvered
[...]
Run Code Online (Sandbox Code Playgroud)
接着是声明:
READ 和 WRITE 列提供设备上发生的 I/O 错误的计数,而 CKSUM 列提供设备上发生的不可纠正的校验和错误的计数。
首先,在这种情况下,“设备”是什么意思?他们是在谈论物理设备、vdev 还是其他东西?我的假设是他们正在谈论层次结构中的每个“设备”。vdev 错误计数器可能是其物理设备的错误计数器的总和,而池错误计数器可能是其 vdev 的错误计数器的总和。这样对吗?
其次,不可纠正的校验和错误是什么意思?这是一个我认为在谈论物理磁盘时通常使用的术语,无论是与从盘片到磁盘电子设备的数据传输有关,还是与磁盘上物理扇区的校验和或从磁盘端口(SATA、SAS、 ...)到主板(或控制器)。
但我真正感兴趣的是 ZFS 级别(而不是硬件级别)是否存在校验和错误。我目前确信 CKSUM 正在展示后者(否则,它没有多大意义),但我想确定。
第三,假设他们谈论的校验和错误确实是ZFS级别(而不是硬件级别)的校验和错误,为什么他们只显示不可纠正错误的数量?这没有任何意义。我们希望看到每个校验和错误,无论是否可以纠正,不是吗?毕竟,校验和错误意味着磁盘上存在某种硬件未检测到的数据损坏,因此我们可能希望在出现 …
读完有关zpool export
in的部分后man zpool
,我有点担心:
从系统导出给定的池。所有设备都标记为导出,但仍被其他子系统视为正在使用。只要存在足够数量的设备,设备就可以在系统(甚至是不同字节序的系统)之间移动和导入。
“但仍被其他子系统认为正在使用”是什么意思?“只要有足够数量的设备”是什么意思?
背景:
我有一个相当复杂的备份脚本,它基于 ZFS 快照将生产服务器上的虚拟机存储复制到备用服务器(准确地说,它是主机和虚拟机中的各种脚本的系统,它们协同工作以冻结文件VM 中的系统,获取 ZFS 快照,解冻 VM 中的文件系统,并将快照复制到备用服务器)。这部分工作起来就像一个魅力。
但实际上,除了复制之外,我还需要一种备份。也就是说,我想将虚拟机存储备份到磁盘上,然后我可以将其从所连接的盒子中取出,并将其安全地存储在另一个位置。
我仔细思考了最好的方法,并得出以下想法:
** 这是我不喜欢的步骤(在阅读了上面引用的部分之后)。一方面,在导出 ZPOOL(它是唯一的设备)后移除 HDD 应该没有问题,因为文件系统在导出之前已被卸载(并因此被刷新)。另一方面,手册上说,即使在导出池之后,该 HDD 仍将“被其他子系统视为正在使用”,这使我相信在这种情况下简单地删除它是一个坏主意。
因此,我想知道这个说法的确切含义,以及如何使其他子系统不再使用该硬盘。
**** 我知道我必须为此付出一些努力。该计划是创建一个脚本以及适当的udev
规则,以使备用服务器识别何时插入 HDD 并导入现有的 ZPOOL(HDD 将通过 SATA-3 或 SAS 12G 直接连接,而不是通过 USB)。但这不是这个问题的一部分。
总结一下:
确切地说 …
我的 bash 知识有点生疏(以前也不是很扎实),所以我似乎无法找到以下问题的答案:
正如标题所说,我想知道如何确定命令执行后的非零退出代码是由 bash(表示真正的错误)还是由命令(可能表示错误,取决于命令)设置和我的目的)。
例如,让我们看看以下非常简单的脚本:
#!/bin/bash
string='abc'
grep 'd' <<< "$string"
echo $?
Run Code Online (Sandbox Code Playgroud)
这输出 1,这是在阅读grep
's 手册后预期的(摘录,缩短我的):
退出状态
通常,如果选择了一行,退出状态为 0,如果没有选择任何行,则退出状态为 1,如果发生错误,则退出状态为 2。[...]
在阅读了bash
's manual的相应部分后,我遇到了一个问题(摘录、缩短和强调我的):
退出状态
[...]
如果未找到命令,则为执行它而创建的子进程返回状态 127。如果找到命令但不可执行,则返回状态为 126。
如果命令因扩展或重定向期间的错误而失败,则退出状态大于零。
如果成功,Shell 内置命令将返回状态 0(真),如果在执行时发生错误,则返回非零(假)状态。所有内置函数都返回退出状态 2 以指示不正确的使用、通常无效的选项或缺少参数。
[...]
我的问题是强调语句。
我的脚本通常需要特别处理真正的错误(如权限不足、所需程序不可用、资源耗尽等),但在我上面的例子中,当grep
不选择一行时,它不是上述意义上的错误; 相反,它只是意味着它的输入不包含匹配的字符序列。
但是,如果我从bash
字面上看手册中的部分,则可能是bash
它本身设置了1
. 从该部分,我们知道如果找不到命令(退出状态127
)或不可执行(退出状态126
)会发生什么。
根据我的理解,该部分中的下一条语句意味着所有其他错误都可以[1, 255]
通过 bash映射到包含范围内的任何退出状态。值得注意的是,它可以映射到 exit status 1
。我认为这是一个主要问题,因为我相信除了“找不到命令”或“命令不可执行”之外还有大量错误。例如,内存耗尽、文件句柄耗尽、磁盘读取错误导致的超时等可能会阻止命令执行。
与“grep 找不到匹配的行”错误相反,这些是真正的严重错误,大多数情况下必须将电子邮件发送给管理员以立即采取行动。
但现在似乎我无法区分这两种错误(执行命令设置的非零退出状态与尝试执行命令后 bash 设置的非零退出状态)。
有人能给我指出一个合理的解决方案吗?
类似问题
在我的研究中,我遇到了很多类似的问题。但是,据我所知,没有人遇到 …
我刚刚将两台服务器从Debian 10 (Buster) 升级到Debian 11 (Bullseye)。此后,我再也无法通过网络联系到他们。经过一番排查,发现问题如下:
Both machines have a bridge device configured. Obviously, the algorithm which Debian uses to assign MAC addresses to bridge devices has changed from version 10 to 11. After the upgrade, the bridge device on the first server had the same MAC address as the bridge device on the second server, which for sure has not been the case before.
One of the answers there claims that a bridge is a purely …
我正在努力理解 bash 中的 IO 重定向。我见过很多像下面这样的例子(这实际上取自此处接受的答案):
exec 3<> /tmp/foo #open fd 3.
echo "test" >&3
exec 3>&- #close fd 3.
Run Code Online (Sandbox Code Playgroud)
我不明白第二行。准确地说,我不明白它的行为是如何符合bash手册的。
显然,在第二行中,>&3
应该重定向stdout
(可能stderr
- 我不知道)到文件描述符 3;其他一切都没有任何意义。
但根据当前的 bash 手册(在撰写本文时),第 3.6.4 节(格式化我的):
此结构允许将标准输出(文件描述符 1)和标准错误输出(文件描述符 2)重定向到名称为单词扩展的文件。 重定向标准输出和标准错误有两种格式:
&>word
和>&word
[ 然后它解释了第一种格式和第二种格式之间的细微差别,但让我们暂时把它放在一边,因为它对于这个问题并不重要。]
据我了解,这表示>&3
重定向stderr
和stdout
到一个名为 的文件,这与重定向(可能)到文件描述符3
有很大不同。stdout
stderr
3
有人可以解释一下我缺少什么吗?
每当我升级我的一个 Linux 机器时(即安装我最喜欢的发行版的下一个版本),升级相应的配置文件总是非常耗时,因为在许多情况下,我不只是更改发行版的默认配置文件来反映我的情况,但我非常仔细地制作了自己的配置文件。
到现在为止,在升级时,在这些情况下,我要么完全从头开始阅读相应的手册页并从头开始制作新的配置文件(这很干净,但需要付出很多努力),或者我比较了(想想差异)旧的和新发行版的默认配置文件,当我看到可能很重要的差异时,我已将其“移植”(合并)到我自己的配置文件中(由于多种原因,我对这种方法不满意,其中之一是维护者可以忽略一个新的配置指令,在我的情况下忽略它可能是危险的;但如果我赶时间,它并不总是可以避免的)。
我一直问自己其他人是如何解决这个问题的。一种想法是将旧版本软件的手册页与新版本的手册页进行比较,从而立即看到配置指令或方法的所有差异。
所以问题是:有人知道手册页的特定差异查看器,特别是文本控制台(主要场景是通过 SSH 工作而不使用 X)吗?
请注意,我知道有很多不同的查看器(我已经阅读了数十篇关于此主题的文章和问答)。我的问题特别是关于手册页的差异查看器,它提供了一些安慰(例如,你告诉它旧手册页的基本目录,然后只需要说“show diff sshd_config”等)。
我也知道我最终可以读取相应上游的更改日志,但是我看到许多您不能依赖它的情况(即那里没有提到所有更改),它更不方便,并且一些发行版很严重修补上游,所以我会说这不是一个真正的选择。将旧版本的源代码与新版本的源代码进行比较,只是为了找出新的配置选项似乎太过分了,而且对于 Apache、Sendmail 等来说,这可能是不可能的。相比之下,比较手册页似乎是合理的(如果可能的话)。
有任何想法吗?
请考虑以下命令:
find . -type f -name '*.*' -exec mv '{}' '{}_foo' \;
Run Code Online (Sandbox Code Playgroud)
find
在这种情况下如何防止无限循环?
一方面,我相信要知道,发现并没有像贝壳水珠工作要做,即它不获取所有的列表*.jpg
文件,存储了列表内部,然后处理该列表中的条目。相反,它从底层 O/S 获取文件以“增量”处理,并在知道后立即处理每个文件(让我们忽略可能发生的一定量的缓冲,因为这与问题无关)。毕竟,据我所知,这是在find
包含大量文件的目录中优于 glob的主要优势。
如果这是真的,我想了解 find 如何防止无限循环。在上面的示例中,1.jpg
将重命名为1.jpg_foo
. 从 StackOverflow 和其他地方的讨论中,我知道重命名可能会导致文件(名称)在目录文件列表中占据不同的位置,因此很可能第二次找到该文件,再次将其重命名(为1.jpg_foo_foo
),等等在。
显然,这不会发生。
过去,在开发 Linux 软件时,我有时会注意到man
我的系统上缺少一些处理开发人员文档的页面。
这种情况主要发生在 Debian 系统上。例如,昨天我需要使用该fls()
功能,但man fls
没有通往任何地方,尽管研究和尝试了这个那个,我仍然不知道我可以做什么来安装那些丢失的man
页面。
我认为这个问题与以下事实有关:一些原本可用的功能已经在其他平台上实现了(例如,fls()
似乎来自。但是,这个发现没有帮助; Debian 中BSD
没有专门的POSIX
或开发人员文档(BSD
至少我没找到)。
到目前为止,我已经通过谷歌搜索解决了这个问题,每次都man xxx
有效(即让我找到相应的页面)。man
但这是粗暴且令人不满意的,并使我依赖于在线服务,所以我认为是时候解决这个问题了。
如何在最新的 Debian 版本中安装所有此类文档(特别是不在软件包中的手册页glibc-doc
)?
I am currently trying to understand parameter expansion, especially the different forms which can remove parts of a parameter's value by pattern matching. For the sake of this question, let's focus on the ${parameter#word}
expansion.
The two relevant sections from the manual (man bash
) (emphasis mine):
${parameter#word}
${parameter##word}
Remove matching prefix pattern. The word is expanded to produce a pattern just as in pathname expansion, and matched against the expanded value of parameter using the rules described under …