This commit is contained in:
Aveline 2025-11-05 16:47:55 +01:00 committed by GitHub
commit 7956b90259
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 37 additions and 21 deletions

View File

@ -177,7 +177,7 @@ func (u *UsbGadget) Init() error {
u.udc = udcs[0] u.udc = udcs[0]
err := u.configureUsbGadget(false) err := u.configureUsbGadget(false, true)
if err != nil { if err != nil {
return u.logError("unable to initialize USB stack", err) return u.logError("unable to initialize USB stack", err)
} }
@ -185,13 +185,13 @@ func (u *UsbGadget) Init() error {
return nil return nil
} }
func (u *UsbGadget) UpdateGadgetConfig() error { func (u *UsbGadget) UpdateGadgetConfig(resetUsbIfNeeded bool) error {
u.configLock.Lock() u.configLock.Lock()
defer u.configLock.Unlock() defer u.configLock.Unlock()
u.loadGadgetConfig() u.loadGadgetConfig()
err := u.configureUsbGadget(true) err := u.configureUsbGadget(true, resetUsbIfNeeded)
if err != nil { if err != nil {
return u.logError("unable to update gadget config", err) return u.logError("unable to update gadget config", err)
} }
@ -199,14 +199,28 @@ func (u *UsbGadget) UpdateGadgetConfig() error {
return nil return nil
} }
func (u *UsbGadget) configureUsbGadget(resetUsb bool) error { func (u *UsbGadget) configureUsbGadget(resetUsb bool, resetUsbIfNeeded bool) error {
return u.WithTransaction(func() error { f := func(resetUsbBefore bool, resetUsbAfter bool) func() error {
u.tx.MountConfigFS() return func() error {
u.tx.CreateConfigPath() if resetUsbBefore {
u.tx.WriteGadgetConfig() u.tx.RebindUsb(true)
if resetUsb { }
u.tx.RebindUsb(true) u.tx.MountConfigFS()
u.tx.CreateConfigPath()
u.tx.WriteGadgetConfig()
if resetUsbAfter {
u.tx.RebindUsb(true)
}
return nil
} }
return nil }
})
// initial attempt to configure the gadget
err := u.WithTransaction(f(false, resetUsb))
if err != nil && !resetUsbIfNeeded {
return err
}
// if the initial attempt failed, try to configure the gadget again with the resetUsb flag
return u.WithTransaction(f(true, resetUsb))
} }

View File

@ -678,7 +678,7 @@ func rpcSetUsbConfig(usbConfig usbgadget.Config) error {
LoadConfig() LoadConfig()
config.UsbConfig = &usbConfig config.UsbConfig = &usbConfig
gadget.SetGadgetConfig(config.UsbConfig) gadget.SetGadgetConfig(config.UsbConfig)
return updateUsbRelatedConfig() return updateUsbRelatedConfig(false)
} }
func rpcGetWakeOnLanDevices() ([]WakeOnLanDevice, error) { func rpcGetWakeOnLanDevices() ([]WakeOnLanDevice, error) {
@ -890,8 +890,8 @@ func rpcGetUsbDevices() (usbgadget.Devices, error) {
return *config.UsbDevices, nil return *config.UsbDevices, nil
} }
func updateUsbRelatedConfig() error { func updateUsbRelatedConfig(resetUsbIfNeeded bool) error {
if err := gadget.UpdateGadgetConfig(); err != nil { if err := gadget.UpdateGadgetConfig(resetUsbIfNeeded); err != nil {
return fmt.Errorf("failed to write gadget config: %w", err) return fmt.Errorf("failed to write gadget config: %w", err)
} }
if err := SaveConfig(); err != nil { if err := SaveConfig(); err != nil {
@ -903,7 +903,7 @@ func updateUsbRelatedConfig() error {
func rpcSetUsbDevices(usbDevices usbgadget.Devices) error { func rpcSetUsbDevices(usbDevices usbgadget.Devices) error {
config.UsbDevices = &usbDevices config.UsbDevices = &usbDevices
gadget.SetGadgetDevices(config.UsbDevices) gadget.SetGadgetDevices(config.UsbDevices)
return updateUsbRelatedConfig() return updateUsbRelatedConfig(false)
} }
func rpcSetUsbDeviceState(device string, enabled bool) error { func rpcSetUsbDeviceState(device string, enabled bool) error {
@ -920,7 +920,7 @@ func rpcSetUsbDeviceState(device string, enabled bool) error {
return fmt.Errorf("invalid device: %s", device) return fmt.Errorf("invalid device: %s", device)
} }
gadget.SetGadgetDevices(config.UsbDevices) gadget.SetGadgetDevices(config.UsbDevices)
return updateUsbRelatedConfig() return updateUsbRelatedConfig(false)
} }
func rpcSetCloudUrl(apiUrl string, appUrl string) error { func rpcSetCloudUrl(apiUrl string, appUrl string) error {

View File

@ -12,6 +12,7 @@ import { TextAreaWithLabel } from "@components/TextArea";
import { isOnDevice } from "@/main"; import { isOnDevice } from "@/main";
import notifications from "@/notifications"; import notifications from "@/notifications";
import { m } from "@localizations/messages.js"; import { m } from "@localizations/messages.js";
import { sleep } from "@/utils";
export default function SettingsAdvancedRoute() { export default function SettingsAdvancedRoute() {
const { send } = useJsonRpc(); const { send } = useJsonRpc();
@ -311,7 +312,7 @@ export default function SettingsAdvancedRoute() {
size="SM" size="SM"
theme="light" theme="light"
text={m.advanced_reset_config_button()} text={m.advanced_reset_config_button()}
onClick={() => { onClick={async () => {
handleResetConfig(); handleResetConfig();
// Add 2s delay between resetting the configuration and calling reload() to prevent reload from interrupting the RPC call to reset things. // Add 2s delay between resetting the configuration and calling reload() to prevent reload from interrupting the RPC call to reset things.
await sleep(2000); await sleep(2000);

View File

@ -4,12 +4,13 @@ import { useNavigate } from "react-router";
import { useJsonRpc } from "@hooks/useJsonRpc"; import { useJsonRpc } from "@hooks/useJsonRpc";
import { Button } from "@components/Button"; import { Button } from "@components/Button";
import { m } from "@localizations/messages.js"; import { m } from "@localizations/messages.js";
import { sleep } from "@/utils";
export default function SettingsGeneralRebootRoute() { export default function SettingsGeneralRebootRoute() {
const navigate = useNavigate(); const navigate = useNavigate();
const { send } = useJsonRpc(); const { send } = useJsonRpc();
const onClose = useCallback(() => { const onClose = useCallback(async () => {
navigate(".."); // back to the devices.$id.settings page navigate(".."); // back to the devices.$id.settings page
// Add 1s delay between navigation and calling reload() to prevent reload from interrupting the navigation. // Add 1s delay between navigation and calling reload() to prevent reload from interrupting the navigation.
await sleep(1000); await sleep(1000);

View File

@ -21,7 +21,7 @@ export default function SettingsGeneralUpdateRoute() {
const { setModalView, otaState } = useUpdateStore(); const { setModalView, otaState } = useUpdateStore();
const { send } = useJsonRpc(); const { send } = useJsonRpc();
const onClose = useCallback(() => { const onClose = useCallback(async () => {
navigate(".."); // back to the devices.$id.settings page navigate(".."); // back to the devices.$id.settings page
// Add 1s delay between navigation and calling reload() to prevent reload from interrupting the navigation. // Add 1s delay between navigation and calling reload() to prevent reload from interrupting the navigation.
await sleep(1000); await sleep(1000);

View File

@ -66,7 +66,7 @@ func setMassStorageMode(cdrom bool) error {
return nil return nil
} }
return gadget.UpdateGadgetConfig() return gadget.UpdateGadgetConfig(true)
} }
func mountImage(imagePath string) error { func mountImage(imagePath string) error {