Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
fuchsia.googlesource.com-third_party-github.com-pkg-sftp
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
fuchsia-mirror
fuchsia.googlesource.com-third_party-github.com-pkg-sftp
Commits
718e6477
Unverified
Commit
718e6477
authored
6 years ago
by
John Eikenberry
Committed by
GitHub
6 years ago
Browse files
Options
Downloads
Plain Diff
Merge pull request #266 from pkg/issue265
fix race w/ open packet and stat
parents
fe93131e
b0f20f99
No related branches found
Branches containing commit
Tags
v1.8.2
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
packet-manager.go
+10
-11
10 additions, 11 deletions
packet-manager.go
server_test.go
+49
-0
49 additions, 0 deletions
server_test.go
with
59 additions
and
11 deletions
packet-manager.go
+
10
−
11
View file @
718e6477
...
...
@@ -105,33 +105,32 @@ func (s *packetManager) close() {
func
(
s
*
packetManager
)
workerChan
(
runWorker
func
(
chan
orderedRequest
),
)
chan
orderedRequest
{
// multiple workers for faster read/writes
rwChan
:=
make
(
chan
orderedRequest
,
SftpServerWorkerCount
)
for
i
:=
0
;
i
<
SftpServerWorkerCount
;
i
++
{
runWorker
(
rwChan
)
}
// single worker to enforce sequential processing of everything else
cmdChan
:=
make
(
chan
orderedRequest
)
runWorker
(
cmdChan
)
pktChan
:=
make
(
chan
orderedRequest
,
SftpServerWorkerCount
)
go
func
()
{
// start with cmdChan
curChan
:=
cmdChan
for
pkt
:=
range
pktChan
{
// on file open packet, switch to rwChan
switch
pkt
.
requestPacket
.
(
type
)
{
case
*
sshFxp
Open
Packet
:
curChan
=
rwChan
// on file close packet, switch back to cmdChan
// after waiting for any reads/writes to finish
case
*
sshFxp
ReadPacket
,
*
sshFxpWrite
Packet
:
s
.
incomingPacket
(
pkt
)
rwChan
<-
pkt
continue
case
*
sshFxpClosePacket
:
// wait for rwChan to finish
// wait for reads/writes to finish when file is closed
// incomingPacket() call must occur after this
s
.
working
.
Wait
()
// stop using rwChan
curChan
=
cmdChan
}
s
.
incomingPacket
(
pkt
)
curChan
<-
pkt
// all non-RW use sequential cmdChan
cmdChan
<-
pkt
}
close
(
rwChan
)
close
(
cmdChan
)
...
...
This diff is collapsed.
Click to expand it.
server_test.go
+
49
−
0
View file @
718e6477
...
...
@@ -3,6 +3,7 @@ package sftp
import
(
"io"
"os"
"path"
"regexp"
"sync"
"syscall"
...
...
@@ -278,3 +279,51 @@ func TestStatusFromError(t *testing.T) {
assert
.
Equal
(
t
,
tc
.
pkt
,
statusFromError
(
tc
.
pkt
,
tc
.
err
))
}
}
// This was written to test a race b/w open immediately followed by a stat.
// Previous to this the Open would trigger the use of a worker pool, then the
// stat packet would come in an hit the pool and return faster than the open
// (returning a file-not-found error).
// The below by itself wouldn't trigger the race however, I needed to add a
// small sleep in the openpacket code to trigger the issue. I wanted to add a
// way to inject that in the code but right now there is no good place for it.
// I'm thinking after I convert the server into a request-server backend I
// might be able to do something with the runWorker method passed into the
// packet manager. But with the 2 implementations fo the server it just doesn't
// fit well right now.
func
TestOpenStatRace
(
t
*
testing
.
T
)
{
client
,
server
:=
clientServerPair
(
t
)
defer
client
.
Close
()
defer
server
.
Close
()
// openpacket finishes to fast to trigger race in tests
// need to add a small sleep on server to openpackets somehow
tmppath
:=
path
.
Join
(
os
.
TempDir
(),
"stat_race"
)
pflags
:=
flags
(
os
.
O_RDWR
|
os
.
O_CREATE
|
os
.
O_TRUNC
)
ch
:=
make
(
chan
result
,
3
)
id1
:=
client
.
nextID
()
client
.
dispatchRequest
(
ch
,
sshFxpOpenPacket
{
ID
:
id1
,
Path
:
tmppath
,
Pflags
:
pflags
,
})
id2
:=
client
.
nextID
()
client
.
dispatchRequest
(
ch
,
sshFxpLstatPacket
{
ID
:
id2
,
Path
:
tmppath
,
})
testreply
:=
func
(
id
uint32
,
ch
chan
result
)
{
r
:=
<-
ch
switch
r
.
typ
{
case
ssh_FXP_ATTRS
,
ssh_FXP_HANDLE
:
// ignore
case
ssh_FXP_STATUS
:
err
:=
normaliseError
(
unmarshalStatus
(
id
,
r
.
data
))
assert
.
NoError
(
t
,
err
,
"race hit, stat before open"
)
default
:
assert
.
Fail
(
t
,
"Unexpected type"
)
}
}
testreply
(
id1
,
ch
)
testreply
(
id2
,
ch
)
os
.
Remove
(
tmppath
)
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment