有什么快速的方法可以检查 ext2/3/4 个空闲 inode(在未安装的磁盘上)? and/or 为什么他们不都具有相同的 "bad type" 状态
Is there any fast way to examine ext2/3/4 free inodes (on an unmounted disk) ? and/or why do they not all have the same "bad type" status
使用 debugfs 检查空闲 inode(列表来自 dumpe2fs),我观察到它们中的大多数具有 bad type
状态,除了少数 regular
。我想检查所有这些,看看有多少以及哪些状态不同。
因此我制作了一个 python/pexpect 小程序,它启动 debugfs 并交互发送 stat <inode>
请求所有这些空闲 inode 以查找哪些或它们具有其他 bad type
状态。
但是,我的程序似乎需要大约 2 年的时间才能获得所有请求的信息。我可以使用什么更快的方法来获取这些 inode 内容?
或者,我很乐意了解为什么免费 inode 可以具有 regular
状态
由于我没有得到任何简单的解决方案,我最终通过在 debugfs/debugfs.c
中的 do_stat
的基础上添加一个新函数 do_rstat
来修补 debugfs。有点像这样:
void do_rstat(int argc, char *argv[])
{
ext3_ino_t ifrom, ito, inode;
struct ext3_inode * inode_buf;
errcode_t r;
if (argc<4) {
fprintf(stderr, "do_rstat: needs an inodes range (3 arguments).\n");
return;
}
if (check_fs_open(argv[1]))
return;
if (string_to_inode_range(argv[2], argv[2], &ifrom, &ito) & 0x2) {
fprintf(stderr, "do_rstat: invalid inodes range.\n");
return;
}
inode_buf = (struct ext3_inode *)
malloc(EXT3_INODE_SIZE(current_fs->super));
if (!inode_buf) {
fprintf(stderr, "do_rstat: can't allocate buffer\n");
return;
}
for (inode = ifrom; inode<ito; inode++) {
r = debugfs_read_inode_full(inode, inode_buf, argv[1],
EXT3_INODE_SIZE(current_fs->super));
if (r) {
FILE *out;
out = open_pager();
fprintf(out, "%13ud ERROR %ld\n\n", inode, r);
close_pager(out);
} else
dump_inode(inode, inode_buf);
}
free(inode_buf);
return;
}
(但是,我不会在这里详细说明,因为它非常符合我的需要,但我还替换了 dump_inode(inode, inode_buf);
调用以在一行中使用固定宽度字段获取输出,以便删除需要在调用程序中进行模式匹配)。为了做到这一点,我从 dump_inode
和 dump_inode_internal
函数中获得灵感。
而且我还需要在 debugfs/util.c
中添加两个函数
/*
* This routine is used whenever a command needs to turn an <ino> string
* into an inode.
*/
ext2_ino_t string_to_inode_number(char *str)
{
ext2_ino_t ino;
int len = strlen(str);
char *end;
if ((len<2) || (str[0] != '<') || (str[len-1] != '>')) return 0;
ino=strtoul(str+1, &end, 0);
if (*end!='>') return -1;
return ino;
}
/*
* This routine is used whenever a command needs to turn 2 <ino> strings
* into an inodes range ( [ino1, ino2[ ).
*/
int string_to_inode_range(char *str1, char *str2, ext2_ino_t *ino1, ext2_ino_t *ino2)
{
int invalid = 0;
ext2_ino_t inox;
*ino1 = string_to_inode_number(str1);
*ino2 = string_to_inode_number(str2);
if (*ino2 == -1) {
*ino2 = current_fs->super->s_inodes_count+1;
invalid |= 0x1;
}
if (*ino1 >= *ino2) {
inox = *ino1;
*ino1 = *ino2;
*ino2 = inox;
invalid |= 0x2;
}
if (*ino1 <= 0) {
*ino1 = 1;
invalid |= 0x4;
}
if (*ino2 > current_fs->super->s_inodes_count+1) {
*ino2 = current_fs->super->s_inodes_count+1;
invalid |= 0x8;
}
return invalid;
}
我需要在 debugfs/debugfs.h
中添加他们的原型
extern ext2_ino_t string_to_inode_number(char *str);
extern int string_to_inode_range(char *str1, char *str2, ext2_ino_t *ino1, ext2_ino_t *ino2);
我还在 debug_commands.ct
中为新命令添加了一个条目:
request do_rstat, "Show inodes information ",
show_inodes_info, rstat;
当我调用它时,我需要确保输出是通过管道传输的(就像在 | cat
中一样),以便停用烦人的寻呼机。
例如:
> debugfs -cD -R 'rstat <100> <200>' /dev/sdXXX | cat
(别忘了/dev/sdXXX一定不要挂载)
使用 debugfs 检查空闲 inode(列表来自 dumpe2fs),我观察到它们中的大多数具有 bad type
状态,除了少数 regular
。我想检查所有这些,看看有多少以及哪些状态不同。
因此我制作了一个 python/pexpect 小程序,它启动 debugfs 并交互发送 stat <inode>
请求所有这些空闲 inode 以查找哪些或它们具有其他 bad type
状态。
但是,我的程序似乎需要大约 2 年的时间才能获得所有请求的信息。我可以使用什么更快的方法来获取这些 inode 内容?
或者,我很乐意了解为什么免费 inode 可以具有 regular
状态
由于我没有得到任何简单的解决方案,我最终通过在 debugfs/debugfs.c
中的 do_stat
的基础上添加一个新函数 do_rstat
来修补 debugfs。有点像这样:
void do_rstat(int argc, char *argv[])
{
ext3_ino_t ifrom, ito, inode;
struct ext3_inode * inode_buf;
errcode_t r;
if (argc<4) {
fprintf(stderr, "do_rstat: needs an inodes range (3 arguments).\n");
return;
}
if (check_fs_open(argv[1]))
return;
if (string_to_inode_range(argv[2], argv[2], &ifrom, &ito) & 0x2) {
fprintf(stderr, "do_rstat: invalid inodes range.\n");
return;
}
inode_buf = (struct ext3_inode *)
malloc(EXT3_INODE_SIZE(current_fs->super));
if (!inode_buf) {
fprintf(stderr, "do_rstat: can't allocate buffer\n");
return;
}
for (inode = ifrom; inode<ito; inode++) {
r = debugfs_read_inode_full(inode, inode_buf, argv[1],
EXT3_INODE_SIZE(current_fs->super));
if (r) {
FILE *out;
out = open_pager();
fprintf(out, "%13ud ERROR %ld\n\n", inode, r);
close_pager(out);
} else
dump_inode(inode, inode_buf);
}
free(inode_buf);
return;
}
(但是,我不会在这里详细说明,因为它非常符合我的需要,但我还替换了 dump_inode(inode, inode_buf);
调用以在一行中使用固定宽度字段获取输出,以便删除需要在调用程序中进行模式匹配)。为了做到这一点,我从 dump_inode
和 dump_inode_internal
函数中获得灵感。
而且我还需要在 debugfs/util.c
/*
* This routine is used whenever a command needs to turn an <ino> string
* into an inode.
*/
ext2_ino_t string_to_inode_number(char *str)
{
ext2_ino_t ino;
int len = strlen(str);
char *end;
if ((len<2) || (str[0] != '<') || (str[len-1] != '>')) return 0;
ino=strtoul(str+1, &end, 0);
if (*end!='>') return -1;
return ino;
}
/*
* This routine is used whenever a command needs to turn 2 <ino> strings
* into an inodes range ( [ino1, ino2[ ).
*/
int string_to_inode_range(char *str1, char *str2, ext2_ino_t *ino1, ext2_ino_t *ino2)
{
int invalid = 0;
ext2_ino_t inox;
*ino1 = string_to_inode_number(str1);
*ino2 = string_to_inode_number(str2);
if (*ino2 == -1) {
*ino2 = current_fs->super->s_inodes_count+1;
invalid |= 0x1;
}
if (*ino1 >= *ino2) {
inox = *ino1;
*ino1 = *ino2;
*ino2 = inox;
invalid |= 0x2;
}
if (*ino1 <= 0) {
*ino1 = 1;
invalid |= 0x4;
}
if (*ino2 > current_fs->super->s_inodes_count+1) {
*ino2 = current_fs->super->s_inodes_count+1;
invalid |= 0x8;
}
return invalid;
}
我需要在 debugfs/debugfs.h
extern ext2_ino_t string_to_inode_number(char *str);
extern int string_to_inode_range(char *str1, char *str2, ext2_ino_t *ino1, ext2_ino_t *ino2);
我还在 debug_commands.ct
中为新命令添加了一个条目:
request do_rstat, "Show inodes information ",
show_inodes_info, rstat;
当我调用它时,我需要确保输出是通过管道传输的(就像在 | cat
中一样),以便停用烦人的寻呼机。
例如:
> debugfs -cD -R 'rstat <100> <200>' /dev/sdXXX | cat
(别忘了/dev/sdXXX一定不要挂载)