Skip to content

Commit 679acea

Browse files
authored
fix: deduplicate logind shutdown inhibitors during silent updates (#318)
Use a shared refcounted inhibitor so overlapping update/check flows only hold one logind inhibit lock at a time, preventing duplicate org.deepin.dde.Lastore1 shutdown blockers. Bug: https://pms.uniontech.com/bug-view-350063.html
1 parent 638b0ea commit 679acea

3 files changed

Lines changed: 91 additions & 43 deletions

File tree

src/lastore-daemon/inhibitor.go

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@
55
package main
66

77
import (
8+
"sync"
89
"syscall"
910

1011
"github.com/godbus/dbus/v5"
1112
login1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.login1"
1213
)
1314

15+
var (
16+
sharedInhibitMu sync.Mutex
17+
sharedInhibitRef int
18+
sharedInhibitFd dbus.UnixFD = -1
19+
)
20+
21+
var (
22+
inhibitorFn = Inhibitor
23+
closeInhibitFd = func(fd dbus.UnixFD) error { return syscall.Close(int(fd)) }
24+
)
25+
1426
type methodCaller uint
1527

1628
const (
@@ -47,24 +59,58 @@ func (m *Manager) updateSystemOnChanging(onChanging bool, caller methodCaller) {
4759
default:
4860
why = Tr("Preventing from shutting down")
4961
}
50-
fd, err := Inhibitor("shutdown:sleep", dbusServiceName, why)
51-
logger.Infof("Prevent shutdown...: fd:%v\n", fd)
62+
fd, err := sharedInhibitAcquire(why)
5263
if err != nil {
53-
logger.Infof("Prevent shutdown failed: fd:%v, err:%v\n", fd, err)
64+
logger.Infof("Prevent shutdown failed: err:%v\n", err)
5465
return
5566
}
67+
logger.Info("Prevent shutdown...")
5668
m.inhibitFd = fd
5769
} else if !onChanging && m.inhibitFd != -1 {
58-
err := syscall.Close(int(m.inhibitFd))
70+
err := sharedInhibitRelease()
5971
if err != nil {
60-
logger.Infof("Enable shutdown...: fd:%d, err:%s\n", m.inhibitFd, err)
72+
logger.Infof("Enable shutdown failed: err:%v\n", err)
6173
} else {
6274
logger.Info("Enable shutdown...")
6375
}
6476
m.inhibitFd = -1
6577
}
6678
}
6779

