Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Levin Zimmermann
go-fuse
Commits
6f5fc437
Commit
6f5fc437
authored
Mar 22, 2011
by
Han-Wen Nienhuys
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add more timing hooks to TimingPathFilesystem.
parent
b1becd41
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
86 additions
and
38 deletions
+86
-38
example/loopback.go
example/loopback.go
+28
-16
fuse/timingfs.go
fuse/timingfs.go
+58
-22
No files found.
example/loopback.go
View file @
6f5fc437
...
@@ -10,8 +10,12 @@ import (
...
@@ -10,8 +10,12 @@ import (
"flag"
"flag"
"runtime"
"runtime"
"sort"
"sort"
"log"
)
)
var
_
=
runtime
.
GOMAXPROCS
var
_
=
log
.
Print
func
PrintMap
(
m
map
[
string
]
float64
)
{
func
PrintMap
(
m
map
[
string
]
float64
)
{
keys
:=
make
([]
string
,
len
(
m
))
keys
:=
make
([]
string
,
len
(
m
))
for
k
,
_
:=
range
m
{
for
k
,
_
:=
range
m
{
...
@@ -43,15 +47,16 @@ func main() {
...
@@ -43,15 +47,16 @@ func main() {
var
opts
fuse
.
PathFileSystemConnectorOptions
var
opts
fuse
.
PathFileSystemConnectorOptions
opts
.
AttrTimeout
=
1
.0
opts
.
AttrTimeout
=
0
.0
opts
.
EntryTimeout
=
1
.0
opts
.
EntryTimeout
=
0
.0
opts
.
NegativeTimeout
=
1
.0
opts
.
NegativeTimeout
=
0
.0
fs
.
Set
Options
(
&
opts
)
fs
.
Fill
Options
(
&
opts
)
conn
:=
fuse
.
NewPathFileSystemConnector
(
timing
)
conn
:=
fuse
.
NewPathFileSystemConnector
(
timing
)
rawTiming
:=
fuse
.
NewTimingRawFilesystem
(
conn
)
rawTiming
:=
fuse
.
NewTimingRawFilesystem
(
conn
)
conn
.
SetOptions
(
opts
)
state
:=
fuse
.
NewMountState
(
rawTiming
)
state
:=
fuse
.
NewMountState
(
rawTiming
)
state
.
Debug
=
*
debug
state
.
Debug
=
*
debug
...
@@ -61,27 +66,34 @@ func main() {
...
@@ -61,27 +66,34 @@ func main() {
fmt
.
Printf
(
"MountFuse fail: %v
\n
"
,
err
)
fmt
.
Printf
(
"MountFuse fail: %v
\n
"
,
err
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
// TODO - figure out what a good value is.
cpus
:=
1
// cpus := fuse.CountCpus()
if
cpus
>
1
{
runtime
.
GOMAXPROCS
(
cpus
)
}
fmt
.
Printf
(
"Mounted %s on %s (threaded=%v, debug=%v
, cpus=%v)
\n
"
,
orig
,
mountPoint
,
*
threaded
,
*
debug
,
cpus
)
fmt
.
Printf
(
"Mounted %s on %s (threaded=%v, debug=%v
)
\n
"
,
orig
,
mountPoint
,
*
threaded
,
*
debug
)
state
.
Loop
(
*
threaded
)
state
.
Loop
(
*
threaded
)
fmt
.
Println
(
"Finished"
,
state
.
Stats
())
fmt
.
Println
(
"Finished"
,
state
.
Stats
())
fmt
.
Println
(
"
\n\n
MountState statistics
\n
"
)
counts
:=
state
.
OperationCounts
()
counts
:=
state
.
OperationCounts
()
fmt
.
Println
(
"Counts: "
,
counts
)
fmt
.
Println
(
"Counts: "
,
counts
)
latency
:=
state
.
Latencies
()
latency
:=
state
.
Latencies
()
fmt
.
Println
(
"
MountState
latency (ms):"
)
fmt
.
Println
(
"
Operation
latency (ms):"
)
PrintMap
(
latency
)
PrintMap
(
latency
)
latency
=
rawTiming
.
Latencies
()
fmt
.
Println
(
"
\n\n
Raw FS (ms):"
,
latency
)
fmt
.
Println
(
"
\n\n
Loopback FS statistics
\n
"
)
latency
=
timing
.
Latencies
()
latency
=
timing
.
Latencies
()
fmt
.
Println
(
"
Path ops
(ms):"
,
latency
)
fmt
.
Println
(
"
Latency
(ms):"
,
latency
)
latency
=
rawTiming
.
Latencies
()
fmt
.
Println
(
"Operation counts:"
,
timing
.
OperationCounts
())
fmt
.
Println
(
"Raw FS (ms):"
,
latency
)
hot
,
unique
:=
timing
.
HotPaths
(
"GetAttr"
)
top
:=
200
start
:=
len
(
hot
)
-
top
if
start
<
0
{
start
=
0
}
fmt
.
Printf
(
"Unique GetAttr paths: %d
\n
"
,
unique
)
fmt
.
Printf
(
"Top %d GetAttr paths: %v"
,
top
,
hot
[
start
:
])
}
}
fuse/timingfs.go
View file @
6f5fc437
...
@@ -4,9 +4,12 @@ import (
...
@@ -4,9 +4,12 @@ import (
"sync"
"sync"
"time"
"time"
"log"
"log"
"fmt"
"sort"
)
)
var
_
=
log
.
Print
var
_
=
log
.
Print
var
_
=
fmt
.
Print
// TimingPathFilesystem is a wrapper to collect timings for a PathFilesystem
// TimingPathFilesystem is a wrapper to collect timings for a PathFilesystem
type
TimingPathFilesystem
struct
{
type
TimingPathFilesystem
struct
{
...
@@ -15,6 +18,7 @@ type TimingPathFilesystem struct {
...
@@ -15,6 +18,7 @@ type TimingPathFilesystem struct {
statisticsLock
sync
.
Mutex
statisticsLock
sync
.
Mutex
latencies
map
[
string
]
int64
latencies
map
[
string
]
int64
counts
map
[
string
]
int64
counts
map
[
string
]
int64
pathCounts
map
[
string
]
map
[
string
]
int64
}
}
func
NewTimingPathFilesystem
(
fs
PathFilesystem
)
*
TimingPathFilesystem
{
func
NewTimingPathFilesystem
(
fs
PathFilesystem
)
*
TimingPathFilesystem
{
...
@@ -22,10 +26,11 @@ func NewTimingPathFilesystem(fs PathFilesystem) *TimingPathFilesystem {
...
@@ -22,10 +26,11 @@ func NewTimingPathFilesystem(fs PathFilesystem) *TimingPathFilesystem {
t
.
original
=
fs
t
.
original
=
fs
t
.
latencies
=
make
(
map
[
string
]
int64
)
t
.
latencies
=
make
(
map
[
string
]
int64
)
t
.
counts
=
make
(
map
[
string
]
int64
)
t
.
counts
=
make
(
map
[
string
]
int64
)
t
.
pathCounts
=
make
(
map
[
string
]
map
[
string
]
int64
)
return
t
return
t
}
}
func
(
me
*
TimingPathFilesystem
)
startTimer
(
name
string
)
(
closure
func
())
{
func
(
me
*
TimingPathFilesystem
)
startTimer
(
name
string
,
arg
string
)
(
closure
func
())
{
start
:=
time
.
Nanoseconds
()
start
:=
time
.
Nanoseconds
()
return
func
()
{
return
func
()
{
...
@@ -35,9 +40,27 @@ func (me *TimingPathFilesystem) startTimer(name string) (closure func()) {
...
@@ -35,9 +40,27 @@ func (me *TimingPathFilesystem) startTimer(name string) (closure func()) {
me
.
counts
[
name
]
+=
1
me
.
counts
[
name
]
+=
1
me
.
latencies
[
name
]
+=
dt
me
.
latencies
[
name
]
+=
dt
m
,
ok
:=
me
.
pathCounts
[
name
]
if
!
ok
{
m
=
make
(
map
[
string
]
int64
)
me
.
pathCounts
[
name
]
=
m
}
m
[
arg
]
+=
1
}
}
}
}
func
(
me
*
TimingPathFilesystem
)
OperationCounts
()
map
[
string
]
int64
{
me
.
statisticsLock
.
Lock
()
defer
me
.
statisticsLock
.
Unlock
()
r
:=
make
(
map
[
string
]
int64
)
for
k
,
v
:=
range
me
.
counts
{
r
[
k
]
=
v
}
return
r
}
func
(
me
*
TimingPathFilesystem
)
Latencies
()
map
[
string
]
float64
{
func
(
me
*
TimingPathFilesystem
)
Latencies
()
map
[
string
]
float64
{
me
.
statisticsLock
.
Lock
()
me
.
statisticsLock
.
Lock
()
defer
me
.
statisticsLock
.
Unlock
()
defer
me
.
statisticsLock
.
Unlock
()
...
@@ -49,103 +72,116 @@ func (me *TimingPathFilesystem) Latencies() map[string]float64 {
...
@@ -49,103 +72,116 @@ func (me *TimingPathFilesystem) Latencies() map[string]float64 {
return
r
return
r
}
}
func
(
me
*
TimingPathFilesystem
)
HotPaths
(
operation
string
)
(
paths
[]
string
,
uniquePaths
int
)
{
me
.
statisticsLock
.
Lock
()
defer
me
.
statisticsLock
.
Unlock
()
counts
:=
me
.
pathCounts
[
operation
]
results
:=
make
([]
string
,
0
,
len
(
counts
))
for
k
,
v
:=
range
counts
{
results
=
append
(
results
,
fmt
.
Sprintf
(
"% 9d %s"
,
v
,
k
))
}
sort
.
SortStrings
(
results
)
return
results
,
len
(
counts
)
}
func
(
me
*
TimingPathFilesystem
)
GetAttr
(
name
string
)
(
*
Attr
,
Status
)
{
func
(
me
*
TimingPathFilesystem
)
GetAttr
(
name
string
)
(
*
Attr
,
Status
)
{
defer
me
.
startTimer
(
"GetAttr"
)()
defer
me
.
startTimer
(
"GetAttr"
,
name
)()
return
me
.
original
.
GetAttr
(
name
)
return
me
.
original
.
GetAttr
(
name
)
}
}
func
(
me
*
TimingPathFilesystem
)
GetXAttr
(
name
string
,
attr
string
)
([]
byte
,
Status
)
{
func
(
me
*
TimingPathFilesystem
)
GetXAttr
(
name
string
,
attr
string
)
([]
byte
,
Status
)
{
defer
me
.
startTimer
(
"GetXAttr"
)()
defer
me
.
startTimer
(
"GetXAttr"
,
name
)()
return
me
.
original
.
GetXAttr
(
name
,
attr
)
return
me
.
original
.
GetXAttr
(
name
,
attr
)
}
}
func
(
me
*
TimingPathFilesystem
)
Readlink
(
name
string
)
(
string
,
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Readlink
(
name
string
)
(
string
,
Status
)
{
defer
me
.
startTimer
(
"Readlink"
)()
defer
me
.
startTimer
(
"Readlink"
,
name
)()
return
me
.
original
.
Readlink
(
name
)
return
me
.
original
.
Readlink
(
name
)
}
}
func
(
me
*
TimingPathFilesystem
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
)
Status
{
func
(
me
*
TimingPathFilesystem
)
Mknod
(
name
string
,
mode
uint32
,
dev
uint32
)
Status
{
defer
me
.
startTimer
(
"Mknod"
)()
defer
me
.
startTimer
(
"Mknod"
,
name
)()
return
me
.
original
.
Mknod
(
name
,
mode
,
dev
)
return
me
.
original
.
Mknod
(
name
,
mode
,
dev
)
}
}
func
(
me
*
TimingPathFilesystem
)
Mkdir
(
name
string
,
mode
uint32
)
Status
{
func
(
me
*
TimingPathFilesystem
)
Mkdir
(
name
string
,
mode
uint32
)
Status
{
defer
me
.
startTimer
(
"Mkdir"
)()
defer
me
.
startTimer
(
"Mkdir"
,
name
)()
return
me
.
original
.
Mkdir
(
name
,
mode
)
return
me
.
original
.
Mkdir
(
name
,
mode
)
}
}
func
(
me
*
TimingPathFilesystem
)
Unlink
(
name
string
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Unlink
(
name
string
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Unlink"
)()
defer
me
.
startTimer
(
"Unlink"
,
name
)()
return
me
.
original
.
Unlink
(
name
)
return
me
.
original
.
Unlink
(
name
)
}
}
func
(
me
*
TimingPathFilesystem
)
Rmdir
(
name
string
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Rmdir
(
name
string
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Rmdir"
)()
defer
me
.
startTimer
(
"Rmdir"
,
name
)()
return
me
.
original
.
Rmdir
(
name
)
return
me
.
original
.
Rmdir
(
name
)
}
}
func
(
me
*
TimingPathFilesystem
)
Symlink
(
value
string
,
linkName
string
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Symlink
(
value
string
,
linkName
string
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Symlink"
)()
defer
me
.
startTimer
(
"Symlink"
,
linkName
)()
return
me
.
original
.
Symlink
(
value
,
linkName
)
return
me
.
original
.
Symlink
(
value
,
linkName
)
}
}
func
(
me
*
TimingPathFilesystem
)
Rename
(
oldName
string
,
newName
string
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Rename
(
oldName
string
,
newName
string
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Rename"
)()
defer
me
.
startTimer
(
"Rename"
,
oldName
)()
return
me
.
original
.
Rename
(
oldName
,
newName
)
return
me
.
original
.
Rename
(
oldName
,
newName
)
}
}
func
(
me
*
TimingPathFilesystem
)
Link
(
oldName
string
,
newName
string
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Link
(
oldName
string
,
newName
string
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Link"
)()
defer
me
.
startTimer
(
"Link"
,
newName
)()
return
me
.
original
.
Link
(
oldName
,
newName
)
return
me
.
original
.
Link
(
oldName
,
newName
)
}
}
func
(
me
*
TimingPathFilesystem
)
Chmod
(
name
string
,
mode
uint32
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Chmod
(
name
string
,
mode
uint32
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Chmod"
)()
defer
me
.
startTimer
(
"Chmod"
,
name
)()
return
me
.
original
.
Chmod
(
name
,
mode
)
return
me
.
original
.
Chmod
(
name
,
mode
)
}
}
func
(
me
*
TimingPathFilesystem
)
Chown
(
name
string
,
uid
uint32
,
gid
uint32
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Chown
(
name
string
,
uid
uint32
,
gid
uint32
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Chown"
)()
defer
me
.
startTimer
(
"Chown"
,
name
)()
return
me
.
original
.
Chown
(
name
,
uid
,
gid
)
return
me
.
original
.
Chown
(
name
,
uid
,
gid
)
}
}
func
(
me
*
TimingPathFilesystem
)
Truncate
(
name
string
,
offset
uint64
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Truncate
(
name
string
,
offset
uint64
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Truncate"
)()
defer
me
.
startTimer
(
"Truncate"
,
name
)()
return
me
.
original
.
Truncate
(
name
,
offset
)
return
me
.
original
.
Truncate
(
name
,
offset
)
}
}
func
(
me
*
TimingPathFilesystem
)
Open
(
name
string
,
flags
uint32
)
(
file
RawFuseFile
,
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Open
(
name
string
,
flags
uint32
)
(
file
RawFuseFile
,
code
Status
)
{
defer
me
.
startTimer
(
"Open"
)()
defer
me
.
startTimer
(
"Open"
,
name
)()
return
me
.
original
.
Open
(
name
,
flags
)
return
me
.
original
.
Open
(
name
,
flags
)
}
}
func
(
me
*
TimingPathFilesystem
)
OpenDir
(
name
string
)
(
stream
chan
DirEntry
,
status
Status
)
{
func
(
me
*
TimingPathFilesystem
)
OpenDir
(
name
string
)
(
stream
chan
DirEntry
,
status
Status
)
{
defer
me
.
startTimer
(
"OpenDir"
)()
defer
me
.
startTimer
(
"OpenDir"
,
name
)()
return
me
.
original
.
OpenDir
(
name
)
return
me
.
original
.
OpenDir
(
name
)
}
}
func
(
me
*
TimingPathFilesystem
)
Mount
(
conn
*
PathFileSystemConnector
)
Status
{
func
(
me
*
TimingPathFilesystem
)
Mount
(
conn
*
PathFileSystemConnector
)
Status
{
defer
me
.
startTimer
(
"Mount"
)()
defer
me
.
startTimer
(
"Mount"
,
""
)()
return
me
.
original
.
Mount
(
conn
)
return
me
.
original
.
Mount
(
conn
)
}
}
func
(
me
*
TimingPathFilesystem
)
Unmount
()
{
func
(
me
*
TimingPathFilesystem
)
Unmount
()
{
defer
me
.
startTimer
(
"Unmount"
)()
defer
me
.
startTimer
(
"Unmount"
,
""
)()
me
.
original
.
Unmount
()
me
.
original
.
Unmount
()
}
}
func
(
me
*
TimingPathFilesystem
)
Access
(
name
string
,
mode
uint32
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Access
(
name
string
,
mode
uint32
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Access"
)()
defer
me
.
startTimer
(
"Access"
,
name
)()
return
me
.
original
.
Access
(
name
,
mode
)
return
me
.
original
.
Access
(
name
,
mode
)
}
}
func
(
me
*
TimingPathFilesystem
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
)
(
file
RawFuseFile
,
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Create
(
name
string
,
flags
uint32
,
mode
uint32
)
(
file
RawFuseFile
,
code
Status
)
{
defer
me
.
startTimer
(
"Create"
)()
defer
me
.
startTimer
(
"Create"
,
name
)()
return
me
.
original
.
Create
(
name
,
flags
,
mode
)
return
me
.
original
.
Create
(
name
,
flags
,
mode
)
}
}
func
(
me
*
TimingPathFilesystem
)
Utimens
(
name
string
,
AtimeNs
uint64
,
CtimeNs
uint64
)
(
code
Status
)
{
func
(
me
*
TimingPathFilesystem
)
Utimens
(
name
string
,
AtimeNs
uint64
,
CtimeNs
uint64
)
(
code
Status
)
{
defer
me
.
startTimer
(
"Utimens"
)()
defer
me
.
startTimer
(
"Utimens"
,
name
)()
return
me
.
original
.
Utimens
(
name
,
AtimeNs
,
CtimeNs
)
return
me
.
original
.
Utimens
(
name
,
AtimeNs
,
CtimeNs
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment