1 Star 0 Fork 1

mysnapcore / mysnapd

forked from tupelo-shen / mysnapd 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
bootstrap.go 4.10 KB
一键复制 编辑 原始数据 按行查看 历史
tupelo-shen 提交于 2022-11-08 22:37 . fix: cmd commit
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2017 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package main
// Use a pre-main helper to switch the mount namespace. This is required as
// golang creates threads at will and setns(..., CLONE_NEWNS) fails if any
// threads apart from the main thread exist.
/*
#include <stdlib.h>
#include "bootstrap.h"
// The bootstrap function is called by the loader before passing
// control to main. We are using `preinit_array` rather than
// `init_array` because the Go linker adds its own initialisation
// function to `init_array`, and having ours run second would defeat
// the purpose of the C bootstrap code.
//
// The `used` attribute ensures that the compiler doesn't optimise out
// the variable on the mistaken belief that it isn't used.
__attribute__((section(".preinit_array"), used)) static typeof(&bootstrap) init = &bootstrap;
// NOTE: do not add anything before the following `import "C"'
*/
import "C"
import (
"errors"
"fmt"
"syscall"
"unsafe"
)
var (
// ErrNoNamespace is returned when a snap namespace does not exist.
ErrNoNamespace = errors.New("cannot update mount namespace that was not created yet")
)
// IMPORTANT: all the code in this section may be run with elevated privileges
// when invoking snap-update-ns from the setuid snap-confine.
// BootstrapError returns error (if any) encountered in pre-main C code.
func BootstrapError() error {
if C.bootstrap_msg == nil {
return nil
}
errno := syscall.Errno(C.bootstrap_errno)
// Translate EINVAL from setns or ENOENT from open into a dedicated error.
if errno == syscall.EINVAL || errno == syscall.ENOENT {
return ErrNoNamespace
}
if errno != 0 {
return fmt.Errorf("%s: %s", C.GoString(C.bootstrap_msg), errno)
}
return fmt.Errorf("%s", C.GoString(C.bootstrap_msg))
}
// This function is here to make clearing the boostrap errors accessible
// from the tests.
func clearBootstrapError() {
C.bootstrap_msg = nil
C.bootstrap_errno = 0
}
// END IMPORTANT
func makeArgv(args []string) []*C.char {
// Create argv array with terminating NULL element
argv := make([]*C.char, len(args)+1)
for i, arg := range args {
argv[i] = C.CString(arg)
}
return argv
}
func freeArgv(argv []*C.char) {
for _, arg := range argv {
C.free(unsafe.Pointer(arg))
}
}
// validateInstanceName checks if snap instance name is valid.
// This also sets bootstrap_msg on failure.
//
// This function is here only to make the C.validate_instance_name
// code testable from go, as cgo is not directly importable from test packages.
func validateInstanceName(instanceName string) int {
cStr := C.CString(instanceName)
defer C.free(unsafe.Pointer(cStr))
return int(C.validate_instance_name(cStr))
}
// processArguments parses commnad line arguments.
// The argument cmdline is a string with embedded
// NUL bytes, separating particular arguments.
//
// This function is here only to make the C.validate_instance_name
// code testable from go, as cgo is not directly importable from test packages.
func processArguments(args []string) (snapName string, shouldSetNs bool, processUserFstab bool, uid uint) {
argv := makeArgv(args)
defer freeArgv(argv)
var snapNameOut *C.char
var shouldSetNsOut C.bool
var processUserFstabOut C.bool
var uidOut C.ulong
C.process_arguments(C.int(len(args)), &argv[0], &snapNameOut, &shouldSetNsOut, &processUserFstabOut, &uidOut)
if snapNameOut != nil {
snapName = C.GoString(snapNameOut)
}
shouldSetNs = bool(shouldSetNsOut)
processUserFstab = bool(processUserFstabOut)
uid = uint(uidOut)
return snapName, shouldSetNs, processUserFstab, uid
}
Go
1
https://gitee.com/mysnapcore/mysnapd.git
git@gitee.com:mysnapcore/mysnapd.git
mysnapcore
mysnapd
mysnapd
v0.1.0

搜索帮助