Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/orchestrator/pkg/sandbox/cgroup/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,7 @@ func (m *managerImpl) Destroy(ctx context.Context, cgroupName string) error {
return err
}

// Remove kills any remaining processes internally and returns nil once the
// cgroup is gone, so it is the authoritative teardown signal.
// Remove kills any remaining processes and deletes the cgroup.
return handle.Remove(ctx)
}

Expand Down
4 changes: 4 additions & 0 deletions packages/orchestrator/pkg/sandbox/nbd/path_direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ func disconnectNBDWithTimeout(ctx context.Context, deviceIndex uint32, timeout t
return nil
}

func DisconnectDevice(ctx context.Context, deviceIndex DeviceSlot) error {
return disconnectNBDWithTimeout(ctx, deviceIndex, disconnectTimeout)
}

func closeSocketPairs(socksClient []*os.File, socksServer []io.Closer) error {
var errs []error
for _, sock := range socksClient {
Expand Down
53 changes: 43 additions & 10 deletions packages/orchestrator/pkg/sandbox/nbd/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
const (
waitOnNBDError = 50 * time.Millisecond
devicePoolCloseReleaseTimeout = 10 * time.Minute
sysBlockDir = "/sys/block"
)

var (
Expand Down Expand Up @@ -126,6 +127,43 @@
return uint(maxDevices), nil
}

func ConnectedDevices() ([]DeviceSlot, error) {
maxDevices, err := getMaxDevices()
if err != nil {
return nil, err
}

devices := make([]DeviceSlot, 0)
for slot := DeviceSlot(0); slot < DeviceSlot(maxDevices); slot++ {
Comment thread
wj-e2b marked this conversation as resolved.
Dismissed
connected, err := isDeviceConnectedIn(sysBlockDir, slot)
if err != nil {
return nil, err
}
if connected {
devices = append(devices, slot)
}
}

return devices, nil
}

func IsDeviceConnected(slot DeviceSlot) (bool, error) {
return isDeviceConnectedIn(sysBlockDir, slot)
}

func isDeviceConnectedIn(blockDir string, slot DeviceSlot) (bool, error) {
pidFile := fmt.Sprintf("%s/nbd%d/pid", blockDir, slot)
_, err := os.Stat(pidFile)
if err == nil {
return true, nil
}
if !os.IsNotExist(err) {
return false, fmt.Errorf("failed to stat pid file: %w", err)
}

return false, nil
}

func (d *DevicePool) Populate(ctx context.Context) {
defer close(d.slots)

Expand Down Expand Up @@ -178,20 +216,15 @@
// https://superuser.com/questions/919895/how-to-get-a-list-of-connected-nbd-devices-on-ubuntu
// https://github.com/NetworkBlockDevice/nbd/blob/17043b068f4323078637314258158aebbfff0a6c/nbd-client.c#L254
func (d *DevicePool) isDeviceFree(slot DeviceSlot) (bool, error) {
// Continue only if the file doesn't exist.
pidFile := fmt.Sprintf("/sys/block/nbd%d/pid", slot)

_, err := os.Stat(pidFile)
if err == nil {
connected, err := isDeviceConnectedIn(sysBlockDir, slot)
if err != nil {
return false, err
}
if connected {
// File is present, therefore the device is in use.
return false, nil
}

if !os.IsNotExist(err) {
// Some other error occurred.
return false, fmt.Errorf("failed to stat pid file: %w", err)
}

sizeFile := fmt.Sprintf("/sys/block/nbd%d/size", slot)

data, err := os.ReadFile(sizeFile)
Expand Down
28 changes: 28 additions & 0 deletions packages/orchestrator/pkg/sandbox/nbd/reclaim_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//go:build linux

package nbd

import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

func TestIsDeviceConnectedIn(t *testing.T) {
t.Parallel()

dir := t.TempDir()
require.NoError(t, os.Mkdir(filepath.Join(dir, "nbd0"), 0o700))
require.NoError(t, os.Mkdir(filepath.Join(dir, "nbd1"), 0o700))
require.NoError(t, os.WriteFile(filepath.Join(dir, "nbd0", "pid"), []byte("123"), 0o600))

connected, err := isDeviceConnectedIn(dir, 0)
require.NoError(t, err)
require.True(t, connected)

connected, err = isDeviceConnectedIn(dir, 1)
require.NoError(t, err)
require.False(t, connected)
}
Loading