From 842e33521ad8374010b8ed250bbbb561cc405fc8 Mon Sep 17 00:00:00 2001 From: Zexi Date: Mon, 19 Aug 2019 21:27:17 +0800 Subject: [PATCH] baremetal: fix ext4 rootfs inode inconsistent --- pkg/baremetal/manager.go | 4 +++- pkg/baremetal/tasks/basedeploy.go | 8 ++++++++ pkg/baremetal/tasks/create.go | 13 +++++++++++++ pkg/baremetal/tasks/rebuild.go | 4 ++++ pkg/baremetal/utils/disktool/disktool.go | 11 +++++++++-- pkg/compute/models/snapshotpolicy.go | 2 +- pkg/hostman/guestfs/fsdriver/linux.go | 6 +++--- pkg/hostman/guestfs/sshpart/sshpart.go | 20 +++++++++++--------- pkg/util/ssh/ssh.go | 2 +- pkg/util/stringutils2/stringutils_test.go | 6 ++++++ 10 files changed, 59 insertions(+), 17 deletions(-) diff --git a/pkg/baremetal/manager.go b/pkg/baremetal/manager.go index bf31ad9fee..6d3c5ad949 100644 --- a/pkg/baremetal/manager.go +++ b/pkg/baremetal/manager.go @@ -1745,7 +1745,9 @@ func (s *SBaremetalServer) deployFs(term *ssh.Client, deployInfo *deployapi.Depl if err != nil { return nil, fmt.Errorf("Find rootfs error: %s", err) } - defer rootDev.Umount() + defer func() { + rootDev.Umount() + }() if strings.ToLower(rootfs.GetOs()) == "windows" { return nil, fmt.Errorf("Unsupported OS: %s", rootfs.GetOs()) } diff --git a/pkg/baremetal/tasks/basedeploy.go b/pkg/baremetal/tasks/basedeploy.go index c80c1fa6a8..efa608cc63 100644 --- a/pkg/baremetal/tasks/basedeploy.go +++ b/pkg/baremetal/tasks/basedeploy.go @@ -29,6 +29,7 @@ import ( type IServerBaseDeployTask interface { IPXEBootTask DoDeploys(term *ssh.Client) (jsonutils.JSONObject, error) + PostDeploys(term *ssh.Client) error } type SBaremetalServerBaseDeployTask struct { @@ -62,6 +63,10 @@ func (self *SBaremetalServerBaseDeployTask) GetFinishAction() string { return "" } +func (self *SBaremetalServerBaseDeployTask) PostDeploys(_ *ssh.Client) error { + return nil +} + func (self *SBaremetalServerBaseDeployTask) OnPXEBoot(ctx context.Context, term *ssh.Client, args interface{}) error { log.Infof("%s called on stage pxeboot, args: %v", self.GetName(), args) result, err := self.serverDeployTask.DoDeploys(term) @@ -75,6 +80,9 @@ func (self *SBaremetalServerBaseDeployTask) OnPXEBoot(ctx context.Context, term if err != nil { return errors.Wrap(err, "Sync disk") } + if err := self.serverDeployTask.PostDeploys(term); err != nil { + return errors.Wrap(err, "post deploy") + } onFinishAction := self.GetFinishAction() if utils.IsInStringArray(onFinishAction, []string{"restart", "shutdown"}) { err = self.EnsurePowerShutdown(false) diff --git a/pkg/baremetal/tasks/create.go b/pkg/baremetal/tasks/create.go index c4dce505f0..363fe48d32 100644 --- a/pkg/baremetal/tasks/create.go +++ b/pkg/baremetal/tasks/create.go @@ -73,6 +73,19 @@ func (self *SBaremetalServerCreateTask) DoDeploys(term *ssh.Client) (jsonutils.J return data, nil } +func doPoweroff(term *ssh.Client) error { + if _, err := term.Run("/sbin/poweroff"); err != nil { + log.Errorf("poweroff error: %s", err) + return nil + } + time.Sleep(2 * time.Second) + return nil +} + +func (self *SBaremetalServerCreateTask) PostDeploys(term *ssh.Client) error { + return doPoweroff(term) +} + func (self *SBaremetalServerCreateTask) onError(term *ssh.Client, err error) error { log.Errorf("Create server error: %+v", err) if err1 := self.Baremetal.GetServer().DoEraseDisk(term); err1 != nil { diff --git a/pkg/baremetal/tasks/rebuild.go b/pkg/baremetal/tasks/rebuild.go index f91f5b398b..04dbb38c99 100644 --- a/pkg/baremetal/tasks/rebuild.go +++ b/pkg/baremetal/tasks/rebuild.go @@ -59,3 +59,7 @@ func (self *SBaremetalServerRebuildTask) DoDeploys(term *ssh.Client) (jsonutils. data.Update(deployInfo) return data, nil } + +func (self *SBaremetalServerRebuildTask) PostDeploys(term *ssh.Client) error { + return doPoweroff(term) +} diff --git a/pkg/baremetal/utils/disktool/disktool.go b/pkg/baremetal/utils/disktool/disktool.go index 67df72e910..e68bd26cb2 100644 --- a/pkg/baremetal/utils/disktool/disktool.go +++ b/pkg/baremetal/utils/disktool/disktool.go @@ -108,8 +108,7 @@ func (p *Partition) Format(fs string, uuid string) error { cmdUUID = []string{"/usr/sbin/tune2fs", "-U", uuid} case "ext4": // for baremetal, force 64bit support large disks - //cmd = []string{"/usr/sbin/mkfs.ext4", "-O", "64bit", "-E", "lazy_itable_init=1", "-T", "largefile"} - cmd = []string{"/usr/sbin/mkfs.ext4", "-O", "64bit", "-E", "lazy_itable_init=1"} + cmd = []string{"/usr/sbin/mkfs.ext4", "-O", "64bit", "-E", "lazy_itable_init=1", "-T", "largefile"} cmdUUID = []string{"/usr/sbin/tune2fs", "-U", uuid} case "ext4dev": cmd = []string{"/usr/sbin/mkfs.ext4dev", "-E", "lazy_itable_init=1"} @@ -206,6 +205,10 @@ func (p *Partition) GetSizeMB() (int64, error) { return p.count * 512 / 1024 / 1024, nil } +func (p *Partition) GetDisk() *DiskPartitions { + return p.disk +} + type DiskPartitions struct { driver string adapter int @@ -243,6 +246,10 @@ func (p *DiskPartitions) IsRaidDriver() bool { }) } +func (p *DiskPartitions) GetDev() string { + return p.dev +} + func (p *DiskPartitions) SetInfo(info *types.SDiskInfo) *DiskPartitions { p.dev = fmt.Sprintf("/dev/%s", info.Dev) p.devName = info.Dev diff --git a/pkg/compute/models/snapshotpolicy.go b/pkg/compute/models/snapshotpolicy.go index 326285a136..94250adbea 100644 --- a/pkg/compute/models/snapshotpolicy.go +++ b/pkg/compute/models/snapshotpolicy.go @@ -416,4 +416,4 @@ func (self *SSnapshotPolicy) preCheck( return nil, httperrors.NewNotFoundError("Disks %v not found", notFoundDisks) } return diskIds, nil -} \ No newline at end of file +} diff --git a/pkg/hostman/guestfs/fsdriver/linux.go b/pkg/hostman/guestfs/fsdriver/linux.go index 6e5bf39505..a2811211e4 100644 --- a/pkg/hostman/guestfs/fsdriver/linux.go +++ b/pkg/hostman/guestfs/fsdriver/linux.go @@ -277,16 +277,16 @@ func (l *sLinuxRootFs) DeployStandbyNetworkingScripts(rootFs IDiskPartition, nic var udevPath = "/etc/udev/rules.d/" var nicRules string for _, nic := range nicsStandby { - if len(nic.NicType) == 0 || nic.NicType != "impi" { + if len(nic.NicType) == 0 || nic.NicType != types.NIC_TYPE_IPMI { nicRules += `KERNEL=="*", SUBSYSTEM=="net", ACTION=="add", ` nicRules += `DRIVERS=="?*", ` mac := nic.Mac nicRules += fmt.Sprintf(`ATTR{address}=="%s", ATTR{type}=="1", `, strings.ToLower(mac)) idx := nic.Index - nicRules += fmt.Sprintf("NAME=\"eth%d\"\n", idx) + nicRules += fmt.Sprintf(`NAME="eth%d"\n`, idx) } } - if err := rootFs.FilePutContents(path.Join(udevPath, "70-persistent-net.rules"), nicRules, false, false); err != nil { + if err := rootFs.FilePutContents(path.Join(udevPath, "70-persistent-net.rules"), nicRules, true, false); err != nil { return err } return nil diff --git a/pkg/hostman/guestfs/sshpart/sshpart.go b/pkg/hostman/guestfs/sshpart/sshpart.go index 97df985bbd..331e2521f7 100644 --- a/pkg/hostman/guestfs/sshpart/sshpart.go +++ b/pkg/hostman/guestfs/sshpart/sshpart.go @@ -40,13 +40,15 @@ type SSHPartition struct { term *ssh.Client partDev string mountPath string + part *disktool.Partition } -func NewSSHPartition(term *ssh.Client, dev string) *SSHPartition { +func NewSSHPartition(term *ssh.Client, part *disktool.Partition) *SSHPartition { p := new(SSHPartition) p.term = term - p.partDev = dev + p.partDev = part.GetDev() p.mountPath = fmt.Sprintf("/tmp/%s", strings.Replace(p.partDev, "/", "_", -1)) + p.part = part return p } @@ -169,12 +171,17 @@ func (p *SSHPartition) Umount() bool { "/sbin/sysctl -w vm.drop_caches=3", fmt.Sprintf("/bin/umount %s", p.mountPath), fmt.Sprintf("/sbin/hdparm -f %s", p.partDev), + //fmt.Sprintf("/usr/bin/sg_sync %s", p.part.GetDisk().GetDev()), } _, err = p.term.Run(cmds...) if err != nil { log.Errorf("umount %s error: %v", p.mountPath, err) time.Sleep(1 * time.Second) } else { + if err := p.osRmDir(p.mountPath); err != nil { + log.Errorf("remove mount path %s: %v", p.mountPath, err) + return false + } return true } } @@ -300,11 +307,6 @@ func (p *SSHPartition) sshFilePutContents(sPath, content string, modAppend bool) op = ">>" } - if len(content) == 0 { - _, err := p.term.Run(fmt.Sprintf("echo '' %s %s", op, sPath)) - return err - } - cmds := []string{} var chunkSize int = 8192 for offset := 0; offset < len(content); offset += chunkSize { @@ -316,7 +318,7 @@ func (p *SSHPartition) sshFilePutContents(sPath, content string, modAppend bool) if err != nil { return fmt.Errorf("EscapeEchoString %q error: %v", content[offset:end], err) } - cmd := fmt.Sprintf("echo -n -e \"%s\" %s %s", ll, op, sPath) + cmd := fmt.Sprintf(`echo -n -e "%s" %s %s`, ll, op, sPath) cmds = append(cmds, cmd) if op == ">" { op = ">>" @@ -534,7 +536,7 @@ func MountSSHRootfs(term *ssh.Client, layouts []baremetal.Layout) (*SSHPartition return nil, nil, fmt.Errorf("Not found root disk partitions") } for _, part := range parts { - dev := NewSSHPartition(term, part.GetDev()) + dev := NewSSHPartition(term, part) if !dev.Mount() { continue } diff --git a/pkg/util/ssh/ssh.go b/pkg/util/ssh/ssh.go index e4c95839de..c49b17e0e7 100644 --- a/pkg/util/ssh/ssh.go +++ b/pkg/util/ssh/ssh.go @@ -125,7 +125,7 @@ func (s *Client) run(parseOutput bool, cmds ...string) ([]string, error) { return nil, err } defer session.Close() - log.Debugf("Run command: %q", cmd) + log.Debugf("Run command: %s", cmd) var stdOut bytes.Buffer var stdErr bytes.Buffer session.Stdout = &stdOut diff --git a/pkg/util/stringutils2/stringutils_test.go b/pkg/util/stringutils2/stringutils_test.go index 05bd332511..2a7f69cb58 100644 --- a/pkg/util/stringutils2/stringutils_test.go +++ b/pkg/util/stringutils2/stringutils_test.go @@ -100,6 +100,12 @@ func TestEscapeEchoString(t *testing.T) { want: `abcd\n\"Te\\\\rst\"ddd\"\$Test\"aaa\n\$TTT`, wantErr: false, }, + { + name: "echoInput", + args: args{"SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"1d6b\", ATTRS{idProduct}==\"0001\", RUN+=\"/bin/sh -c 'echo enabled > /sys$env{DEVPATH}/../power/wakeup'\""}, + want: `SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"1d6b\", ATTRS{idProduct}==\"0001\", RUN+=\"/bin/sh -c 'echo enabled > /sys\$env{DEVPATH}/../power/wakeup'\"`, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {