#
我开始研究旧的 C 代码(Unix v6),我想知道文件开头的单个的目的是什么.c
。例如来自https://github.com/lsahn-gh/unix-v6/blob/master/sys%2Fken%2Falloc.c
#
/*
*/
#include "../param.h"
#include "../systm.h"
#include "../filsys.h"
...
#
我开始研究旧的 C 代码(Unix v6),我想知道文件开头的单个的目的是什么.c
。例如来自https://github.com/lsahn-gh/unix-v6/blob/master/sys%2Fken%2Falloc.c
#
/*
*/
#include "../param.h"
#include "../systm.h"
#include "../filsys.h"
...
简而言之,我在内核中有一个物理地址0x250000000
(9,932,111,872 或),它显然与 4kB(页面大小)对齐。当我使用内核__va()
函数获取内核虚拟地址时,我得到了类似的内容0xf570660f
(每次启动时都不同),它没有与 4kB 对齐。
我使用的是 64 位系统,因此没有 HIGHMEM,并且我认为由于线性内存模型,4kB 对齐的物理地址的虚拟地址也应该是 4kB 对齐的。我错过了什么?虚拟地址不应该是吗phys_addr + PAGE_OFFSET
?或者是sparsemem的影响?但也许它也应该是 4kB 对齐的?
以下是更多详细信息:
我的工作环境是在 x86 64 位 QEMU VM 上。我正在尝试在模式下使用 PMEMDEV-DAX
作为普通内存。我可以得到它的物理起始地址(0x250000000
),已经确认是正确的。然后我需要将它转移到内核空间中的虚拟地址,以便我可以根据需要使用它。这是一些代码:
static long nvpc_map_whole_dev(struct dax_device *dax_dev, void **kaddr, pfn_t *pfn)
{
// get the device
struct dev_dax_nvpc *dax_nvpc = (struct dev_dax_nvpc *)dax_get_private(dax_dev);
// get the virtual address and the pfn_t
*kaddr = __va(dax_nvpc->phys_start);
*pfn = phys_to_pfn_t(dax_nvpc->phys_start, PFN_MAP);
pr_info("[NVPC DEBUG]: paddr %#llx kaddr %p pfn %lu\n", dax_nvpc->phys_start, *kaddr, pfn_t_to_pfn(*pfn));
pr_info("[NVPC DEBUG]: kaddr-paddr %#llx\n", __pa(*kaddr));
return PHYS_PFN(dax_nvpc->size);
}
这是我得到的结果:
如图所示, 、paddr
dax_nvpc->phys_start
、 、pfn
都是正确的。但kaddr
(虚拟地址)让我感到困惑。然后,当我将其传输kaddr
回物理地址(下一个输出行)时,结果是正确的。
更重要的是,我可以对内存从kaddr
到进行任何操作kaddr + dax_nvpc->size
,没有页面错误。
谁能告诉我为什么虚拟地址不是 4kB 对齐的?我在某个地方是不是傻瓜?此外,我可以做些什么来确保虚拟地址也与页面对齐吗?
我跑了这个:
cat /usr/bin/* |
perl -ne 'map {$a{$_}++} split//; END{print map { "$a{$_}\t$_\n" } keys %a}' |
grep --text . | sort -n | plotpipe --log y {1}
并得到这个:
(即使使用对数 y 轴,它看起来仍然是指数的!顶部和底部之间的距离超过 100 倍)
看一下数字:
:
31919597 ^H
32983719 ^B
33943030 ^O
39130281 \213
39893389 $
52237360 \211
53229196 ^A
76884442 \377
100776756 H
746405320 ^@
^@ (NUL) 是可执行文件中最常见的字节,这并不奇怪。\377 (255) 和 ^A (1) 对我来说也具有直观意义。
但是,是什么导致“H”(72)成为可执行文件中第二常见的字节——比 255 和 1 更常见呢?
在Linux中,文件系统时间似乎总是落后系统时间几毫秒,如果您想检查文件是否在给定时间之前或之后在非常窄的时间范围(毫秒)内被修改,则会导致不一致。
在任何具有支持纳秒分辨率的文件系统的 Linux 系统中(我尝试使用具有 256 字节 inode 和 ZFS 的 ext4),如果您尝试执行以下操作:
date +%H:%M:%S.%N; echo "hello" > test1; stat -c %y test1 | cut -d" " -f 2
第二个输出值(文件修改时间)始终比第一个输出值(系统时间)晚几毫秒,例如:
17:26:42.400823099
17:26:42.395348462
而它应该是相反的,因为文件在调用命令后被test1
修改。date
你可以在 python 中得到相同的结果:
import os, time
def test():
print(time.time())
with open("test1", "w") as f:
f.write("hello")
print(os.stat("test1").st_mtime)
test()
1698255477.3125281
1698255477.3070245
为什么会这样呢?有没有办法避免它,使系统时间与文件系统时间一致?到目前为止,我发现的唯一解决方法是通过创建一个虚拟临时文件并获取其修改时间来获取文件系统“时间”(无论这在实践中意味着什么),如下所示:
def get_filesystem_time():
"""
get the current filesystem time by creating a temporary file and getting
its modification time.
"""
with tempfile.NamedTemporaryFile() as f:
return os.stat(f.name).st_mtime
但我想知道是否有更清洁的解决方案。
内核中有很多常量以HORKAGE
,
ATA_HORKAGE_ZERO_AFTER_TRIM
ATA_HORKAGE_NODMA
ATA_HORKAGE_ATAPI_MOD16_DMA
ATA_HORKAGE_NO_DMA_LOG
ATA_HORKAGE_NO_ID_DEV_LO
ATA_HORKAGE_NO_LOG_DIR
ATA_HORKAGE_WD_BROKEN_LPM
然而,这些并没有真正记录在案
根据 libata.force 强制 horkage 并抱怨它。为了与链路选择保持一致,15 号设备选择连接到主机链路的第一个设备。
"horkage" 是什么意思?
“是的,而且……”是即兴喜剧中的一个很棒的经验法则。在 UNIX 世界中则不然。
当我运行这个公认的愚蠢yes&
命令时,我无法中断它。终端崩溃或陷入循环。
我希望该yes
进程立即暂停,因为如果尝试写入标准输出,后台的任何进程都应该暂停,但情况似乎并非如此,我想知道为什么。
我的雇主位于欧洲 (CET),因此我们使用夏令时,这需要每年两次前后移动一个小时。我们的服务器在不同位置的云中运行。设置所有基础设施的员工不在了。他决定在所有服务器(目前是 Ubuntu 18.04、20.04 和 22.04)上使用 UTC 作为系统时区。
这并不理想,因为您必须在日志文件中看到的每个日期都在心理上增加 1/2 小时,具体取决于一年中的时间(夏季 +2 小时,冬季 +1 小时)。一些 cronjobs 的时间也需要每年调整两次,因为任务应该在 CET 中午运行。
是否有充分的理由(仍然)使用 UTC 作为系统的时区?或者我应该改用 CET,以便我的 cronjobs 和日志文件更好地与挂钟保持一致?
是的,我知道你在想什么:“到底是谁命名他们的文件`a`b
?”
但是让我们假设您确实有一个名为`a`b
(可能是由疯狂的 Mac 用户制作的 - 显然不是您制作的)的文件,并且您想要rsync
那个。显而易见的解决方案:
rsync server:'./`a`b' ./.;
rsync 'server:./`a`b' ./.;
给出:
bash: line 1: a: command not found
rsync: [sender] link_stat "/home/tange/b" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1865) [Receiver=3.2.7]
rsync: [Receiver] write error: Broken pipe (32)
甚至:
$ rsync 'server:./\`a\`b' ./.;
bash: line 3: a\: command not found
rsync: [sender] link_stat "/home/tange/\b" failed: No such file or directory (2)
:
rsync
我应该运行的命令是什么?
$ rsync --version
rsync version 3.2.7 protocol version 31
当 Linux 系统休眠并从休眠中恢复时,我认为内核需要知道它正在恢复,而不是引导。否则,内核将启动通常的引导过程,并且不会加载交换的数据。内核如何知道它正在恢复?
起初,我以为GRUB(或其他引导加载程序)通过内核参数告诉内核。但是只要我查看/proc/cmdline,内核参数就和平时一样了。内核是否有任何机制知道它正在恢复?
July 2022 mac os Monterey V12.1
awk --version 20200816
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)
为什么awk -F
对大多数字母有效,但对字母无效t
?我有解决方案,但我想了解为什么 awk 对 letter 失败t
。
# Count 'e's
% echo "tweeter" | awk -F "e" '{print NF-1}'
3
# Count 'r's
% echo "tweeter" | awk -F "r" '{print NF-1}'
1
# (Attempt to) count 't's
% echo "tweeter" | awk -F "t" '{print NF-1}'
0 <=== ????
# Use gsub()
% echo "tweeter" | awk '{print gsub(/t/, "")}'
2
我正在寻找一种方法来消除某些附加代码以.bashrc
自动强制加载其环境的安装程序的不良行为。这个问题出现了几次,主要是在 Conda 上,在某些情况下,用户最终会使用一个损坏的帐户阻止他们再登录。
我试图在 .bashrc 的末尾添加一个未关闭的 here-document,如下所示:
# .bashrc
#...
: <<'__END__'
哪个有效,但会产生解析错误烦人的警告。
什么是一种干净的方法(不使 .bashrc 只读)?
假设我有 50 个 USB 闪存驱动器。
我想他们会/dev/sda
去/dev/sdz
。之后是什么/dev/sdz
?
我可以 ping google.com几秒钟,当我按Ctrl+C时,底部会显示一个简短的摘要:
$ ping google.com
PING google.com (74.125.131.113) 56(84) bytes of data.
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=2 ttl=56 time=46.7 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=3 ttl=56 time=45.0 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=4 ttl=56 time=54.5 ms
^C
--- google.com ping statistics ---
4 packets transmitted, 3 received, 25% packet loss, time 3009ms
rtt min/avg/max/mdev = 44.965/48.719/54.524/4.163 ms
但是,当我使用 将相同的重定向输出重定向到日志文件时tee
,不会显示摘要:
$ ping google.com | tee log
PING google.com (74.125.131.113) 56(84) bytes of data.
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=1 ttl=56 time=34.1 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=2 ttl=56 time=57.0 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=3 ttl=57 time=50.9 ms
^C
使用 重定向输出时,我也可以获得摘要tee
吗?
我收到以下错误sudo
:
$ sudo ls
sudo: /etc/sudoers is owned by uid 1000, should be 0
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin
当然chown
,root
如果不使用sudo
. root
我们的帐户也没有密码。
老实说,我不知道系统是如何陷入这种混乱的,但现在由我来解决它。
通常我会启动到恢复模式,但系统是远程的,只能在正常启动时通过 VPN 访问。出于同样的原因,从 Live CD 或 USB 记忆棒引导也是不切实际的。
系统是Ubuntu 16.04(EOL以后,别问了),不过问答可能比较笼统。
也许我今天还没有喝足够的咖啡,但我不记得或想不出为什么/proc/PID/cmdline
应该是世界可读的——毕竟,/proc/PID/environ
不是。
使其只能由用户(当然也可能是组和 root)可读,可以防止作为命令行参数输入的密码被随意暴露。
当然,它会影响其他用户的运行ps
等等htop
——但这是一件好事,对吧?那将是不使其具有世界可读性的关键。
我看到这有以下行为:
[root@divinity test]# echo 0 > file.txt
[root@divinity test]# cat file.txt
0
[root@divinity test]# echo 0> file.txt
[root@divinity test]# cat file.txt
我还注意到,如果我包含""
then 它会按预期工作:
[root@divinity test]# echo 0""> file.txt
[root@divinity test]# cat file.txt
0
我想这只是 IO 重定向的一部分,但我不太明白echo 0>
在做什么。