Skip to content

Commit ef45e4f

Browse files
Merge pull request #3046 from linxiulei/fix_shim_socket
Shorten the unix socket path for shim
2 parents 63d7a9c + a631796 commit ef45e4f

4 files changed

Lines changed: 112 additions & 3 deletions

File tree

container_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ import (
3232
// Register the typeurl
3333
"github.com/containerd/containerd/cio"
3434
"github.com/containerd/containerd/containers"
35+
"github.com/containerd/containerd/namespaces"
3536
"github.com/containerd/containerd/oci"
37+
"github.com/containerd/containerd/platforms"
3638
_ "github.com/containerd/containerd/runtime"
3739
"github.com/containerd/typeurl"
3840
specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -1528,3 +1530,59 @@ func TestContainerHook(t *testing.T) {
15281530
}
15291531
defer task.Delete(ctx, WithProcessKill)
15301532
}
1533+
1534+
func TestShimSockLength(t *testing.T) {
1535+
t.Parallel()
1536+
1537+
// Max length of namespace should be 76
1538+
namespace := strings.Repeat("n", 76)
1539+
1540+
ctx, cancel := context.WithCancel(context.Background())
1541+
defer cancel()
1542+
1543+
ctx = namespaces.WithNamespace(ctx, namespace)
1544+
1545+
client, err := newClient(t, address)
1546+
if err != nil {
1547+
t.Fatal(err)
1548+
}
1549+
defer client.Close()
1550+
1551+
image, err := client.Pull(ctx, testImage,
1552+
WithPlatformMatcher(platforms.Default()),
1553+
WithPullUnpack,
1554+
)
1555+
if err != nil {
1556+
t.Fatal(err)
1557+
}
1558+
1559+
id := strings.Repeat("c", 64)
1560+
1561+
// We don't have limitation with length of container name,
1562+
// but 64 bytes of sha256 is the common case
1563+
container, err := client.NewContainer(ctx, id,
1564+
WithNewSnapshot(id, image),
1565+
WithNewSpec(oci.WithImageConfig(image), withExitStatus(0)),
1566+
)
1567+
if err != nil {
1568+
t.Fatal(err)
1569+
}
1570+
defer container.Delete(ctx, WithSnapshotCleanup)
1571+
1572+
task, err := container.NewTask(ctx, empty())
1573+
if err != nil {
1574+
t.Fatal(err)
1575+
}
1576+
defer task.Delete(ctx)
1577+
1578+
statusC, err := task.Wait(ctx)
1579+
if err != nil {
1580+
t.Fatal(err)
1581+
}
1582+
1583+
if err := task.Start(ctx); err != nil {
1584+
t.Fatal(err)
1585+
}
1586+
1587+
<-statusC
1588+
}

runtime/v1/linux/bundle.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package linux
2020

2121
import (
2222
"context"
23+
"crypto/sha256"
2324
"fmt"
2425
"io/ioutil"
2526
"os"
@@ -103,7 +104,7 @@ func ShimLocal(c *Config, exchange *exchange.Exchange) ShimOpt {
103104
// ShimConnect is a ShimOpt for connecting to an existing remote shim
104105
func ShimConnect(c *Config, onClose func()) ShimOpt {
105106
return func(b *bundle, ns string, ropts *runctypes.RuncOptions) (shim.Config, client.Opt) {
106-
return b.shimConfig(ns, c, ropts), client.WithConnect(b.shimAddress(ns), onClose)
107+
return b.shimConfig(ns, c, ropts), client.WithConnect(b.decideShimAddress(ns), onClose)
107108
}
108109
}
109110

@@ -127,10 +128,32 @@ func (b *bundle) Delete() error {
127128
return errors.Wrapf(err, "Failed to remove both bundle and workdir locations: %v", err2)
128129
}
129130

130-
func (b *bundle) shimAddress(namespace string) string {
131+
func (b *bundle) legacyShimAddress(namespace string) string {
131132
return filepath.Join(string(filepath.Separator), "containerd-shim", namespace, b.id, "shim.sock")
132133
}
133134

135+
func (b *bundle) shimAddress(namespace string) string {
136+
d := sha256.Sum256([]byte(filepath.Join(namespace, b.id)))
137+
return filepath.Join(string(filepath.Separator), "containerd-shim", fmt.Sprintf("%x.sock", d))
138+
}
139+
140+
func (b *bundle) loadAddress() (string, error) {
141+
addressPath := filepath.Join(b.path, "address")
142+
data, err := ioutil.ReadFile(addressPath)
143+
if err != nil {
144+
return "", err
145+
}
146+
return string(data), nil
147+
}
148+
149+
func (b *bundle) decideShimAddress(namespace string) string {
150+
address, err := b.loadAddress()
151+
if err != nil {
152+
return b.legacyShimAddress(namespace)
153+
}
154+
return address
155+
}
156+
134157
func (b *bundle) shimConfig(namespace string, c *Config, runcOptions *runctypes.RuncOptions) shim.Config {
135158
var (
136159
criuPath string

runtime/v1/shim/client/client.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ package client
2020

2121
import (
2222
"context"
23+
"fmt"
2324
"io"
2425
"net"
2526
"os"
2627
"os/exec"
28+
"path/filepath"
2729
"strings"
2830
"sync"
2931
"syscall"
@@ -107,6 +109,10 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
107109
"address": address,
108110
"debug": debug,
109111
}).Infof("shim %s started", binary)
112+
113+
if err := writeAddress(filepath.Join(config.Path, "address"), address); err != nil {
114+
return nil, nil, err
115+
}
110116
// set shim in cgroup if it is provided
111117
if cgroup != "" {
112118
if err := setCgroup(cgroup, cmd); err != nil {
@@ -166,6 +172,25 @@ func newCommand(binary, daemonAddress string, debug bool, config shim.Config, so
166172
return cmd, nil
167173
}
168174

175+
// writeAddress writes a address file atomically
176+
func writeAddress(path, address string) error {
177+
path, err := filepath.Abs(path)
178+
if err != nil {
179+
return err
180+
}
181+
tempPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path)))
182+
f, err := os.OpenFile(tempPath, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0666)
183+
if err != nil {
184+
return err
185+
}
186+
_, err = f.WriteString(address)
187+
f.Close()
188+
if err != nil {
189+
return err
190+
}
191+
return os.Rename(tempPath, path)
192+
}
193+
169194
func newSocket(address string) (*net.UnixListener, error) {
170195
if len(address) > 106 {
171196
return nil, errors.Errorf("%q: unix socket path too long (> 106)", address)

runtime/v2/shim/util_unix.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ package shim
2020

2121
import (
2222
"context"
23+
"crypto/sha256"
24+
"fmt"
2325
"net"
2426
"path/filepath"
2527
"strings"
@@ -50,7 +52,8 @@ func SocketAddress(ctx context.Context, id string) (string, error) {
5052
if err != nil {
5153
return "", err
5254
}
53-
return filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim.sock"), nil
55+
d := sha256.Sum256([]byte(filepath.Join(ns, id)))
56+
return filepath.Join(string(filepath.Separator), "containerd-shim", fmt.Sprintf("%x.sock", d)), nil
5457
}
5558

5659
// AnonDialer returns a dialer for an abstract socket

0 commit comments

Comments
 (0)