feat(init): mount partitions dynamically (#169)

This commit is contained in:
Andrew Rynhard 2018-10-17 14:44:41 -07:00 committed by GitHub
parent 04bb2dab8c
commit 453bc48ae7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 59 deletions

View File

@ -108,7 +108,7 @@ DEFAULT Dianemo
LABEL Dianemo
KERNEL /boot/vmlinuz
INITRD /boot/initramfs.xz
APPEND ${KERNEL_SELF_PROTECTION_PROJECT_KERNEL_PARAMS} ip=dhcp consoleblank=0 console=tty0 console=ttyS0,9600 dianemo.autonomy.io/root=${DIANEMO_ROOT} dianemo.autonomy.io/userdata=${DIANEMO_USERDATA} dianemo.autonomy.io/platform=${DIANEMO_PLATFORM}
APPEND ${KERNEL_SELF_PROTECTION_PROJECT_KERNEL_PARAMS} ip=dhcp consoleblank=0 console=tty0 console=ttyS0,9600 dianemo.autonomy.io/userdata=${DIANEMO_USERDATA} dianemo.autonomy.io/platform=${DIANEMO_PLATFORM}
EOF
}
@ -120,7 +120,6 @@ function cleanup {
# Defaults
DIANEMO_ROOT="sda"
DIANEMO_USERDATA=""
DIANEMO_PLATFORM="bare-metal"
RAW_IMAGE="/out/image.raw"
@ -136,7 +135,7 @@ KERNEL_SELF_PROTECTION_PROJECT_KERNEL_PARAMS="page_poison=1 slab_nomerge pti=on"
case "$1" in
image)
shift
while getopts "b:flt:p:u:" opt; do
while getopts "b:flp:u:" opt; do
case ${opt} in
b )
DEVICE=${OPTARG}
@ -157,10 +156,6 @@ case "$1" in
DIANEMO_PLATFORM=${OPTARG}
echo "Using kernel parameter dianemo.autonomy.io/platform=${DIANEMO_PLATFORM}"
;;
t )
DIANEMO_ROOT=${OPTARG}
echo "Using kernel parameter dianemo.autonomy.io/root=${DIANEMO_ROOT}"
;;
u )
DIANEMO_USERDATA=${OPTARG}
echo "Using kernel parameter dianemo.autonomy.io/userdata=${DIANEMO_USERDATA}"

View File

@ -64,7 +64,7 @@
"sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\"",
"sudo apt-get -y update",
"sudo apt-get -y install docker-ce",
"sudo docker run --privileged --volume /dev:/dev autonomy/dianemo:{{ user `version` }} image -b /dev/xvdf -t /dev/xvda -f -p aws -u none"
"sudo docker run --privileged --volume /dev:/dev autonomy/dianemo:{{ user `version` }} image -b /dev/xvdf -f -p aws -u none"
]
}
]

View File

