Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
b6939b28
Commit
b6939b28
authored
Dec 15, 2016
by
Xiang Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rollback: use 237 wal pkg
parent
69cd8055
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
1602 additions
and
2 deletions
+1602
-2
rollback.go
cluster/images/etcd/rollback/rollback.go
+4
-2
fileutil.go
third_party/forked/etcd237/pkg/fileutil/fileutil.go
+75
-0
fileutil_test.go
third_party/forked/etcd237/pkg/fileutil/fileutil_test.go
+96
-0
lock.go
third_party/forked/etcd237/pkg/fileutil/lock.go
+29
-0
lock_plan9.go
third_party/forked/etcd237/pkg/fileutil/lock_plan9.go
+79
-0
lock_solaris.go
third_party/forked/etcd237/pkg/fileutil/lock_solaris.go
+87
-0
lock_test.go
third_party/forked/etcd237/pkg/fileutil/lock_test.go
+96
-0
lock_unix.go
third_party/forked/etcd237/pkg/fileutil/lock_unix.go
+65
-0
lock_windows.go
third_party/forked/etcd237/pkg/fileutil/lock_windows.go
+60
-0
perallocate_unsupported.go
...ty/forked/etcd237/pkg/fileutil/perallocate_unsupported.go
+28
-0
preallocate.go
third_party/forked/etcd237/pkg/fileutil/preallocate.go
+42
-0
preallocate_test.go
third_party/forked/etcd237/pkg/fileutil/preallocate_test.go
+53
-0
purge.go
third_party/forked/etcd237/pkg/fileutil/purge.go
+80
-0
purge_test.go
third_party/forked/etcd237/pkg/fileutil/purge_test.go
+161
-0
sync.go
third_party/forked/etcd237/pkg/fileutil/sync.go
+26
-0
sync_linux.go
third_party/forked/etcd237/pkg/fileutil/sync_linux.go
+29
-0
decoder.go
third_party/forked/etcd237/wal/decoder.go
+103
-0
doc.go
third_party/forked/etcd237/wal/doc.go
+68
-0
encoder.go
third_party/forked/etcd237/wal/encoder.go
+89
-0
metrics.go
third_party/forked/etcd237/wal/metrics.go
+38
-0
multi_readcloser.go
third_party/forked/etcd237/wal/multi_readcloser.go
+45
-0
repair.go
third_party/forked/etcd237/wal/repair.go
+107
-0
util.go
third_party/forked/etcd237/wal/util.go
+93
-0
wal.go
third_party/forked/etcd237/wal/wal.go
+0
-0
record.go
third_party/forked/etcd237/wal/walpb/record.go
+29
-0
record.pb.go
third_party/forked/etcd237/wal/walpb/record.pb.go
+0
-0
record.proto
third_party/forked/etcd237/wal/walpb/record.proto
+20
-0
No files found.
cluster/images/etcd/rollback/rollback.go
View file @
b6939b28
...
...
@@ -26,6 +26,8 @@ import (
"strings"
"time"
wal237
"k8s.io/kubernetes/third_party/forked/etcd237/wal"
"github.com/coreos/etcd/etcdserver"
pb
"github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/etcdserver/membership"
...
...
@@ -42,7 +44,7 @@ import (
"github.com/golang/glog"
)
const
rollbackVersion
=
"2.
3.7
"
const
rollbackVersion
=
"2.
2.0
"
var
(
migrateDatadir
=
flag
.
String
(
"data-dir"
,
""
,
"Path to the data directory"
)
...
...
@@ -116,7 +118,7 @@ func main() {
}
walDir
:=
path
.
Join
(
*
migrateDatadir
,
"member"
,
"wal"
)
w
,
err
:=
wal
.
Create
(
walDir
,
metadata
)
w
,
err
:=
wal
237
.
Create
(
walDir
,
metadata
)
if
err
!=
nil
{
glog
.
Fatal
(
err
)
}
...
...
third_party/forked/etcd237/pkg/fileutil/fileutil.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package fileutil implements utility functions related to files and paths.
package
fileutil
import
(
"io/ioutil"
"os"
"path"
"sort"
"github.com/coreos/pkg/capnslog"
)
const
(
privateFileMode
=
0600
// owner can make/remove files inside the directory
privateDirMode
=
0700
)
var
(
plog
=
capnslog
.
NewPackageLogger
(
"github.com/coreos/etcd/pkg"
,
"fileutil"
)
)
// IsDirWriteable checks if dir is writable by writing and removing a file
// to dir. It returns nil if dir is writable.
func
IsDirWriteable
(
dir
string
)
error
{
f
:=
path
.
Join
(
dir
,
".touch"
)
if
err
:=
ioutil
.
WriteFile
(
f
,
[]
byte
(
""
),
privateFileMode
);
err
!=
nil
{
return
err
}
return
os
.
Remove
(
f
)
}
// ReadDir returns the filenames in the given directory in sorted order.
func
ReadDir
(
dirpath
string
)
([]
string
,
error
)
{
dir
,
err
:=
os
.
Open
(
dirpath
)
if
err
!=
nil
{
return
nil
,
err
}
defer
dir
.
Close
()
names
,
err
:=
dir
.
Readdirnames
(
-
1
)
if
err
!=
nil
{
return
nil
,
err
}
sort
.
Strings
(
names
)
return
names
,
nil
}
// TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory
// does not exists. TouchDirAll also ensures the given directory is writable.
func
TouchDirAll
(
dir
string
)
error
{
err
:=
os
.
MkdirAll
(
dir
,
privateDirMode
)
if
err
!=
nil
&&
err
!=
os
.
ErrExist
{
return
err
}
return
IsDirWriteable
(
dir
)
}
func
Exist
(
name
string
)
bool
{
_
,
err
:=
os
.
Stat
(
name
)
return
err
==
nil
}
third_party/forked/etcd237/pkg/fileutil/fileutil_test.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fileutil
import
(
"io/ioutil"
"os"
"os/user"
"path/filepath"
"reflect"
"testing"
)
func
TestIsDirWriteable
(
t
*
testing
.
T
)
{
tmpdir
,
err
:=
ioutil
.
TempDir
(
""
,
""
)
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected ioutil.TempDir error: %v"
,
err
)
}
defer
os
.
RemoveAll
(
tmpdir
)
if
err
=
IsDirWriteable
(
tmpdir
);
err
!=
nil
{
t
.
Fatalf
(
"unexpected IsDirWriteable error: %v"
,
err
)
}
if
err
=
os
.
Chmod
(
tmpdir
,
0444
);
err
!=
nil
{
t
.
Fatalf
(
"unexpected os.Chmod error: %v"
,
err
)
}
me
,
err
:=
user
.
Current
()
if
err
!=
nil
{
// err can be non-nil when cross compiled
// http://stackoverflow.com/questions/20609415/cross-compiling-user-current-not-implemented-on-linux-amd64
t
.
Skipf
(
"failed to get current user: %v"
,
err
)
}
if
me
.
Name
==
"root"
||
me
.
Name
==
"Administrator"
{
// ideally we should check CAP_DAC_OVERRIDE.
// but it does not matter for tests.
t
.
Skipf
(
"running as a superuser"
)
}
if
err
:=
IsDirWriteable
(
tmpdir
);
err
==
nil
{
t
.
Fatalf
(
"expected IsDirWriteable to error"
)
}
}
func
TestReadDir
(
t
*
testing
.
T
)
{
tmpdir
,
err
:=
ioutil
.
TempDir
(
""
,
""
)
defer
os
.
RemoveAll
(
tmpdir
)
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected ioutil.TempDir error: %v"
,
err
)
}
files
:=
[]
string
{
"def"
,
"abc"
,
"xyz"
,
"ghi"
}
for
_
,
f
:=
range
files
{
var
fh
*
os
.
File
fh
,
err
=
os
.
Create
(
filepath
.
Join
(
tmpdir
,
f
))
if
err
!=
nil
{
t
.
Fatalf
(
"error creating file: %v"
,
err
)
}
if
err
=
fh
.
Close
();
err
!=
nil
{
t
.
Fatalf
(
"error closing file: %v"
,
err
)
}
}
fs
,
err
:=
ReadDir
(
tmpdir
)
if
err
!=
nil
{
t
.
Fatalf
(
"error calling ReadDir: %v"
,
err
)
}
wfs
:=
[]
string
{
"abc"
,
"def"
,
"ghi"
,
"xyz"
}
if
!
reflect
.
DeepEqual
(
fs
,
wfs
)
{
t
.
Fatalf
(
"ReadDir: got %v, want %v"
,
fs
,
wfs
)
}
}
func
TestExist
(
t
*
testing
.
T
)
{
f
,
err
:=
ioutil
.
TempFile
(
os
.
TempDir
(),
"fileutil"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
f
.
Close
()
if
g
:=
Exist
(
f
.
Name
());
g
!=
true
{
t
.
Errorf
(
"exist = %v, want true"
,
g
)
}
os
.
Remove
(
f
.
Name
())
if
g
:=
Exist
(
f
.
Name
());
g
!=
false
{
t
.
Errorf
(
"exist = %v, want false"
,
g
)
}
}
third_party/forked/etcd237/pkg/fileutil/lock.go
0 → 100644
View file @
b6939b28
// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fileutil
type
Lock
interface
{
// Name returns the name of the file.
Name
()
string
// TryLock acquires exclusivity on the lock without blocking.
TryLock
()
error
// Lock acquires exclusivity on the lock.
Lock
()
error
// Unlock unlocks the lock.
Unlock
()
error
// Destroy should be called after Unlock to clean up
// the resources.
Destroy
()
error
}
third_party/forked/etcd237/pkg/fileutil/lock_plan9.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fileutil
import
(
"errors"
"os"
"syscall"
"time"
)
var
(
ErrLocked
=
errors
.
New
(
"file already locked"
)
)
type
lock
struct
{
fname
string
file
*
os
.
File
}
func
(
l
*
lock
)
Name
()
string
{
return
l
.
fname
}
func
(
l
*
lock
)
TryLock
()
error
{
err
:=
os
.
Chmod
(
l
.
fname
,
syscall
.
DMEXCL
|
0600
)
if
err
!=
nil
{
return
err
}
f
,
err
:=
os
.
Open
(
l
.
fname
)
if
err
!=
nil
{
return
ErrLocked
}
l
.
file
=
f
return
nil
}
func
(
l
*
lock
)
Lock
()
error
{
err
:=
os
.
Chmod
(
l
.
fname
,
syscall
.
DMEXCL
|
0600
)
if
err
!=
nil
{
return
err
}
for
{
f
,
err
:=
os
.
Open
(
l
.
fname
)
if
err
==
nil
{
l
.
file
=
f
return
nil
}
time
.
Sleep
(
10
*
time
.
Millisecond
)
}
}
func
(
l
*
lock
)
Unlock
()
error
{
return
l
.
file
.
Close
()
}
func
(
l
*
lock
)
Destroy
()
error
{
return
nil
}
func
NewLock
(
file
string
)
(
Lock
,
error
)
{
l
:=
&
lock
{
fname
:
file
}
return
l
,
nil
}
third_party/forked/etcd237/pkg/fileutil/lock_solaris.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build solaris
package
fileutil
import
(
"errors"
"os"
"syscall"
)
var
(
ErrLocked
=
errors
.
New
(
"file already locked"
)
)
type
lock
struct
{
fd
int
file
*
os
.
File
}
func
(
l
*
lock
)
Name
()
string
{
return
l
.
file
.
Name
()
}
func
(
l
*
lock
)
TryLock
()
error
{
var
lock
syscall
.
Flock_t
lock
.
Start
=
0
lock
.
Len
=
0
lock
.
Pid
=
0
lock
.
Type
=
syscall
.
F_WRLCK
lock
.
Whence
=
0
lock
.
Pid
=
0
err
:=
syscall
.
FcntlFlock
(
uintptr
(
l
.
fd
),
syscall
.
F_SETLK
,
&
lock
)
if
err
!=
nil
&&
err
==
syscall
.
EAGAIN
{
return
ErrLocked
}
return
err
}
func
(
l
*
lock
)
Lock
()
error
{
var
lock
syscall
.
Flock_t
lock
.
Start
=
0
lock
.
Len
=
0
lock
.
Type
=
syscall
.
F_WRLCK
lock
.
Whence
=
0
lock
.
Pid
=
0
return
syscall
.
FcntlFlock
(
uintptr
(
l
.
fd
),
syscall
.
F_SETLK
,
&
lock
)
}
func
(
l
*
lock
)
Unlock
()
error
{
var
lock
syscall
.
Flock_t
lock
.
Start
=
0
lock
.
Len
=
0
lock
.
Type
=
syscall
.
F_UNLCK
lock
.
Whence
=
0
err
:=
syscall
.
FcntlFlock
(
uintptr
(
l
.
fd
),
syscall
.
F_SETLK
,
&
lock
)
if
err
!=
nil
&&
err
==
syscall
.
EAGAIN
{
return
ErrLocked
}
return
err
}
func
(
l
*
lock
)
Destroy
()
error
{
return
l
.
file
.
Close
()
}
func
NewLock
(
file
string
)
(
Lock
,
error
)
{
f
,
err
:=
os
.
OpenFile
(
file
,
os
.
O_WRONLY
,
0600
)
if
err
!=
nil
{
return
nil
,
err
}
l
:=
&
lock
{
int
(
f
.
Fd
()),
f
}
return
l
,
nil
}
third_party/forked/etcd237/pkg/fileutil/lock_test.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fileutil
import
(
"io/ioutil"
"os"
"testing"
"time"
)
func
TestLockAndUnlock
(
t
*
testing
.
T
)
{
f
,
err
:=
ioutil
.
TempFile
(
""
,
"lock"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
f
.
Close
()
defer
func
()
{
err
=
os
.
Remove
(
f
.
Name
())
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}()
// lock the file
l
,
err
:=
NewLock
(
f
.
Name
())
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
l
.
Destroy
()
err
=
l
.
Lock
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// try lock a locked file
dupl
,
err
:=
NewLock
(
f
.
Name
())
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
dupl
.
TryLock
()
if
err
!=
ErrLocked
{
t
.
Errorf
(
"err = %v, want %v"
,
err
,
ErrLocked
)
}
// unlock the file
err
=
l
.
Unlock
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// try lock the unlocked file
err
=
dupl
.
TryLock
()
if
err
!=
nil
{
t
.
Errorf
(
"err = %v, want %v"
,
err
,
nil
)
}
defer
dupl
.
Destroy
()
// blocking on locked file
locked
:=
make
(
chan
struct
{},
1
)
go
func
()
{
l
.
Lock
()
locked
<-
struct
{}{}
}()
select
{
case
<-
locked
:
t
.
Error
(
"unexpected unblocking"
)
case
<-
time
.
After
(
100
*
time
.
Millisecond
)
:
}
// unlock
err
=
dupl
.
Unlock
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// the previously blocked routine should be unblocked
select
{
case
<-
locked
:
case
<-
time
.
After
(
1
*
time
.
Second
)
:
t
.
Error
(
"unexpected blocking"
)
}
}
third_party/forked/etcd237/pkg/fileutil/lock_unix.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !windows,!plan9,!solaris
package
fileutil
import
(
"errors"
"os"
"syscall"
)
var
(
ErrLocked
=
errors
.
New
(
"file already locked"
)
)
type
lock
struct
{
fd
int
file
*
os
.
File
}
func
(
l
*
lock
)
Name
()
string
{
return
l
.
file
.
Name
()
}
func
(
l
*
lock
)
TryLock
()
error
{
err
:=
syscall
.
Flock
(
l
.
fd
,
syscall
.
LOCK_EX
|
syscall
.
LOCK_NB
)
if
err
!=
nil
&&
err
==
syscall
.
EWOULDBLOCK
{
return
ErrLocked
}
return
err
}
func
(
l
*
lock
)
Lock
()
error
{
return
syscall
.
Flock
(
l
.
fd
,
syscall
.
LOCK_EX
)
}
func
(
l
*
lock
)
Unlock
()
error
{
return
syscall
.
Flock
(
l
.
fd
,
syscall
.
LOCK_UN
)
}
func
(
l
*
lock
)
Destroy
()
error
{
return
l
.
file
.
Close
()
}
func
NewLock
(
file
string
)
(
Lock
,
error
)
{
f
,
err
:=
os
.
Open
(
file
)
if
err
!=
nil
{
return
nil
,
err
}
l
:=
&
lock
{
int
(
f
.
Fd
()),
f
}
return
l
,
nil
}
third_party/forked/etcd237/pkg/fileutil/lock_windows.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build windows
package
fileutil
import
(
"errors"
"os"
)
var
(
ErrLocked
=
errors
.
New
(
"file already locked"
)
)
type
lock
struct
{
fd
int
file
*
os
.
File
}
func
(
l
*
lock
)
Name
()
string
{
return
l
.
file
.
Name
()
}
func
(
l
*
lock
)
TryLock
()
error
{
return
nil
}
func
(
l
*
lock
)
Lock
()
error
{
return
nil
}
func
(
l
*
lock
)
Unlock
()
error
{
return
nil
}
func
(
l
*
lock
)
Destroy
()
error
{
return
l
.
file
.
Close
()
}
func
NewLock
(
file
string
)
(
Lock
,
error
)
{
f
,
err
:=
os
.
Open
(
file
)
if
err
!=
nil
{
return
nil
,
err
}
l
:=
&
lock
{
int
(
f
.
Fd
()),
f
}
return
l
,
nil
}
third_party/forked/etcd237/pkg/fileutil/perallocate_unsupported.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !linux
package
fileutil
import
"os"
// Preallocate tries to allocate the space for given
// file. This operation is only supported on linux by a
// few filesystems (btrfs, ext4, etc.).
// If the operation is unsupported, no error will be returned.
// Otherwise, the error encountered will be returned.
func
Preallocate
(
f
*
os
.
File
,
sizeInBytes
int
)
error
{
return
nil
}
third_party/forked/etcd237/pkg/fileutil/preallocate.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build linux
package
fileutil
import
(
"os"
"syscall"
)
// Preallocate tries to allocate the space for given
// file. This operation is only supported on linux by a
// few filesystems (btrfs, ext4, etc.).
// If the operation is unsupported, no error will be returned.
// Otherwise, the error encountered will be returned.
func
Preallocate
(
f
*
os
.
File
,
sizeInBytes
int
)
error
{
// use mode = 1 to keep size
// see FALLOC_FL_KEEP_SIZE
err
:=
syscall
.
Fallocate
(
int
(
f
.
Fd
()),
1
,
0
,
int64
(
sizeInBytes
))
if
err
!=
nil
{
errno
,
ok
:=
err
.
(
syscall
.
Errno
)
// treat not support as nil error
if
ok
&&
errno
==
syscall
.
ENOTSUP
{
return
nil
}
return
err
}
return
nil
}
third_party/forked/etcd237/pkg/fileutil/preallocate_test.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fileutil
import
(
"io/ioutil"
"os"
"runtime"
"testing"
)
func
TestPreallocate
(
t
*
testing
.
T
)
{
if
runtime
.
GOOS
!=
"linux"
{
t
.
Skipf
(
"skip testPreallocate, OS = %s"
,
runtime
.
GOOS
)
}
p
,
err
:=
ioutil
.
TempDir
(
os
.
TempDir
(),
"preallocateTest"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
os
.
RemoveAll
(
p
)
f
,
err
:=
ioutil
.
TempFile
(
p
,
""
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
size
:=
64
*
1000
err
=
Preallocate
(
f
,
size
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
stat
,
err
:=
f
.
Stat
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
stat
.
Size
()
!=
0
{
t
.
Errorf
(
"size = %d, want %d"
,
stat
.
Size
(),
0
)
}
}
third_party/forked/etcd237/pkg/fileutil/purge.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fileutil
import
(
"os"
"path"
"sort"
"strings"
"time"
)
func
PurgeFile
(
dirname
string
,
suffix
string
,
max
uint
,
interval
time
.
Duration
,
stop
<-
chan
struct
{})
<-
chan
error
{
errC
:=
make
(
chan
error
,
1
)
go
func
()
{
for
{
fnames
,
err
:=
ReadDir
(
dirname
)
if
err
!=
nil
{
errC
<-
err
return
}
newfnames
:=
make
([]
string
,
0
)
for
_
,
fname
:=
range
fnames
{
if
strings
.
HasSuffix
(
fname
,
suffix
)
{
newfnames
=
append
(
newfnames
,
fname
)
}
}
sort
.
Strings
(
newfnames
)
for
len
(
newfnames
)
>
int
(
max
)
{
f
:=
path
.
Join
(
dirname
,
newfnames
[
0
])
l
,
err
:=
NewLock
(
f
)
if
err
!=
nil
{
errC
<-
err
return
}
err
=
l
.
TryLock
()
if
err
!=
nil
{
break
}
err
=
os
.
Remove
(
f
)
if
err
!=
nil
{
errC
<-
err
return
}
err
=
l
.
Unlock
()
if
err
!=
nil
{
plog
.
Errorf
(
"error unlocking %s when purging file (%v)"
,
l
.
Name
(),
err
)
errC
<-
err
return
}
err
=
l
.
Destroy
()
if
err
!=
nil
{
plog
.
Errorf
(
"error destroying lock %s when purging file (%v)"
,
l
.
Name
(),
err
)
errC
<-
err
return
}
plog
.
Infof
(
"purged file %s successfully"
,
f
)
newfnames
=
newfnames
[
1
:
]
}
select
{
case
<-
time
.
After
(
interval
)
:
case
<-
stop
:
return
}
}
}()
return
errC
}
third_party/forked/etcd237/pkg/fileutil/purge_test.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
fileutil
import
(
"fmt"
"io/ioutil"
"os"
"path"
"reflect"
"testing"
"time"
)
func
TestPurgeFile
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"purgefile"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
os
.
RemoveAll
(
dir
)
for
i
:=
0
;
i
<
5
;
i
++
{
_
,
err
=
os
.
Create
(
path
.
Join
(
dir
,
fmt
.
Sprintf
(
"%d.test"
,
i
)))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
stop
:=
make
(
chan
struct
{})
// keep at most 3 most recent files
errch
:=
PurgeFile
(
dir
,
"test"
,
3
,
time
.
Millisecond
,
stop
)
// create 5 more files
for
i
:=
5
;
i
<
10
;
i
++
{
_
,
err
=
os
.
Create
(
path
.
Join
(
dir
,
fmt
.
Sprintf
(
"%d.test"
,
i
)))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
time
.
Sleep
(
10
*
time
.
Millisecond
)
}
// purge routine should purge 7 out of 10 files and only keep the
// 3 most recent ones.
// wait for purging for at most 100ms.
var
fnames
[]
string
for
i
:=
0
;
i
<
10
;
i
++
{
fnames
,
err
=
ReadDir
(
dir
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
fnames
)
<=
3
{
break
}
time
.
Sleep
(
10
*
time
.
Millisecond
)
}
wnames
:=
[]
string
{
"7.test"
,
"8.test"
,
"9.test"
}
if
!
reflect
.
DeepEqual
(
fnames
,
wnames
)
{
t
.
Errorf
(
"filenames = %v, want %v"
,
fnames
,
wnames
)
}
// no error should be reported from purge routine
select
{
case
err
:=
<-
errch
:
t
.
Errorf
(
"unexpected purge error %v"
,
err
)
case
<-
time
.
After
(
time
.
Millisecond
)
:
}
close
(
stop
)
}
func
TestPurgeFileHoldingLock
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"purgefile"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
os
.
RemoveAll
(
dir
)
for
i
:=
0
;
i
<
10
;
i
++
{
_
,
err
=
os
.
Create
(
path
.
Join
(
dir
,
fmt
.
Sprintf
(
"%d.test"
,
i
)))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
// create a purge barrier at 5
l
,
err
:=
NewLock
(
path
.
Join
(
dir
,
fmt
.
Sprintf
(
"%d.test"
,
5
)))
err
=
l
.
Lock
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
stop
:=
make
(
chan
struct
{})
errch
:=
PurgeFile
(
dir
,
"test"
,
3
,
time
.
Millisecond
,
stop
)
var
fnames
[]
string
for
i
:=
0
;
i
<
10
;
i
++
{
fnames
,
err
=
ReadDir
(
dir
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
fnames
)
<=
5
{
break
}
time
.
Sleep
(
10
*
time
.
Millisecond
)
}
wnames
:=
[]
string
{
"5.test"
,
"6.test"
,
"7.test"
,
"8.test"
,
"9.test"
}
if
!
reflect
.
DeepEqual
(
fnames
,
wnames
)
{
t
.
Errorf
(
"filenames = %v, want %v"
,
fnames
,
wnames
)
}
select
{
case
err
=
<-
errch
:
t
.
Errorf
(
"unexpected purge error %v"
,
err
)
case
<-
time
.
After
(
time
.
Millisecond
)
:
}
// remove the purge barrier
err
=
l
.
Unlock
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
l
.
Destroy
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
for
i
:=
0
;
i
<
10
;
i
++
{
fnames
,
err
=
ReadDir
(
dir
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
fnames
)
<=
3
{
break
}
time
.
Sleep
(
10
*
time
.
Millisecond
)
}
wnames
=
[]
string
{
"7.test"
,
"8.test"
,
"9.test"
}
if
!
reflect
.
DeepEqual
(
fnames
,
wnames
)
{
t
.
Errorf
(
"filenames = %v, want %v"
,
fnames
,
wnames
)
}
select
{
case
err
:=
<-
errch
:
t
.
Errorf
(
"unexpected purge error %v"
,
err
)
case
<-
time
.
After
(
time
.
Millisecond
)
:
}
close
(
stop
)
}
third_party/forked/etcd237/pkg/fileutil/sync.go
0 → 100644
View file @
b6939b28
// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !linux
package
fileutil
import
"os"
// Fdatasync is similar to fsync(), but does not flush modified metadata
// unless that metadata is needed in order to allow a subsequent data retrieval
// to be correctly handled.
func
Fdatasync
(
f
*
os
.
File
)
error
{
return
f
.
Sync
()
}
third_party/forked/etcd237/pkg/fileutil/sync_linux.go
0 → 100644
View file @
b6939b28
// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build linux
package
fileutil
import
(
"os"
"syscall"
)
// Fdatasync is similar to fsync(), but does not flush modified metadata
// unless that metadata is needed in order to allow a subsequent data retrieval
// to be correctly handled.
func
Fdatasync
(
f
*
os
.
File
)
error
{
return
syscall
.
Fdatasync
(
int
(
f
.
Fd
()))
}
third_party/forked/etcd237/wal/decoder.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
wal
import
(
"bufio"
"encoding/binary"
"hash"
"io"
"sync"
"github.com/coreos/etcd/pkg/crc"
"github.com/coreos/etcd/pkg/pbutil"
"github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/wal/walpb"
)
type
decoder
struct
{
mu
sync
.
Mutex
br
*
bufio
.
Reader
c
io
.
Closer
crc
hash
.
Hash32
}
func
newDecoder
(
rc
io
.
ReadCloser
)
*
decoder
{
return
&
decoder
{
br
:
bufio
.
NewReader
(
rc
),
c
:
rc
,
crc
:
crc
.
New
(
0
,
crcTable
),
}
}
func
(
d
*
decoder
)
decode
(
rec
*
walpb
.
Record
)
error
{
d
.
mu
.
Lock
()
defer
d
.
mu
.
Unlock
()
rec
.
Reset
()
l
,
err
:=
readInt64
(
d
.
br
)
if
err
!=
nil
{
return
err
}
data
:=
make
([]
byte
,
l
)
if
_
,
err
=
io
.
ReadFull
(
d
.
br
,
data
);
err
!=
nil
{
// ReadFull returns io.EOF only if no bytes were read
// the decoder should treat this as an ErrUnexpectedEOF instead.
if
err
==
io
.
EOF
{
err
=
io
.
ErrUnexpectedEOF
}
return
err
}
if
err
:=
rec
.
Unmarshal
(
data
);
err
!=
nil
{
return
err
}
// skip crc checking if the record type is crcType
if
rec
.
Type
==
crcType
{
return
nil
}
d
.
crc
.
Write
(
rec
.
Data
)
return
rec
.
Validate
(
d
.
crc
.
Sum32
())
}
func
(
d
*
decoder
)
updateCRC
(
prevCrc
uint32
)
{
d
.
crc
=
crc
.
New
(
prevCrc
,
crcTable
)
}
func
(
d
*
decoder
)
lastCRC
()
uint32
{
return
d
.
crc
.
Sum32
()
}
func
(
d
*
decoder
)
close
()
error
{
return
d
.
c
.
Close
()
}
func
mustUnmarshalEntry
(
d
[]
byte
)
raftpb
.
Entry
{
var
e
raftpb
.
Entry
pbutil
.
MustUnmarshal
(
&
e
,
d
)
return
e
}
func
mustUnmarshalState
(
d
[]
byte
)
raftpb
.
HardState
{
var
s
raftpb
.
HardState
pbutil
.
MustUnmarshal
(
&
s
,
d
)
return
s
}
func
readInt64
(
r
io
.
Reader
)
(
int64
,
error
)
{
var
n
int64
err
:=
binary
.
Read
(
r
,
binary
.
LittleEndian
,
&
n
)
return
n
,
err
}
third_party/forked/etcd237/wal/doc.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
Package wal provides an implementation of a write ahead log that is used by
etcd.
A WAL is created at a particular directory and is made up of a number of
segmented WAL files. Inside of each file the raft state and entries are appended
to it with the Save method:
metadata := []byte{}
w, err := wal.Create("/var/lib/etcd", metadata)
...
err := w.Save(s, ents)
After saving an raft snapshot to disk, SaveSnapshot method should be called to
record it. So WAL can match with the saved snapshot when restarting.
err := w.SaveSnapshot(walpb.Snapshot{Index: 10, Term: 2})
When a user has finished using a WAL it must be closed:
w.Close()
WAL files are placed inside of the directory in the following format:
$seq-$index.wal
The first WAL file to be created will be 0000000000000000-0000000000000000.wal
indicating an initial sequence of 0 and an initial raft index of 0. The first
entry written to WAL MUST have raft index 0.
WAL will cuts its current wal files if its size exceeds 8MB. This will increment an internal
sequence number and cause a new file to be created. If the last raft index saved
was 0x20 and this is the first time cut has been called on this WAL then the sequence will
increment from 0x0 to 0x1. The new file will be: 0000000000000001-0000000000000021.wal.
If a second cut issues 0x10 entries with incremental index later then the file will be called:
0000000000000002-0000000000000031.wal.
At a later time a WAL can be opened at a particular snapshot. If there is no
snapshot, an empty snapshot should be passed in.
w, err := wal.Open("/var/lib/etcd", walpb.Snapshot{Index: 10, Term: 2})
...
The snapshot must have been written to the WAL.
Additional items cannot be Saved to this WAL until all of the items from the given
snapshot to the end of the WAL are read first:
metadata, state, ents, err := w.ReadAll()
This will give you the metadata, the last raft.State and the slice of
raft.Entry items in the log.
*/
package
wal
third_party/forked/etcd237/wal/encoder.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
wal
import
(
"bufio"
"encoding/binary"
"hash"
"io"
"sync"
"github.com/coreos/etcd/pkg/crc"
"github.com/coreos/etcd/wal/walpb"
)
type
encoder
struct
{
mu
sync
.
Mutex
bw
*
bufio
.
Writer
crc
hash
.
Hash32
buf
[]
byte
uint64buf
[]
byte
}
func
newEncoder
(
w
io
.
Writer
,
prevCrc
uint32
)
*
encoder
{
return
&
encoder
{
bw
:
bufio
.
NewWriter
(
w
),
crc
:
crc
.
New
(
prevCrc
,
crcTable
),
// 1MB buffer
buf
:
make
([]
byte
,
1024
*
1024
),
uint64buf
:
make
([]
byte
,
8
),
}
}
func
(
e
*
encoder
)
encode
(
rec
*
walpb
.
Record
)
error
{
e
.
mu
.
Lock
()
defer
e
.
mu
.
Unlock
()
e
.
crc
.
Write
(
rec
.
Data
)
rec
.
Crc
=
e
.
crc
.
Sum32
()
var
(
data
[]
byte
err
error
n
int
)
if
rec
.
Size
()
>
len
(
e
.
buf
)
{
data
,
err
=
rec
.
Marshal
()
if
err
!=
nil
{
return
err
}
}
else
{
n
,
err
=
rec
.
MarshalTo
(
e
.
buf
)
if
err
!=
nil
{
return
err
}
data
=
e
.
buf
[
:
n
]
}
if
err
=
writeInt64
(
e
.
bw
,
int64
(
len
(
data
)),
e
.
uint64buf
);
err
!=
nil
{
return
err
}
_
,
err
=
e
.
bw
.
Write
(
data
)
return
err
}
func
(
e
*
encoder
)
flush
()
error
{
e
.
mu
.
Lock
()
defer
e
.
mu
.
Unlock
()
return
e
.
bw
.
Flush
()
}
func
writeInt64
(
w
io
.
Writer
,
n
int64
,
buf
[]
byte
)
error
{
// http://golang.org/src/encoding/binary/binary.go
binary
.
LittleEndian
.
PutUint64
(
buf
,
uint64
(
n
))
_
,
err
:=
w
.
Write
(
buf
)
return
err
}
third_party/forked/etcd237/wal/metrics.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
wal
import
"github.com/prometheus/client_golang/prometheus"
var
(
syncDurations
=
prometheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Namespace
:
"etcd"
,
Subsystem
:
"wal"
,
Name
:
"fsync_durations_seconds"
,
Help
:
"The latency distributions of fsync called by wal."
,
Buckets
:
prometheus
.
ExponentialBuckets
(
0.001
,
2
,
14
),
})
lastIndexSaved
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Namespace
:
"etcd"
,
Subsystem
:
"wal"
,
Name
:
"last_index_saved"
,
Help
:
"The index of the last entry saved by wal."
,
})
)
func
init
()
{
prometheus
.
MustRegister
(
syncDurations
)
prometheus
.
MustRegister
(
lastIndexSaved
)
}
third_party/forked/etcd237/wal/multi_readcloser.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
wal
import
"io"
type
multiReadCloser
struct
{
closers
[]
io
.
Closer
reader
io
.
Reader
}
func
(
mc
*
multiReadCloser
)
Close
()
error
{
var
err
error
for
i
:=
range
mc
.
closers
{
err
=
mc
.
closers
[
i
]
.
Close
()
}
return
err
}
func
(
mc
*
multiReadCloser
)
Read
(
p
[]
byte
)
(
int
,
error
)
{
return
mc
.
reader
.
Read
(
p
)
}
func
MultiReadCloser
(
readClosers
...
io
.
ReadCloser
)
io
.
ReadCloser
{
cs
:=
make
([]
io
.
Closer
,
len
(
readClosers
))
rs
:=
make
([]
io
.
Reader
,
len
(
readClosers
))
for
i
:=
range
readClosers
{
cs
[
i
]
=
readClosers
[
i
]
rs
[
i
]
=
readClosers
[
i
]
}
r
:=
io
.
MultiReader
(
rs
...
)
return
&
multiReadCloser
{
cs
,
r
}
}
third_party/forked/etcd237/wal/repair.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
wal
import
(
"io"
"os"
"path"
"k8s.io/kubernetes/third_party/forked/etcd237/pkg/fileutil"
"github.com/coreos/etcd/wal/walpb"
)
// Repair tries to repair ErrUnexpectedEOF in the
// last wal file by truncating.
func
Repair
(
dirpath
string
)
bool
{
f
,
err
:=
openLast
(
dirpath
)
if
err
!=
nil
{
return
false
}
defer
f
.
Close
()
n
:=
0
rec
:=
&
walpb
.
Record
{}
decoder
:=
newDecoder
(
f
)
defer
decoder
.
close
()
for
{
err
:=
decoder
.
decode
(
rec
)
switch
err
{
case
nil
:
n
+=
8
+
rec
.
Size
()
// update crc of the decoder when necessary
switch
rec
.
Type
{
case
crcType
:
crc
:=
decoder
.
crc
.
Sum32
()
// current crc of decoder must match the crc of the record.
// do no need to match 0 crc, since the decoder is a new one at this case.
if
crc
!=
0
&&
rec
.
Validate
(
crc
)
!=
nil
{
return
false
}
decoder
.
updateCRC
(
rec
.
Crc
)
}
continue
case
io
.
EOF
:
return
true
case
io
.
ErrUnexpectedEOF
:
plog
.
Noticef
(
"repairing %v"
,
f
.
Name
())
bf
,
bferr
:=
os
.
Create
(
f
.
Name
()
+
".broken"
)
if
bferr
!=
nil
{
plog
.
Errorf
(
"could not repair %v, failed to create backup file"
,
f
.
Name
())
return
false
}
defer
bf
.
Close
()
if
_
,
err
=
f
.
Seek
(
0
,
os
.
SEEK_SET
);
err
!=
nil
{
plog
.
Errorf
(
"could not repair %v, failed to read file"
,
f
.
Name
())
return
false
}
if
_
,
err
=
io
.
Copy
(
bf
,
f
);
err
!=
nil
{
plog
.
Errorf
(
"could not repair %v, failed to copy file"
,
f
.
Name
())
return
false
}
if
err
=
f
.
Truncate
(
int64
(
n
));
err
!=
nil
{
plog
.
Errorf
(
"could not repair %v, failed to truncate file"
,
f
.
Name
())
return
false
}
if
err
=
f
.
Sync
();
err
!=
nil
{
plog
.
Errorf
(
"could not repair %v, failed to sync file"
,
f
.
Name
())
return
false
}
return
true
default
:
plog
.
Errorf
(
"could not repair error (%v)"
,
err
)
return
false
}
}
}
// openLast opens the last wal file for read and write.
func
openLast
(
dirpath
string
)
(
*
os
.
File
,
error
)
{
names
,
err
:=
fileutil
.
ReadDir
(
dirpath
)
if
err
!=
nil
{
return
nil
,
err
}
names
=
checkWalNames
(
names
)
if
len
(
names
)
==
0
{
return
nil
,
ErrFileNotFound
}
last
:=
path
.
Join
(
dirpath
,
names
[
len
(
names
)
-
1
])
return
os
.
OpenFile
(
last
,
os
.
O_RDWR
,
0
)
}
third_party/forked/etcd237/wal/util.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
wal
import
(
"errors"
"fmt"
"strings"
"k8s.io/kubernetes/third_party/forked/etcd237/pkg/fileutil"
)
var
(
badWalName
=
errors
.
New
(
"bad wal name"
)
)
func
Exist
(
dirpath
string
)
bool
{
names
,
err
:=
fileutil
.
ReadDir
(
dirpath
)
if
err
!=
nil
{
return
false
}
return
len
(
names
)
!=
0
}
// searchIndex returns the last array index of names whose raft index section is
// equal to or smaller than the given index.
// The given names MUST be sorted.
func
searchIndex
(
names
[]
string
,
index
uint64
)
(
int
,
bool
)
{
for
i
:=
len
(
names
)
-
1
;
i
>=
0
;
i
--
{
name
:=
names
[
i
]
_
,
curIndex
,
err
:=
parseWalName
(
name
)
if
err
!=
nil
{
plog
.
Panicf
(
"parse correct name should never fail: %v"
,
err
)
}
if
index
>=
curIndex
{
return
i
,
true
}
}
return
-
1
,
false
}
// names should have been sorted based on sequence number.
// isValidSeq checks whether seq increases continuously.
func
isValidSeq
(
names
[]
string
)
bool
{
var
lastSeq
uint64
for
_
,
name
:=
range
names
{
curSeq
,
_
,
err
:=
parseWalName
(
name
)
if
err
!=
nil
{
plog
.
Panicf
(
"parse correct name should never fail: %v"
,
err
)
}
if
lastSeq
!=
0
&&
lastSeq
!=
curSeq
-
1
{
return
false
}
lastSeq
=
curSeq
}
return
true
}
func
checkWalNames
(
names
[]
string
)
[]
string
{
wnames
:=
make
([]
string
,
0
)
for
_
,
name
:=
range
names
{
if
_
,
_
,
err
:=
parseWalName
(
name
);
err
!=
nil
{
plog
.
Warningf
(
"ignored file %v in wal"
,
name
)
continue
}
wnames
=
append
(
wnames
,
name
)
}
return
wnames
}
func
parseWalName
(
str
string
)
(
seq
,
index
uint64
,
err
error
)
{
if
!
strings
.
HasSuffix
(
str
,
".wal"
)
{
return
0
,
0
,
badWalName
}
_
,
err
=
fmt
.
Sscanf
(
str
,
"%016x-%016x.wal"
,
&
seq
,
&
index
)
return
seq
,
index
,
err
}
func
walName
(
seq
,
index
uint64
)
string
{
return
fmt
.
Sprintf
(
"%016x-%016x.wal"
,
seq
,
index
)
}
third_party/forked/etcd237/wal/wal.go
0 → 100644
View file @
b6939b28
This diff is collapsed.
Click to expand it.
third_party/forked/etcd237/wal/walpb/record.go
0 → 100644
View file @
b6939b28
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
walpb
import
"errors"
var
(
ErrCRCMismatch
=
errors
.
New
(
"walpb: crc mismatch"
)
)
func
(
rec
*
Record
)
Validate
(
crc
uint32
)
error
{
if
rec
.
Crc
==
crc
{
return
nil
}
rec
.
Reset
()
return
ErrCRCMismatch
}
third_party/forked/etcd237/wal/walpb/record.pb.go
0 → 100644
View file @
b6939b28
This diff is collapsed.
Click to expand it.
third_party/forked/etcd237/wal/walpb/record.proto
0 → 100644
View file @
b6939b28
syntax
=
"proto2"
;
package
walpb
;
import
"gogoproto/gogo.proto"
;
option
(
gogoproto.marshaler_all
)
=
true
;
option
(
gogoproto.sizer_all
)
=
true
;
option
(
gogoproto.unmarshaler_all
)
=
true
;
option
(
gogoproto.goproto_getters_all
)
=
false
;
message
Record
{
optional
int64
type
=
1
[(
gogoproto.nullable
)
=
false
];
optional
uint32
crc
=
2
[(
gogoproto.nullable
)
=
false
];
optional
bytes
data
=
3
;
}
message
Snapshot
{
optional
uint64
index
=
1
[(
gogoproto.nullable
)
=
false
];
optional
uint64
term
=
2
[(
gogoproto.nullable
)
=
false
];
}
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