Dragonfly2
63 строки · 1.7 Кб
1//go:build linux
2
3/*
4* Copyright 2020 The Dragonfly Authors
5*
6* Licensed under the Apache License, Version 2.0 (the "License");
7* you may not use this file except in compliance with the License.
8* You may obtain a copy of the License at
9*
10* http://www.apache.org/licenses/LICENSE-2.0
11*
12* Unless required by applicable law or agreed to in writing, software
13* distributed under the License is distributed on an "AS IS" BASIS,
14* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15* See the License for the specific language governing permissions and
16* limitations under the License.
17*/
18
19package daemon
20
21import (
22"fmt"
23"os"
24
25"golang.org/x/sys/unix"
26
27logger "d7y.io/dragonfly/v2/internal/dflog"
28)
29
30func switchNetNamespace(target string) (func() error, error) {
31fd, err := unix.Open(target, unix.O_RDONLY, 0)
32if err != nil {
33return nil, err
34}
35defer unix.Close(fd)
36
37orgNS := fmt.Sprintf("/proc/%d/ns/net", os.Getpid())
38// hold the original net namespace
39orgFD, err := unix.Open(orgNS, unix.O_RDONLY, 0)
40if err != nil {
41return nil, err
42}
43logger.Infof("switch net namespace, from %s to %s", orgNS, target)
44
45err = unix.Setns(fd, unix.CLONE_NEWNET)
46if err != nil {
47return nil, err
48}
49
50return func() error {
51if err := unix.Setns(orgFD, unix.CLONE_NEWNET); err != nil {
52logger.Errorf("recover net namespace, from %s to %s, error: %s", target, orgNS, err)
53return err
54}
55logger.Infof("recover net namespace, from %s to %s", target, orgNS)
56if err := unix.Close(orgFD); err != nil {
57logger.Errorf("recover net namespace, close fd error: %s", err)
58return err
59}
60logger.Infof("recover net namespace, close original fd")
61return nil
62}, nil
63}
64