🛸 Sync 2026-08-01 20:23:40

This commit is contained in:
github-actions[bot] 2026-08-01 20:23:40 +08:00
parent e37e0024d0
commit a93f778f83
9 changed files with 105 additions and 65 deletions

View File

@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=daed
PKG_VERSION:=2026.07.31
PKG_RELEASE:=36
PKG_RELEASE:=37
PKG_SOURCE:=daed-src-2026.07.31-178adbdeb296.tar.gz
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/daed-src

View File

@ -1,20 +1,25 @@
From: kenzok8 <kenzok8@noreply>
Date: 2026-07-08
Subject: [PATCH] daed: restart process when dashboard reload hangs
Dashboard "Apply" can leave dae's runtime half-reloaded on some OpenWrt
netns/veth setups. Bound the GraphQL reload request and let procd respawn daed
so daed-guard can clean stale runtime state before starting again.
Reported: https://github.com/kenzok8/openwrt-daede/issues/31
---
diff --git a/graphql/service/config/mutation_utils.go b/graphql/service/config/mutation_utils.go
index 7a3c33f..fd61554 100644
--- a/graphql/service/config/mutation_utils.go
+++ b/graphql/service/config/mutation_utils.go
@@ -11,0 +12 @@
@@ -9,11 +9,13 @@ import (
"context"
"errors"
"fmt"
+ "os"
@@ -16,0 +18 @@
"reflect"
"regexp"
"sort"
"strings"
"sync"
+ "time"
@@ -260,0 +263,9 @@
"github.com/daeuniverse/dae-wing/common"
"github.com/daeuniverse/dae-wing/dae"
@@ -258,6 +260,15 @@ func Rename(ctx context.Context, _id graphql.ID, name string) (n int32, err erro
var runLock sync.Mutex
+const reloadWaitTimeout = 75 * time.Second
+
+func restartAfterReloadTimeout() {
@ -24,10 +29,18 @@ Reported: https://github.com/kenzok8/openwrt-daede/issues/31
+ }()
+}
+
@@ -458 +469 @@
func Run(d *gorm.DB, noLoad bool) (n int32, err error) {
if ok := runLock.TryLock(); !ok {
return 0, fmt.Errorf("the last request didn't complete; make a cup of tea and take a break")
@@ -455,13 +466,24 @@ func Run(d *gorm.DB, noLoad bool) (n int32, err error) {
/// Reload with current config.
chReloadCallback := make(chan error)
- dae.ChReloadConfigs <- &dae.ReloadMessage{
+ reloadMsg := &dae.ReloadMessage{
@@ -462,3 +473,5 @@
Config: c,
Callback: chReloadCallback,
}
- errReload := <-chReloadCallback
- if errReload != nil {
- return 0, fmt.Errorf("failed to load new config: %w; see more in log", errReload)
@ -36,7 +49,7 @@ Reported: https://github.com/kenzok8/openwrt-daede/issues/31
+ case <-time.After(reloadWaitTimeout):
+ restartAfterReloadTimeout()
+ return 0, fmt.Errorf("failed to submit reload within %s; restarting daed to recover runtime", reloadWaitTimeout)
@@ -465,0 +479,9 @@
+ }
+ select {
+ case errReload := <-chReloadCallback:
+ if errReload != nil {
@ -45,4 +58,6 @@ Reported: https://github.com/kenzok8/openwrt-daede/issues/31
+ case <-time.After(reloadWaitTimeout):
+ restartAfterReloadTimeout()
+ return 0, fmt.Errorf("reload timed out after %s; restarting daed to recover runtime", reloadWaitTimeout)
+ }
}
// Save running status

View File

@ -1,30 +1,21 @@
From: kenzok8 <kenzok8@noreply>
Date: 2026-07-19
Subject: [PATCH] daed: bound startup network wait
Purge stale dae filters before probing the network and stop waiting after 60
seconds so the dashboard remains available for recovery.
---
--- a/dae/utils.go
+++ b/dae/utils.go
@@ -97 +97 @@
-func WaitForNetwork(log *logrus.Logger) {
+func WaitForNetwork(log *logrus.Logger) error {
@@ -98,0 +99 @@
+ deadline := time.Now().Add(60 * time.Second)
@@ -117,0 +119,3 @@
+ if time.Now().After(deadline) {
+ return fmt.Errorf("network unavailable after 60 seconds")
+ }
@@ -136,0 +141 @@
+ return nil
diff --git a/dae/run.go b/dae/run.go
index d8f86c2..a0a665d 100644
--- a/dae/run.go
+++ b/dae/run.go
@@ -35 +35,2 @@
@@ -32,7 +32,8 @@ var ChReloadConfigs = make(chan *ReloadMessage)
var GracefullyExit = make(chan struct{})
var EmptyConfig *daeConfig.Config
var c *control.ControlPlane
-var onceWaitingNetwork sync.Once
+var waitingNetworkMu sync.Mutex
+var networkReady bool
@@ -54,0 +56,13 @@
func init() {
sections, err := config_parser.Parse(`global{} routing{}`)
@@ -52,6 +53,19 @@ func ControlPlane() (*control.ControlPlane, error) {
return c, nil
}
+func waitForNetwork(log *logrus.Logger) error {
+ waitingNetworkMu.Lock()
+ defer waitingNetworkMu.Unlock()
@ -38,14 +29,60 @@ seconds so the dashboard remains available for recovery.
+ return nil
+}
+
@@ -223,0 +238,3 @@
func Run(log *logrus.Logger, conf *daeConfig.Config, externGeoDataDirs []string, disableTimestamp bool, dry bool) (err error) {
defer close(GracefullyExit)
// Not really run dae.
@@ -221,6 +235,9 @@ func newControlPlane(log *logrus.Logger, bpf interface{}, dnsCache map[string]*c
// Deep copy to prevent modification.
conf = deepcopy.Copy(conf).(*daeConfig.Config)
+ if bpf == nil {
+ control.PurgeStaleTCFilters(log)
+ }
@@ -231,3 +248,3 @@
// Init Direct Dialers.
direct.InitDirectDialers(conf.Global.FallbackResolver)
@@ -228,9 +245,9 @@ func newControlPlane(log *logrus.Logger, bpf interface{}, dnsCache map[string]*c
if !conf.Global.DisableWaitingNetwork && len(conf.Global.WanInterface) > 0 {
// Wait for network for WAN ready.
- onceWaitingNetwork.Do(func() {
- WaitForNetwork(log)
- })
+ if err = waitForNetwork(log); err != nil {
+ return nil, err
+ }
}
/// Get subscription -> nodeList mapping.
diff --git a/dae/utils.go b/dae/utils.go
index 65965a2..dc43cbc 100644
--- a/dae/utils.go
+++ b/dae/utils.go
@@ -94,8 +94,9 @@ func preprocessWanInterfaceAuto(params *daeConfig.Config) error {
return nil
}
-func WaitForNetwork(log *logrus.Logger) {
+func WaitForNetwork(log *logrus.Logger) error {
epo := 5 * time.Second
+ deadline := time.Now().Add(60 * time.Second)
client := http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (c net.Conn, err error) {
@@ -115,6 +116,9 @@ func WaitForNetwork(log *logrus.Logger) {
}
log.Infoln("Waiting for network...")
for i := 0; ; i++ {
+ if time.Now().After(deadline) {
+ return fmt.Errorf("network unavailable after 60 seconds")
+ }
resp, err := client.Get(cmd.CheckNetworkLinks[i%len(cmd.CheckNetworkLinks)])
if err != nil {
log.Debugln("CheckNetwork:", err)
@@ -134,4 +138,5 @@ func WaitForNetwork(log *logrus.Logger) {
time.Sleep(epo)
}
log.Infoln("Network online.")
+ return nil
}

View File

@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=hysteria
PKG_VERSION:=2.10.0
PKG_RELEASE:=12
PKG_VERSION:=2.11.0
PKG_RELEASE:=13
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/apernet/hysteria/tar.gz/app/v$(PKG_VERSION)?

View File

@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.8.1
PKG_RELEASE:=199
PKG_RELEASE:=200
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \

View File

@ -339,8 +339,7 @@ if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
"chnlist-file " .. RULES_PATH .. "/chnlist",
"ipset-name4 " .. setflag .. "psw_chn" .. suffix,
"ipset-name6 " .. setflag .. "psw_chn6" .. suffix,
"add-tagchn-ip" .. ((NFTFLAG == "1") and (" " .. table.concat(sets, ",")) or ""),
"chnlist-first"
"add-tagchn-ip" .. ((NFTFLAG == "1") and (" " .. table.concat(sets, ",")) or "")
}
merge_array(config_lines, tmp_lines)
log(string.format(" - 中国域名表(chnroute)%s", DNS_LOCAL or "默认"))

View File

@ -4,7 +4,7 @@ LUCI_TITLE:=Web UI for QEMU Virtual Machine Simple (VMS)
LUCI_DEPENDS:=@TARGET_x86_64 +qemu-vms +ttyd +usbutils +pciutils
PKG_LICENSE:=GPLv3
PKG_VERSION:=0.0.1
PKG_RELEASE:=9
PKG_RELEASE:=10
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -635,21 +635,10 @@ return view.extend({
var newNets = Array.prototype.slice.call(document.querySelectorAll('.edit-network-check:checked'))
.map(function(el) { return el.value; });
if (existingName) {
var oldNets = uci.get('qemu-vms', name, 'network') || [];
if (!Array.isArray(oldNets)) oldNets = oldNets ? [oldNets] : [];
var sortedOld = oldNets.slice().sort();
var sortedNew = newNets.slice().sort();
var changed = (sortedOld.length !== sortedNew.length) ||
sortedOld.some(function(v, i) { return v !== sortedNew[i]; });
if (changed) {
uci.set('qemu-vms', name, 'network', newNets); // только если изменился
}
} else {
if (newNets.length) {
uci.set('qemu-vms', name, 'network', newNets);
} else {
uci.unset('qemu-vms', name, 'network');
}
return uci.save().then(function() {

View File

@ -294,9 +294,9 @@ vm_status_one() {
[ -n "$pid" ] && json_add_int "pid" "$pid"
[ -n "$ram_kb" ] && json_add_int "ram_kb" "$ram_kb"
[ -n "$image_bytes" ] && json_add_int "disk_bytes" "$image_bytes"
json_add_string "console_sock" "/var/run/qemu-$vm.sock"
json_add_string "console_log" "/var/log/qemu-$vm-console.log"
json_add_string "qmp_sock" "/var/run/qemu-$vm.qmp"
json_add_string "console_sock" "$STATUS_DIR/qemu-$vm.sock"
json_add_string "file_log" "$LOG_DIR/$vm.log"
json_add_string "qmp_sock" "$STATUS_DIR/qemu-$vm.qmp"
json_close_object
}