VirtualBoxΥե륷ƥ10® ~ find ~
⤦äȤȤޤǿƩƤ۴ĶߤʤޤϲȤǤ礦?
μդǤVirtualBox褯ȤƤޤ
ŵŪʻȤȤƤϡ ʲΤ褦ʴǤ
- ۥOSˤϡmac/windowsĤ
- OSˤϡLinuxȤ
- ͭեȤäơۥȤȥȤǥեͭ
Ǥ̣˽פʤΤͭե
ͭեȤϡۥOSΥե륷ƥOSޥȤ뤿ΡVirtualBoxƤȤߤǤ
ȿ̡ե륢٤Ȥ褯ʹޤ
findʤȤgit status٤Ȥ...
ؤкõƤߤȡΤ褦ʪߤĤޤ
vboxsfΤΤؤкϼƤʤ褦Ǥ
ǡvboxsf¾Υե륷ƥȤεưΰ㤤Ĵ١vboxsf®Ƥߤ褦Ȼפޤ
ΤĤҲ𤷤ƤȻפޤ
夲Τϡfind٤ˤĤơ
ڤĶ
ڤĶȤƤϰʲ̤Ǥ
ޤĴоݤˤǥ쥯ȥϡե̤4GBȤʤäƤޤ
Ķ | ġ | version |
---|---|---|
VirualBox | 4.3.28 | |
VMWare Fusion | 7.1.2 | |
ۥOS | OS X Yosemite 10.10.2 | |
OS | Debian 8.1 (Jessie) | |
findutils | GNU findutils 4.4.2 | |
coreutils | GNU coreutils 8.23 | |
glibc | 2.19 | |
linux kernel | 3.16.0-4-amd64 | |
VBoxGuestAdditions | 4.3.18 | |
VMwareTools | 9.9.3 |
ݤǧ
ޤϡfindޥɤ٤Τ¾Υե륷ƥӤƤߤ뤳Ȥˤޤ
оݤˤϡVMWareΥۥ-ȴ֤Υե붦ͭǻȤƤvmhgfsӤޤ
ͳϡvboxsfȻȤߤɤƤ뤳ȤǤ
vboxsfvmhgfs줾ǡfindޥɼ¹ԤȤtime/straceη̤˼ޤ
timeη̤ȡΤvboxsf٤ʤäƤ뤳ȤǧǤޤ
ޤstraceǡ¹ԤƤ륷ƥॳǧƤߤȡvboxsfˤƺǤ֤ΤäƤ륷ƥॳnewfstatat
ǡμ¹Բvmhgfs礭ۤʤ狼ޤ
顢vboxsf/vmhgfsβ餫ΰ㤤ˤäfindޥǼ¹ԤۤʤäƤȤ狼ޤ
parameter | vmhgfs | vboxsf |
---|---|---|
time(real) | 0m7.205s | 0m19.774s |
time(sys) | 0m5.740s | 0m8.088s |
// vboxsf
$ strace -c find .
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
76.59 0.509083 15 34145 newfstatat <-
10.86 0.072196 73 993 openat
10.24 0.068043 68 1005 6 open
2.14 0.014249 0 34145 write
0.14 0.000952 1 998 fstat
0.03 0.000173 0 2013 getdents
(ά)
// vmhgfs
$ strace -c find .
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
94.99 3.207002 1593 2013 getdents
2.36 0.079565 79 1005 6 open
1.96 0.066032 66 993 openat
0.38 0.012751 13 993 newfstatat <-
0.19 0.006551 0 34145 write
0.12 0.004198 2 1993 close
0.00 0.000139 0 998 fstat
(ά)
ɤɤ
Ĥˡʤvboxsf/vmhgfsnewfstatatθƤӽФۤʤΤĴ٤Ƥߤޤ
findΥ
ɤɤ߿ʤƤä̡newfstatat¹Ԥ뤫ݤϡʲǷƤ狼ޤ
// findutils-4.4.2/gnulib/lib/fts.c 1135-1140
bool skip_stat = (ISSET(FTS_PHYSICAL)
&& ISSET(FTS_NOSTAT)
&& DT_IS_KNOWN(dp)
&& ! DT_MUST_BE(dp, DT_DIR));
p->fts_info = FTS_NSOK;
fts_set_stat_required(p, !skip_stat);
dp
glibcδؿreaddirȤäƼdirent ¤ΤǤ
dirent ¤Τϡեѥinodeֹå夷ƤΤǡ˥ѥinodeֹؤѴ˻ȤƤޤ
ȽǤd_type
ǧDT_UNKNOWN
,DT_DIR
Ǥäˡstat¹Ԥ뤳ȤˤʤäƤޤ
ޤgdbvboxsf/vmhgfsǤλͤǧƤߤȡvboxsfǤϾdp->d_type=0 (DT_UNKNOWN)
ǤФơvmhgfsǤdp->d_type=4 (DT_DIR)
dp->d_type=8 (DT_REG)
֤Ƥ狼ޤ
Τ readdirˤʲΤ褦˵Ƥޤ
d_type եɤ Linux ʳǤ BSD ϤΥƥˤ¸ߤ. ΥեɤȤ θưեμ̤ˤޤ lstat(2) ƤӽФȤ뤳ȤǤ. ǽޥ BSDSOURCE 줿 glibc d_type ֤ͤȤưʲΥޥ.
ĤޤꤳϡvboxsfǤd_type
DT_UNKOWN
֤Ƥ뤿ˡstat;פ˼¹Ԥɬפꡢʬvmhgfs٤ʤäƤǤȤޤ
glibc / linux kernelΥ
³ơʤvboxsfd_type
DT_UNKOWN
֤ƤΤĴ٤Ƥߤޤ
Τˡreaddir
ɤΤ褦˥ե륷ƥफƤΤɤɬפޤ
readdirϡglibcƤꡢʲΤ褦syscall getdents
ƤǤ뤳Ȥ狼ޤ
# glibc-2.19/sysdeps/posix/readdir.c
bytes = __GETDENTS (dirp->fd, dirp->data, maxread);
ޤgetdents
ϡlinux kernelƤꡢ椫file->f_op->iterate
ƤӽФƤޤ
// linux/fs/readdir.c
if (!IS_DEADDIR(inode)) {
ctx->pos = file->f_pos;
res = file->f_op->iterate(file, ctx);
file->f_pos = ctx->pos;
fsnotify_access(file);
file_accessed(file);
}
file->f_op
ϥեԤåɷǡե륷ƥऴȤƤޤ
vboxsfΥ
file->f_op
ϥե륷ƥƤΤǡvboxsfμߤƤޤ
vboxsfˤơfile->f_op->iterate
ϰʲΤ褦Ƥޤ
¾Υե륷ƥǤ⡢Ŭgrepдñ˸ĤǤ礦
// VirtualBox-4.3.28/src/VBox/Additions/linux/sharedfolders/dirops.c
struct file_operations sf_dir_fops =
{
.open = sf_dir_open,
.iterate = sf_dir_iterate,
.release = sf_dir_release,
.read = generic_read_dir,
.llseek = generic_file_llseek
};
ơvboxsfsf_dir_iterateɤäƤȡʲεҤĤޤ
// VirtualBox-4.3.28/src/VBox/Additions/linux/sharedfolders/dirops.c
if (!dir_emit(ctx, d_name, strlen(d_name), fake_ino, DT_UNKNOWN))
{
LogFunc(("dir_emit failed\n"));
return 0;
}
dir_emit
ϡե̾inodeֹǥ쥯ȥꥨȥȤơϿ뤿δؿǤ
Τ褦vboxsfǤϡgetdents
¹Ԥ̤Ȥơinodeֹȥե֤̾Ƥꡢd_type
ˤDT_UNKNOWN
֤Ƥ뤳Ȥ狼ޤ
Τᡢvboxsfǥۥ¦dentryμd_type
Ȥ֤ȤǤСvboxsfǤfind®뤳ȤǤȹͤޤ
vboxsf
d_type
Ͽ뤿ˤϡۥ¦d_type
ʤФʤޤ
dentryǧȡ¦ưƤvboxsf顢ۥ¦ưƤ륵ӥ˷̤䤤碌Ƥ뤳Ȥ狼ޤ
dentryƤۥ¦ǤΥɤmac/windows줾ʲΤ褦ˤʤäƤޤ
// VirtualBox-4.3.28/src/VBox/Runtime/r3/posix/dir-posix.cpp
RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry)
...
pDirEntry->INodeId = pDir->Data.d_ino; /* may need #ifdefing later */
pDirEntry->enmType = rtDirType(pDir->Data.d_type);
pDirEntry->cbName = (uint16_t)cchName;
// VirtualBox-4.3.28/src/VBox/Runtime/r3/win/direnum-win.cpp
RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry)
...
pDir->fDataUnread = false;
pDirEntry->INodeId = 0; /** @todo we can use the fileid here if we must (see GetFileInformationByHandle). */
pDirEntry->enmType = pDir->Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
? RTDIRENTRYTYPE_DIRECTORY : RTDIRENTRYTYPE_FILE;
pDirEntry->cbName = (uint16_t)cchName;
ȡdentryξݡd_type
(pDirEntry->enmType)˼Ƥ뤳Ȥ狼ޤ
ϡ¦ޤ֤ͤƤ뤱ɤꤷƤʤǤ褦Ǥ
vboxsfǡʴǥۥ¦d_type
֤褦˽Ԥޤ
νԤäǡۤɤƱͤfindޥɤ¹ԤȤtime/straceη̤ʲ˼ޤ
ʲΤ褦ˡnewfstatat
θƤӽФäƤ뤳Ȥ狼ޤ
ޤʬ¹Ի֤ûʤäƤꡢvmhgfsƱ٤®٤ˤʤޤ
parameter | vmhgfs | vboxsf (before) | vboxsf (after) |
---|---|---|---|
time(real) | 0m7.205s | 0m19.774s | 0m3.385s |
time(sys) | 0m5.740s | 0m8.088s | 0m0.860s |
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
55.75 0.090346 90 1005 6 open
37.71 0.061110 62 993 openat
4.58 0.007425 0 34145 write
0.97 0.001571 2 993 newfstatat <-
0.66 0.001071 1 998 fstat
0.20 0.000326 0 1989 fchdir
0.12 0.000194 0 2013 getdents
0.00 0.000000 0 4 read
(ά)
ޤȤ
vboxsfd_type
֤Ƥ뤳ȤǡfindΤ褦d_type
Ȥäƽ︺Ƥ륳ޥɤ®뤳ȤǤޤ
ޤνϡVirtualBox 5.0.2ν˼ޤޤ