diff --git a/internal/usbgadget/config.go b/internal/usbgadget/config.go index b73d392..87a9e21 100644 --- a/internal/usbgadget/config.go +++ b/internal/usbgadget/config.go @@ -137,6 +137,26 @@ func (u *UsbGadget) GetPath(itemKey string) (string, error) { return joinPath(u.kvmGadgetPath, item.path), nil } +func (u *UsbGadget) OverrideGadgetConfig(itemKey string, itemAttr string, value string) (error, bool) { + u.configLock.Lock() + defer u.configLock.Unlock() + + // get it as a pointer + _, ok := u.configMap[itemKey] + if !ok { + return fmt.Errorf("config item %s not found", itemKey), false + } + + if u.configMap[itemKey].attrs[itemAttr] == value { + return nil, false + } + + u.configMap[itemKey].attrs[itemAttr] = value + u.log.Info().Str("itemKey", itemKey).Str("itemAttr", itemAttr).Str("value", value).Msg("overriding gadget config") + + return nil, true +} + func mountConfigFS() error { _, err := os.Stat(gadgetPath) // TODO: check if it's mounted properly diff --git a/jsonrpc.go b/jsonrpc.go index d56b8ea..fcc0243 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -523,10 +523,12 @@ type RPCHandler struct { func rpcSetMassStorageMode(mode string) (string, error) { logger.Info().Str("mode", mode).Msg("Setting mass storage mode") var cdrom bool - if mode == "cdrom" { + switch mode { + case "cdrom": cdrom = true - } else if mode != "file" { - logger.Info().Str("mode", mode).Msg("Invalid mode provided") + case "disk": + cdrom = false + default: return "", fmt.Errorf("invalid mode: %s", mode) } @@ -544,12 +546,12 @@ func rpcSetMassStorageMode(mode string) (string, error) { } func rpcGetMassStorageMode() (string, error) { - cdrom, err := getMassStorageMode() + cdrom, err := getMassStorageCDROMEnabled() if err != nil { return "", fmt.Errorf("failed to get mass storage mode: %w", err) } - mode := "file" + mode := "disk" if cdrom { mode = "cdrom" } diff --git a/ui/src/routes/devices.$id.mount.tsx b/ui/src/routes/devices.$id.mount.tsx index 74fcae2..4d3369a 100644 --- a/ui/src/routes/devices.$id.mount.tsx +++ b/ui/src/routes/devices.$id.mount.tsx @@ -414,7 +414,7 @@ function BrowserFileView({ if (file?.name.endsWith(".iso")) { setUsbMode("CDROM"); } else if (file?.name.endsWith(".img")) { - setUsbMode("CDROM"); + setUsbMode("Disk"); } }; @@ -566,7 +566,7 @@ function UrlView({ if (url.endsWith(".iso")) { setUsbMode("CDROM"); } else if (url.endsWith(".img")) { - setUsbMode("CDROM"); + setUsbMode("Disk"); } } @@ -773,7 +773,7 @@ function DeviceFileView({ if (file.name.endsWith(".iso")) { setUsbMode("CDROM"); } else if (file.name.endsWith(".img")) { - setUsbMode("CDROM"); + setUsbMode("Disk"); } } @@ -1579,7 +1579,6 @@ function UsbModeSelector({ type="radio" id="disk" name="mountType" - disabled checked={usbMode === "Disk"} onChange={() => setUsbMode("Disk")} className="h-3 w-3 border-slate-800/30 bg-white text-blue-700 transition-opacity focus:ring-blue-500 disabled:opacity-30 dark:bg-slate-800" @@ -1588,9 +1587,6 @@ function UsbModeSelector({ Disk -
- Coming soon -
diff --git a/usb_mass_storage.go b/usb_mass_storage.go index e70a353..adb2206 100644 --- a/usb_mass_storage.go +++ b/usb_mass_storage.go @@ -39,18 +39,29 @@ func setMassStorageImage(imagePath string) error { } func setMassStorageMode(cdrom bool) error { - massStorageFunctionPath, err := gadget.GetPath("mass_storage_lun0") - if err != nil { - return fmt.Errorf("failed to get mass storage path: %w", err) + if gadget == nil { + return fmt.Errorf("gadget is not initialized") } mode := "0" if cdrom { mode = "1" } - if err := writeFile(path.Join(massStorageFunctionPath, "lun.0", "cdrom"), mode); err != nil { - return fmt.Errorf("failed to set cdrom mode: %w", err) + + // override the config + err, changed := gadget.OverrideGadgetConfig("mass_storage_lun0", "cdrom", mode) + if err != nil { + return fmt.Errorf("failed to override gadget config: %w", err) } + if !changed { + return nil + } + + // apply the changes + if err := gadget.UpdateGadgetConfig(); err != nil { + return fmt.Errorf("failed to write gadget config: %w", err) + } + return nil } @@ -109,7 +120,7 @@ func rpcMountBuiltInImage(filename string) error { return mountImage(imagePath) } -func getMassStorageMode() (bool, error) { +func getMassStorageCDROMEnabled() (bool, error) { massStorageFunctionPath, err := gadget.GetPath("mass_storage_lun0") if err != nil { return false, fmt.Errorf("failed to get mass storage path: %w", err) @@ -193,6 +204,7 @@ func rpcMountWithHTTP(url string, mode VirtualMediaMode) error { virtualMediaStateMutex.Unlock() return fmt.Errorf("another virtual media is already mounted") } + setMassStorageMode(mode == CDROM) httpRangeReader = httpreadat.New(url) n, err := httpRangeReader.Size() if err != nil { @@ -239,6 +251,7 @@ func rpcMountWithWebRTC(filename string, size int64, mode VirtualMediaMode) erro Size: size, } virtualMediaStateMutex.Unlock() + setMassStorageMode(mode == CDROM) logger.Debug().Interface("currentVirtualMediaState", currentVirtualMediaState).Msg("currentVirtualMediaState") logger.Debug().Msg("Starting nbd device") nbdDevice = NewNBDDevice() @@ -270,6 +283,8 @@ func rpcMountWithStorage(filename string, mode VirtualMediaMode) error { return fmt.Errorf("another virtual media is already mounted") } + setMassStorageMode(mode == CDROM) + fullPath := filepath.Join(imagesFolder, filename) fileInfo, err := os.Stat(fullPath) if err != nil {