github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/osutil/mount/mount_linux.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package mount 21 22 import ( 23 "math/bits" 24 "syscall" 25 ) 26 27 type flagInfo struct { 28 mask uint32 29 name string 30 } 31 32 func knownMask(knownFlags []flagInfo) uint32 { 33 var mask uint32 34 for _, fi := range knownFlags { 35 mask |= fi.mask 36 } 37 return mask 38 } 39 40 // UMOUNT_NOFOLLOW is not defined in go's syscall package 41 const UMOUNT_NOFOLLOW = 8 42 43 var mountFlags = []flagInfo{ 44 {name: "MS_REMOUNT", mask: syscall.MS_REMOUNT}, 45 {name: "MS_BIND", mask: syscall.MS_BIND}, 46 {name: "MS_REC", mask: syscall.MS_REC}, 47 {name: "MS_RDONLY", mask: syscall.MS_RDONLY}, 48 {name: "MS_SHARED", mask: syscall.MS_SHARED}, 49 {name: "MS_SLAVE", mask: syscall.MS_SLAVE}, 50 {name: "MS_PRIVATE", mask: syscall.MS_PRIVATE}, 51 {name: "MS_UNBINDABLE", mask: syscall.MS_UNBINDABLE}, 52 } 53 54 var mountFlagsMask = knownMask(mountFlags) 55 56 var unmountFlags = []flagInfo{ 57 {name: "UMOUNT_NOFOLLOW", mask: UMOUNT_NOFOLLOW}, 58 {name: "MNT_FORCE", mask: syscall.MNT_FORCE}, 59 {name: "MNT_DETACH", mask: syscall.MNT_DETACH}, 60 {name: "MNT_EXPIRE", mask: syscall.MNT_EXPIRE}, 61 } 62 63 var unmountFlagsMask = knownMask(unmountFlags) 64 65 func flagOptSearch(flags int, knownFlags []flagInfo, knownMask uint32) (opts []string, unknown int) { 66 var f uint32 = uint32(flags) 67 for _, fi := range knownFlags { 68 if f&knownMask == 0 { 69 break 70 } 71 if f&fi.mask != 0 { 72 if opts == nil { 73 opts = make([]string, 0, bits.OnesCount32(f)) 74 } 75 f ^= fi.mask 76 opts = append(opts, fi.name) 77 } 78 } 79 return opts, int(f) 80 } 81 82 // MountFlagsToOpts returns the symbolic representation of mount flags. 83 func MountFlagsToOpts(flags int) (opts []string, unknown int) { 84 return flagOptSearch(flags, mountFlags, mountFlagsMask) 85 } 86 87 // UnmountFlagsToOpts returns the symbolic representation of unmount flags. 88 func UnmountFlagsToOpts(flags int) (opts []string, unknown int) { 89 return flagOptSearch(flags, unmountFlags, unmountFlagsMask) 90 }