-
Notifications
You must be signed in to change notification settings - Fork 689
snap-bootstrap: add scan-disk subcommand #12006
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
96650dc
5ee235d
6ddbf5d
0864e59
7b44331
9c20173
a87aba4
247246b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| // -*- Mode: Go; indent-tabs-mode: t -*- | ||
|
|
||
| /* | ||
| * Copyright (C) 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 blkid | ||
|
|
||
| //#cgo CFLAGS: -D_FILE_OFFSET_BITS=64 | ||
| //#cgo pkg-config: blkid | ||
| //#cgo LDFLAGS: | ||
| // | ||
| //#include <stdlib.h> | ||
| //#include <blkid.h> | ||
| import "C" | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "unsafe" | ||
| ) | ||
|
|
||
| const ( | ||
| BLKID_PARTS_ENTRY_DETAILS int = C.BLKID_PARTS_ENTRY_DETAILS | ||
| ) | ||
|
|
||
| // AbstractBlkidProbe is wrapper for blkid_probe | ||
| // See "Low-level" section of libblkid documentation | ||
| type AbstractBlkidProbe interface { | ||
| // LookupValue is a wrapper for blkid_probe_lookup_value | ||
| LookupValue(entryName string) (string, error) | ||
| // Close is a wrapper for blkid_free_probe | ||
| Close() | ||
| // EnablePartitions is a wrapper for blkid_probe_enable_partitions | ||
| EnablePartitions(value bool) | ||
| // EnableSuperblocks is a wrapper for blkid_probe_enable_superblocks | ||
| EnableSuperblocks(value bool) | ||
| // SetPartitionsFlags is a wrapper for blkid_probe_set_partitions_flags | ||
| SetPartitionsFlags(flags int) | ||
| // DoSafeprobe is a wrapper for blkid_do_safeprobe | ||
| DoSafeprobe() error | ||
| // GetPartitions is a wrapper for blkid_probe_get_partitions | ||
| GetPartitions() (AbstractBlkidPartlist, error) | ||
| } | ||
|
|
||
| // AbstractBlkidPartlist is a wrapper for blkid_partlist | ||
| type AbstractBlkidPartlist interface { | ||
| // GetPartitions is a wrapper for blkid_partlist_get_partition | ||
| // and blkid_partlist_numof_partitions. | ||
| GetPartitions() []AbstractBlkidPartition | ||
| } | ||
|
|
||
| // AbstractBlkidPartition is a wrapper for blkid_partition | ||
| type AbstractBlkidPartition interface { | ||
| // GetName is a wrapper for blkid_partition_get_name | ||
| GetName() string | ||
| // GetUUID is a wrapper for blkid_partition_get_uuid | ||
| GetUUID() string | ||
| } | ||
|
|
||
| type blkidProbe struct { | ||
| probeHandle C.blkid_probe | ||
| } | ||
|
|
||
| func newProbeFromFilenameImpl(node string) (AbstractBlkidProbe, error) { | ||
| cnode := C.CString(node) | ||
| defer C.free(unsafe.Pointer(cnode)) | ||
| probe, err := C.blkid_new_probe_from_filename(cnode) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From my understanding, Do we know for sure
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probe is always nil on error yes.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. Although that is a bit different, I think. I wanted to make sure that
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have changed it to use err.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we use |
||
| if probe == nil { | ||
| if err == nil { | ||
| return nil, fmt.Errorf("blkid_new_probe_from_filename failed but no error was returned") | ||
| } | ||
| return nil, err | ||
| } | ||
| return &blkidProbe{probe}, nil | ||
| } | ||
|
|
||
| var NewProbeFromFilename = newProbeFromFilenameImpl | ||
|
|
||
| func (p *blkidProbe) checkProbe() { | ||
| if p.probeHandle == nil { | ||
| panic("used blkid probe after Close") | ||
| } | ||
| } | ||
|
|
||
| func (p *blkidProbe) LookupValue(entryName string) (string, error) { | ||
| p.checkProbe() | ||
| var value *C.char | ||
| var value_len C.size_t | ||
| cname := C.CString(entryName) | ||
| defer C.free(unsafe.Pointer(cname)) | ||
| res := C.blkid_probe_lookup_value(p.probeHandle, cname, &value, &value_len) | ||
| if res < 0 { | ||
| return "", fmt.Errorf("probe value was not found: %s", entryName) | ||
| } | ||
| if value_len > 0 { | ||
| return C.GoStringN(value, C.int(value_len-1)), nil | ||
| } else { | ||
| return "", fmt.Errorf("probe value has unexpected size") | ||
| } | ||
| } | ||
|
|
||
| func (p *blkidProbe) Close() { | ||
| p.checkProbe() | ||
| C.blkid_free_probe(p.probeHandle) | ||
|
pedronis marked this conversation as resolved.
Outdated
|
||
| p.probeHandle = C.blkid_probe(nil) | ||
| } | ||
|
|
||
| func (p *blkidProbe) EnablePartitions(value bool) { | ||
|
pedronis marked this conversation as resolved.
Outdated
|
||
| p.checkProbe() | ||
| v := 0 | ||
| if value { | ||
| v = 1 | ||
| } | ||
| C.blkid_probe_enable_partitions(p.probeHandle, C.int(v)) | ||
| } | ||
|
|
||
| func (p *blkidProbe) EnableSuperblocks(value bool) { | ||
| p.checkProbe() | ||
| v := 0 | ||
| if value { | ||
| v = 1 | ||
| } | ||
| C.blkid_probe_enable_superblocks(p.probeHandle, C.int(v)) | ||
| } | ||
|
|
||
| func (p *blkidProbe) SetPartitionsFlags(flags int) { | ||
| p.checkProbe() | ||
| C.blkid_probe_set_partitions_flags(p.probeHandle, C.int(flags)) | ||
| } | ||
|
|
||
| func (p *blkidProbe) DoSafeprobe() error { | ||
| p.checkProbe() | ||
| res, err := C.blkid_do_safeprobe(p.probeHandle) | ||
| if res < 0 { | ||
| return err | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| type blkidPartlist struct { | ||
| partlistHandle C.blkid_partlist | ||
| } | ||
|
|
||
| func (p *blkidProbe) GetPartitions() (AbstractBlkidPartlist, error) { | ||
| p.checkProbe() | ||
| partitions, err := C.blkid_probe_get_partitions(p.probeHandle) | ||
| if partitions == nil { | ||
| return nil, err | ||
| } | ||
| return &blkidPartlist{partitions}, nil | ||
| } | ||
|
|
||
| type blkidPartition struct { | ||
| partitionHandle C.blkid_partition | ||
|
pedronis marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| func (p *blkidPartlist) GetPartitions() []AbstractBlkidPartition { | ||
| npartitions := C.blkid_partlist_numof_partitions(p.partlistHandle) | ||
| ret := make([]AbstractBlkidPartition, npartitions) | ||
| for i := 0; i < int(npartitions); i++ { | ||
| partition := C.blkid_partlist_get_partition(p.partlistHandle, C.int(i)) | ||
| ret[i] = &blkidPartition{partition} | ||
| } | ||
| return ret | ||
| } | ||
|
|
||
| func (p *blkidPartition) GetName() string { | ||
| return C.GoString(C.blkid_partition_get_name(p.partitionHandle)) | ||
| } | ||
|
|
||
| func (p *blkidPartition) GetUUID() string { | ||
| return C.GoString(C.blkid_partition_get_uuid(p.partitionHandle)) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| // -*- Mode: Go; indent-tabs-mode: t -*- | ||
|
|
||
| /* | ||
| * Copyright (C) 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 blkid_test | ||
|
|
||
| import ( | ||
| "os/exec" | ||
| "path/filepath" | ||
| "testing" | ||
|
|
||
| . "gopkg.in/check.v1" | ||
|
|
||
| "github.com/snapcore/snapd/cmd/snap-bootstrap/blkid" | ||
|
|
||
| "github.com/snapcore/snapd/testutil" | ||
| ) | ||
|
|
||
| func Test(t *testing.T) { TestingT(t) } | ||
|
|
||
| type blkidSuite struct { | ||
| testutil.BaseTest | ||
|
|
||
| image string | ||
| } | ||
|
|
||
| var _ = Suite(&blkidSuite{}) | ||
|
|
||
| func (s *blkidSuite) SetUpTest(c *C) { | ||
| systemdRepart, err := exec.LookPath("systemd-repart") | ||
| if err != nil { | ||
| c.Skip("systemd-repart is not available") | ||
| } | ||
|
|
||
| s.BaseTest.SetUpTest(c) | ||
|
|
||
| tmp := c.MkDir() | ||
| image := filepath.Join(tmp, "image") | ||
|
|
||
| cmd := exec.Command(systemdRepart, "--offline=yes", "--size=64M", "--empty=create", "--definitions=test-data/repart.d", image) | ||
| err = cmd.Run() | ||
| if err != nil { | ||
| c.Skip("systemd-repart is not working") | ||
| } | ||
|
|
||
| s.image = image | ||
| } | ||
|
|
||
| func (s *blkidSuite) TestScanPartitionTable(c *C) { | ||
| probe, err := blkid.NewProbeFromFilename(s.image) | ||
| c.Assert(err, IsNil) | ||
| defer probe.Close() | ||
|
|
||
| probe.EnablePartitions(true) | ||
|
|
||
| err = probe.DoSafeprobe() | ||
| c.Assert(err, IsNil) | ||
|
|
||
| pttype, err := probe.LookupValue("PTTYPE") | ||
| c.Assert(err, IsNil) | ||
| c.Check(pttype, Equals, "gpt") | ||
|
|
||
| partlist, err := probe.GetPartitions() | ||
| c.Assert(err, IsNil) | ||
|
|
||
| partitions := 0 | ||
| for _, p := range partlist.GetPartitions() { | ||
| partitions++ | ||
| label := p.GetName() | ||
| c.Check(label, Equals, "thelabel") | ||
| uuid := p.GetUUID() | ||
| c.Check(uuid, Equals, "93fd7d8f-a662-4451-a03f-c065f2c2e1ab") | ||
| } | ||
| c.Check(partitions, Equals, 1) | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.