@ -1,10 +1,6 @@
package constants
const (
// KernelParamRoot is the kernel parameter name for specifying the root
// disk.
KernelParamRoot = "dianemo.autonomy.io/root"
// KernelParamUserData is the kernel parameter name for specifying the URL
// to the user data.
KernelParamUserData = "dianemo.autonomy.io/userdata"

View File

@ -16,6 +16,38 @@ import (
"unsafe"
)
// GetDevWithAttribute returns the dev name of a block device matching the ATTRIBUTE=VALUE
// pair. Supported attributes are:
// TYPE: filesystem type
// UUID: filesystem uuid
// LABEL: filesystem label
func GetDevWithAttribute(attribute, value string) (string, error) {
var cache C.blkid_cache
ret := C.blkid_get_cache(&cache, nil)
if ret != 0 {
return "", fmt.Errorf("failed to get blkid cache: %d", ret)
}
C.blkid_probe_all(cache)
cs_attribute := C.CString(attribute)
cs_value := C.CString(value)
defer C.free(unsafe.Pointer(cs_attribute))
defer C.free(unsafe.Pointer(cs_value))
devname := C.blkid_get_devname(cache, cs_attribute, cs_value)
defer C.free(unsafe.Pointer(devname))
// If you have called blkid_get_cache(), you should call blkid_put_cache()
// when you are done using the blkid library functions. This will save the
// cache to the blkid.tab file, if you have write access to the file. It
// will also free all associated devices and tags:
C.blkid_put_cache(cache)
return C.GoString(devname), nil
}
// NewProbeFromFilename executes lblkid blkid_new_probe_from_filename.
func NewProbeFromFilename(s string) (C.blkid_probe, error) {
cs := C.CString(s)

View File

@ -9,7 +9,6 @@ import (
"sync"
"github.com/autonomy/dianemo/src/initramfs/cmd/init/pkg/constants"
"github.com/autonomy/dianemo/src/initramfs/cmd/init/pkg/kernel"
"github.com/autonomy/dianemo/src/initramfs/cmd/init/pkg/mount/blkid"
"golang.org/x/sys/unix"
)
@ -206,54 +205,56 @@ func mountBlockDevices(s string) (err error) {
func probe() (b []*BlockDevice, err error) {
b = []*BlockDevice{}
arguments, err := kernel.ParseProcCmdline()
if err != nil {
return
if err := appendBlockDeviceWithLabel(&b, constants.RootPartitionLabel); err != nil {
return nil, err
}
if root, ok := arguments[constants.KernelParamRoot]; ok {
if _, err := os.Stat(root); os.IsNotExist(err) {
return nil, fmt.Errorf("device does not exist: %s", root)
}
pr, err := blkid.NewProbeFromFilename(root)
defer blkid.FreeProbe(pr)
if err != nil {
return nil, fmt.Errorf("failed to probe %s: %s", root, err)
}
ls := blkid.ProbeGetPartitions(pr)
nparts := blkid.ProbeGetPartitionsPartlistNumOfPartitions(ls)
for i := 0; i < nparts; i++ {
dev := fmt.Sprintf("%s%d", root, i+1)
pr, err = blkid.NewProbeFromFilename(dev)
defer blkid.FreeProbe(pr)
if err != nil {
return nil, fmt.Errorf("failed to probe %s: %s", dev, err)
}
blkid.DoProbe(pr)
UUID, err := blkid.ProbeLookupValue(pr, "UUID", nil)
if err != nil {
return nil, err
}
TYPE, err := blkid.ProbeLookupValue(pr, "TYPE", nil)
if err != nil {
return nil, err
}
LABEL, err := blkid.ProbeLookupValue(pr, "LABEL", nil)
if err != nil {
return nil, err
}
b = append(b, &BlockDevice{
dev: dev,
UUID: UUID,
TYPE: TYPE,
LABEL: LABEL,
})
}
if err := appendBlockDeviceWithLabel(&b, constants.DataPartitionLabel); err != nil {
return nil, err
}
return b, nil
}
func appendBlockDeviceWithLabel(b *[]*BlockDevice, value string) error {
devname, err := blkid.GetDevWithAttribute("LABEL", value)
if err != nil {
return err
}
blockDevice, err := probeDevice(devname)
if err != nil {
return err
}
*b = append(*b, blockDevice)
return nil
}
func probeDevice(devname string) (*BlockDevice, error) {
pr, err := blkid.NewProbeFromFilename(devname)
defer blkid.FreeProbe(pr)
if err != nil {
return nil, fmt.Errorf("failed to probe %s: %s", devname, err)
}
blkid.DoProbe(pr)
UUID, err := blkid.ProbeLookupValue(pr, "UUID", nil)
if err != nil {
return nil, err
}
TYPE, err := blkid.ProbeLookupValue(pr, "TYPE", nil)
if err != nil {
return nil, err
}
LABEL, err := blkid.ProbeLookupValue(pr, "LABEL", nil)
if err != nil {
return nil, err
}
return &BlockDevice{
dev: devname,
UUID: UUID,
TYPE: TYPE,
LABEL: LABEL,
}, nil
}