80+
func sharedInhibitAcquire(why string) (dbus.UnixFD, error) {
81+
sharedInhibitMu.Lock()
82+
defer sharedInhibitMu.Unlock()
83+
84+
if sharedInhibitRef == 0 {
85+
fd, err := inhibitorFn("shutdown:sleep", dbusServiceName, why)
86+
if err != nil {
87+
return 0, err
88+
}
89+
sharedInhibitFd = fd
90+
}
91+
sharedInhibitRef++
92+
return sharedInhibitFd, nil
93+
}
94+
95+
func sharedInhibitRelease() error {
96+
sharedInhibitMu.Lock()
97+
defer sharedInhibitMu.Unlock()
98+
99+
if sharedInhibitRef == 0 {
100+
return nil
101+
}
102+
sharedInhibitRef--
103+
if sharedInhibitRef != 0 {
104+
return nil
105+
}
106+
if sharedInhibitFd == -1 {
107+
return nil
108+
}
109+
fd := sharedInhibitFd
110+
sharedInhibitFd = -1
111+
return closeInhibitFd(fd)
112+
}
113+
68114
func Inhibitor(what, who, why string) (dbus.UnixFD, error) {
69115
systemConn, err := dbus.SystemBus()
70116
if err != nil {

src/lastore-daemon/manager_check.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"errors"
1010
"fmt"
1111
"os"
12-
"syscall"
1312
"time"
1413

1514
"github.com/linuxdeepin/lastore-daemon/src/internal/system"
@@ -44,30 +43,32 @@ func (m *Manager) checkUpgrade(sender dbus.Sender, checkMode system.UpdateType,
4443
if m.rebootTimeoutTimer != nil {
4544
m.rebootTimeoutTimer.Stop()
4645
}
47-
var inhibitFd dbus.UnixFD = -1
4846
why := Tr("Checking and installing updates...")
47+
var inhibitHeld bool
4948
inhibit := func(enable bool) {
50-
logger.Infof("handle inhibit:%v fd:%v", enable, inhibitFd)
49+
logger.Infof("handle inhibit:%v held:%v", enable, inhibitHeld)
5150
if enable {
52-
if inhibitFd == -1 {
53-
fd, err := Inhibitor("shutdown:sleep", dbusServiceName, why)
54-
if err != nil {
55-
logger.Infof("checkUpgrade:prevent shutdown failed: fd:%v, err:%v\n", fd, err)
56-
} else {
57-
logger.Infof("checkUpgrade:prevent shutdown: fd:%v\n", fd)
58-
inhibitFd = fd
59-
}
51+
if inhibitHeld {
52+
return
53+
}
54+
_, err := sharedInhibitAcquire(why)
55+
if err != nil {
56+
logger.Infof("checkUpgrade:prevent shutdown failed: err:%v\n", err)
57+
return
6058
}
59+
logger.Info("checkUpgrade:prevent shutdown")
60+
inhibitHeld = true
6161
} else {
62-
if inhibitFd != -1 {
63-
err := syscall.Close(int(inhibitFd))
64-
if err != nil {
65-
logger.Infof("checkUpgrade:enable shutdown failed: fd:%d, err:%s\n", inhibitFd, err)
66-
} else {
67-
logger.Info("checkUpgrade:enable shutdown")
68-
inhibitFd = -1
69-
}
62+
if !inhibitHeld {
63+
return
64+
}
65+
err := sharedInhibitRelease()
66+
if err != nil {
67+
logger.Infof("checkUpgrade:enable shutdown failed: err:%v\n", err)
68+
return
7069
}
70+
logger.Info("checkUpgrade:enable shutdown")
71+
inhibitHeld = false
7172
}
7273
}
7374
var job *Job

src/lastore-daemon/manager_upgrade.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"path/filepath"
1616
"strings"
1717
"sync"
18-
"syscall"
1918
"time"
2019

2120
"github.com/linuxdeepin/lastore-daemon/src/internal/config"
@@ -100,30 +99,32 @@ func (m *Manager) distUpgradePartly(sender dbus.Sender, origin system.UpdateType
10099
}
101100
return "/", dbusutil.ToError(createJobErr)
102101
}
103-
var inhibitFd dbus.UnixFD = -1
104102
why := Tr("Backing up and installing updates...")
103+
var inhibitHeld bool
105104
inhibit := func(enable bool) {
106-
logger.Infof("DistUpgradePartly:handle inhibit:%v fd:%v", enable, inhibitFd)
105+
logger.Infof("DistUpgradePartly:handle inhibit:%v held:%v", enable, inhibitHeld)
107106
if enable {
108-
if inhibitFd == -1 {
109-
fd, err := Inhibitor("shutdown:sleep", dbusServiceName, why)
110-
if err != nil {
111-
logger.Infof("DistUpgradePartly:prevent shutdown failed: fd:%v, err:%v\n", fd, err)
112-
} else {
113-
logger.Infof("DistUpgradePartly:prevent shutdown: fd:%v\n", fd)
114-
inhibitFd = fd
115-
}
107+
if inhibitHeld {
108+
return
109+
}
110+
_, err := sharedInhibitAcquire(why)
111+
if err != nil {
112+
logger.Infof("DistUpgradePartly:prevent shutdown failed: err:%v\n", err)
113+
return
116114
}
115+
logger.Info("DistUpgradePartly:prevent shutdown")
116+
inhibitHeld = true
117117
} else {
118-
if inhibitFd != -1 {
119-
err := syscall.Close(int(inhibitFd))
120-
if err != nil {
121-
logger.Infof("DistUpgradePartly:enable shutdown failed: fd:%d, err:%s\n", inhibitFd, err)
122-
} else {
123-
logger.Info("DistUpgradePartly:enable shutdown")
124-
inhibitFd = -1
125-
}
118+
if !inhibitHeld {
119+
return
120+
}
121+
err := sharedInhibitRelease()
122+
if err != nil {
123+
logger.Infof("DistUpgradePartly:enable shutdown failed: err:%v\n", err)
124+
return
126125
}
126+
logger.Info("DistUpgradePartly:enable shutdown")
127+
inhibitHeld = false
127128
}
128129
}
129130
// 开始更新job

0 commit comments

Comments
 (0)