-
-
Notifications
You must be signed in to change notification settings - Fork 165
/
devices_sort.go
80 lines (65 loc) · 2.05 KB
/
devices_sort.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
72
73
74
75
76
77
78
79
80
package config
// DeviceNamed contains the name of a device and its config.
type DeviceNamed struct {
Name string
Config Device
}
// DevicesSortable is a sortable slice of device names and config.
type DevicesSortable []DeviceNamed
func (devices DevicesSortable) Len() int {
return len(devices)
}
func (devices DevicesSortable) Less(i, j int) bool {
a := devices[i]
b := devices[j]
// First sort by types.
if a.Config["type"] != b.Config["type"] {
// In VMs, network interface names are derived from PCI
// location. As a result of that, we must ensure that nic devices will
// always show up at the same spot regardless of what other devices may be
// added. Easiest way to do this is to always have them show up first.
if a.Config["type"] == "nic" {
return true
}
if b.Config["type"] == "nic" {
return false
}
// Start disks before other non-nic devices so that any unmounts triggered by deferred resizes
// specified in volatile "apply_quota" key can occur first and the rest of the devices can rely on
// the instance's root disk being mounted.
if a.Config["type"] == "disk" {
return true
}
if b.Config["type"] == "disk" {
return false
}
// Otherwise start devices of same type together.
return a.Config["type"] > b.Config["type"]
}
// Start non-nested NIC devices before nested NIC devices.
if a.Config["type"] == "nic" && b.Config["type"] == "nic" && (a.Config["nested"] != "" || b.Config["nested"] != "") {
if a.Config["nested"] == "" {
return true
} else if b.Config["nested"] == "" {
return false
}
}
// Start disk devices in path order.
if a.Config["type"] == "disk" && b.Config["type"] == "disk" {
if a.Config["path"] != b.Config["path"] {
// The root device always goes first.
if a.Config["path"] == "/" {
return true
}
if b.Config["path"] == "/" {
return false
}
return a.Config["path"] < b.Config["path"]
}
}
// Fallback to sorting by names.
return a.Name < b.Name
}
func (devices DevicesSortable) Swap(i, j int) {
devices[i], devices[j] = devices[j], devices[i]
}