From 82a595fc5c5ce8afd55ecb9da445d79a73cb9642 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 10 Oct 2018 21:08:21 -0700 Subject: [PATCH] Ignore rootfs, use blkid to find partition type if sfdisk doesn't report. Should fix CentOS 7, but untested. Fixes #6 --- fs.go | 4 ++++ lvm.go | 14 ++++---------- part.go | 17 +++++++++++++++++ util.go | 29 +++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 util.go diff --git a/fs.go b/fs.go index bbc0118..73e41ce 100644 --- a/fs.go +++ b/fs.go @@ -113,6 +113,10 @@ func statFS(mnt string) (fs fsStat, err error) { if len(f) < 3 { continue } + if f[0] == "rootfs" { + // See https://github.com/google/embiggen-disk/issues/6 + continue + } if f[1] == mnt { fs.mnt = mnt fs.dev = f[0] diff --git a/lvm.go b/lvm.go index dcad2f4..231bcad 100644 --- a/lvm.go +++ b/lvm.go @@ -19,6 +19,7 @@ package main import ( "bufio" "bytes" + "errors" "fmt" "os/exec" "strconv" @@ -41,10 +42,7 @@ func (r lvResizer) state() (s lvState, err error) { // /dev/debvg/root:debvg:3:1:-1:1:8434778112:1029636:-1:0:-1:254:0 outb, err := exec.Command("lvdisplay", "-c", s.dev).Output() if err != nil { - if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { - err = fmt.Errorf("%v; stderr: %s", err, ee.Stderr) - } - return s, fmt.Errorf("running lvdisplay -c %s: %v", s.dev, err) + return s, fmt.Errorf("running lvdisplay -c %s: %v", s.dev, execErrDetail(err)) } f := strings.Split(strings.TrimSpace(string(outb)), ":") if len(f) < 13 { @@ -66,10 +64,7 @@ func (r lvResizer) DepResizer() (Resizer, error) { out, err := exec.Command("pvdisplay", "-c").Output() if err != nil { - if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { - err = fmt.Errorf("%v; stderr: %s", err, ee.Stderr) - } - return nil, fmt.Errorf("running pvdisplay -c: %v", err) + return nil, fmt.Errorf("running pvdisplay -c: %v", execErrDetail(err)) } bs := bufio.NewScanner(bytes.NewReader(out)) for bs.Scan() { @@ -124,8 +119,7 @@ func (r pvResizer) State() (string, error) { dev := string(r) out, err := exec.Command("pvdisplay", "-c", dev).Output() if err != nil { - // TODO: factor out ExitError.Stderr handling above & use here. - return "", err + return "", errors.New(execErrDetail(err)) } f := strings.Split(strings.TrimSpace(string(out)), ":") if len(f) < 3 { diff --git a/part.go b/part.go index 03111da..27aaf10 100644 --- a/part.go +++ b/part.go @@ -77,6 +77,23 @@ func (p partitionResizer) Resize() error { case "dos": case "gpt": isGPT = true + case "": + // Old version of sfdisk? See https://github.com/google/embiggen-disk/issues/6 + // Use blkid to figure out what it is. + // But only trust the value "dos", because if it's gpt and sfdisk + // is old and doesn't support gpt, we don't want to use that old sfdisk + // to manipulate the gpt tables. + out, err := exec.Command("blkid", "-o", "export", diskDev).Output() + if err != nil { + return fmt.Errorf("error running blkid: %v", execErrDetail(err)) + } + m := regexp.MustCompile(`(?m)^PTTYPE=(.+)\n`).FindSubmatch(out) + if m == nil { + return fmt.Errorf("`blkid -o export %s` lacked PTTYPE line, got: %s", diskDev, out) + } + if got := string(m[1]); got != "dos" { + return fmt.Errorf("Old sfdisk and `blkid -o export %s` reports unexpected PTTYPE=%s", got) + } default: // It might work, but fail as a precaution. Untested. return fmt.Errorf("unsupported partition table type %q on %s", t, diskDev) diff --git a/util.go b/util.go new file mode 100644 index 0000000..919d50f --- /dev/null +++ b/util.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "fmt" + "os/exec" +) + +func execErrDetail(err error) string { + if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { + return fmt.Sprintf("%v; stderr: %s", err, ee.Stderr) + } + return err.Error() +}