1/*
2* Copyright (c) 2022 Huawei Device Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7*     http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16#include <errno.h>
17#include <fcntl.h>
18#include <sched.h>
19#include <string.h>
20#include <unistd.h>
21#include "beget_ext.h"
22
23static int g_defaultNs;
24
25int GetNamespaceFd(const char *nsPath)
26{
27    BEGET_CHECK(nsPath != NULL, return -1);
28    int ns = open(nsPath, O_RDONLY | O_CLOEXEC);
29    if (ns < 0) {
30        BEGET_LOGE("Open default namespace failed, err=%d", errno);
31        return -1;
32    }
33    return ns;
34}
35
36int UnshareNamespace(int nsType)
37{
38    if (nsType == CLONE_NEWNS) {
39        if (unshare(nsType) < 0) {
40            BEGET_LOGE("Unshare namespace failed, err=%d", errno);
41            return -1;
42        } else {
43            return 0;
44        }
45    } else {
46        BEGET_LOGE("Namespace type is not support");
47        return -1;
48    }
49}
50
51int SetNamespace(int nsFd, int nsType)
52{
53    if (nsFd < 0) {
54        BEGET_LOGE("Namespace fd is invalid");
55        return -1;
56    }
57    if (nsType != CLONE_NEWNS) {
58        BEGET_LOGE("Namespace type is not support");
59        return -1;
60    }
61    return setns(nsFd, nsType);
62}
63
64void InitDefaultNamespace(void)
65{
66    BEGET_CHECK(!(g_defaultNs > 0), (void)close(g_defaultNs));
67    g_defaultNs = GetNamespaceFd("/proc/self/ns/mnt");
68    return;
69}
70
71int EnterDefaultNamespace(void)
72{
73    BEGET_CHECK(!(g_defaultNs < 0), return -1);
74    return SetNamespace(g_defaultNs, CLONE_NEWNS);
75}
76
77void CloseDefaultNamespace(void)
78{
79    if (g_defaultNs > 0) {
80        (void)close(g_defaultNs);
81        g_defaultNs = -1;
82    }
83    return;
84}
85