我试过
xtricman?ArchVirtual??~ls /proc/self/fd/ -l
Total 0
lrwx------ 1 xtricman users 64 1? 16 16:34 0 -> /dev/pts/0
lrwx------ 1 xtricman users 64 1? 16 16:34 1 -> /dev/pts/0
lrwx------ 1 xtricman users 64 1? 16 16:34 2 -> /dev/pts/0
lrwx------ 1 xtricman users 64 1? 16 16:34 3 -> '/home/xtricman/a (deleted)'
lr-x------ 1 xtricman users 64 1? 16 16:34 4 -> /proc/1273/fd
xtricman?ArchVirtual??~ln /proc/self/fd/3 b
ln: failed to create hard link 'b' => '/proc/self/fd/3': Invalid cross-device link
Run Code Online (Sandbox Code Playgroud)
由于 inode 仍在磁盘上,如何为其重新创建名称?如果没有指向该 inode 的打开文件描述但该 inode 是 mmaped 怎么办?在这种情况下我该如何恢复它?
你不应该能够做到这一点(但请阅读下面的一个有趣的例外)。
如果内核让它发生,那么调用如下:
fd = open(filename, O_CREAT|O_RDWR, 0666);
unlink(filename);
linkat(fd, "", 0, "/new/path", AT_EMPTY_PATH);
Run Code Online (Sandbox Code Playgroud)
即使被引用的 inodefd
的链接计数为 0,当由具有CAP_DAC_READ_SEARCH
大写的进程完成时也会成功。
但是内核会主动阻止它发生,而不考虑执行它的进程的能力或特权。
int vfs_link(struct dentry *old_dentry, ...
{
...
/* Make sure we don't allow creating hardlink to an unlinked file */
if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE))
error = -ENOENT;
Run Code Online (Sandbox Code Playgroud)
这也记录在联机帮助页中:
AT_EMPTY_PATH
(从 Linux 2.6.39 开始)如果
oldpath
是空字符串,则创建一个指向由olddirfd
(可能已使用open(2)
O_PATH
标志获得)引用的文件的链接 。在这种情况下,olddirfd
可以引用除目录之外的任何类型的文件。 如果文件的链接计数为零(使用O_TMPFILE
和不使用创建的文件O_EXCL
除外),这通常不起作用 。调用者必须具有CAP_DAC_READ_SEARCH
使用此标志的能力。这个标志是 Linux 特有的;定义_GNU_SOURCE
以获取其定义。
基于内核源码,除了O_TMPFILE
. O_TMPFILE
记录在open(2)
联机帮助页中;下面是一个基于此的小例子:
#define _GNU_SOURCE 1
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <err.h>
int main(int ac, char **av){
char path[64]; int fd;
if(ac < 3) errx(1, "usage: %s dir newpath", av[0]);
if((fd = open(av[1], O_TMPFILE|O_RDWR, 0666)) == -1) err(1, "open");
/*
* ...
* write stuff to fd and only "realize" the file at the end if
* everything has succeeded
*/
/* the following line only works with CAP_DAC_READ_SEARCH */
/* if(linkat(fd, "", 0, av[2], AT_EMPTY_PATH)) err(1, "linkat"); */
snprintf(path, sizeof path, "/proc/self/fd/%d", fd);
if(linkat(AT_FDCWD, path, AT_FDCWD, av[2], AT_SYMLINK_FOLLOW))
err(1, "linkat");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
394 次 |
最近记录: |