-
Notifications
You must be signed in to change notification settings - Fork 72
/
device.go
71 lines (59 loc) · 2.19 KB
/
device.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
Copyright (c) Facebook, Inc. and its affiliates.
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 daemon
import (
"fmt"
"os"
"path/filepath"
"github.com/facebook/time/fbclock"
"github.com/facebook/time/phc"
log "github.com/sirupsen/logrus"
)
// ManagedPTPDevicePath is the path we will set up a copy of iface's PHC device,
// so that fbclock clients can access it without explicit configuration.
const ManagedPTPDevicePath = string(fbclock.PTPPath)
// SetupDeviceDir creates a PHC device path from the interface name
func SetupDeviceDir(iface string) error {
// explicitly convert to string to prevent GOPLS from panicking here
target := ManagedPTPDevicePath
dir := filepath.Dir(target)
wantMode := os.ModeCharDevice | os.ModeDevice | 0644
device, err := phc.IfaceToPHCDevice(iface)
if err != nil {
return fmt.Errorf("getting PHC device from iface %q: %w", iface, err)
}
devInfo, err := os.Stat(device)
if err != nil {
return fmt.Errorf("getting PTP device %q info: %w", device, err)
}
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("preparing dir %s: %w", dir, err)
}
// check if it's already there
if targetInfo, err := os.Stat(target); err == nil {
if os.SameFile(devInfo, targetInfo) && targetInfo.Mode() == wantMode {
log.Debugf("Device %s already exists, nothing to link", target)
return nil
}
// remove the wrong file
if err := os.RemoveAll(target); err != nil {
log.Debugf("Removing %s", target)
return fmt.Errorf("removing target file %q: %w", target, err)
}
}
log.Debugf("Linking %s to %s", device, target)
if err := os.Link(device, target); err != nil {
return fmt.Errorf("linking device %s to %s: %w", device, target, err)
}
return os.Chmod(target, wantMode)
}