mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
Merge pull request #489 from tpretz/virtual-media-split
Virtual Media Changes
This commit is contained in:
@@ -94,6 +94,7 @@ start_usb_dev(){
|
||||
ln -s functions/hid.GS2 configs/c.1
|
||||
fi
|
||||
|
||||
# dedicated for media
|
||||
if [ -e /boot/usb.disk0 ]
|
||||
then
|
||||
mkdir functions/mass_storage.disk0
|
||||
@@ -108,17 +109,20 @@ start_usb_dev(){
|
||||
disk=$(cat /boot/usb.disk0)
|
||||
if [ -z "${disk}" ]
|
||||
then
|
||||
# if [ ! -e /mnt/usbdisk.img ]
|
||||
# then
|
||||
# fallocate -l 8G /mnt/usbdisk.img
|
||||
# mkfs.vfat /mnt/usbdisk.img
|
||||
# fi
|
||||
echo /dev/mmcblk0p3 > functions/mass_storage.disk0/lun.0/file
|
||||
echo "" > functions/mass_storage.disk0/lun.0/file
|
||||
else
|
||||
cat /boot/usb.disk0 > functions/mass_storage.disk0/lun.0/file
|
||||
fi
|
||||
fi
|
||||
|
||||
# mount data partition
|
||||
if [ -e /boot/usb.disk1 ]
|
||||
then
|
||||
mkdir functions/mass_storage.disk1
|
||||
ln -s functions/mass_storage.disk1 configs/c.1/
|
||||
echo /dev/mmcblk0p3 > functions/mass_storage.disk1/lun.0/file
|
||||
fi
|
||||
|
||||
ls /sys/class/udc/ | cat > UDC
|
||||
echo device > /proc/cviusb/otg_role
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ type DeleteScriptReq struct {
|
||||
|
||||
type GetVirtualDeviceRsp struct {
|
||||
Network bool `json:"network"`
|
||||
Media bool `json:"media"`
|
||||
Disk bool `json:"disk"`
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ import (
|
||||
|
||||
const (
|
||||
imageDirectory = "/data"
|
||||
imageNone = "/dev/mmcblk0p3"
|
||||
cdromFlag = "/sys/kernel/config/usb_gadget/g0/functions/mass_storage.disk0/lun.0/cdrom"
|
||||
mountDevice = "/sys/kernel/config/usb_gadget/g0/functions/mass_storage.disk0/lun.0/file"
|
||||
inquiryString = "/sys/kernel/config/usb_gadget/g0/functions/mass_storage.disk0/lun.0/inquiry_string"
|
||||
roFlag = "/sys/kernel/config/usb_gadget/g0/functions/mass_storage.disk0/lun.0/ro"
|
||||
usbNoRstMarker = "/boot/usb.norst"
|
||||
)
|
||||
|
||||
func (s *Service) GetImages(c *gin.Context) {
|
||||
@@ -108,16 +108,20 @@ func (s *Service) MountImage(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// mount
|
||||
// mount if file provided
|
||||
image := req.File
|
||||
if image == "" {
|
||||
image = imageNone
|
||||
if image != "" {
|
||||
if err := os.WriteFile(mountDevice, []byte(image), 0o666); err != nil {
|
||||
log.Errorf("mount file %s failed: %s", image, err)
|
||||
rsp.ErrRsp(c, -2, "mount image failed")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.WriteFile(mountDevice, []byte(image), 0o666); err != nil {
|
||||
log.Errorf("mount file %s failed: %s", image, err)
|
||||
rsp.ErrRsp(c, -2, "mount image failed")
|
||||
return
|
||||
// check to see if usb gadget reset is disabled
|
||||
resetUsb := true
|
||||
if _, err := os.Stat(usbNoRstMarker); err == nil {
|
||||
resetUsb = false
|
||||
}
|
||||
|
||||
h := hid.GetHid()
|
||||
@@ -129,18 +133,20 @@ func (s *Service) MountImage(c *gin.Context) {
|
||||
}()
|
||||
|
||||
// reset usb
|
||||
commands := []string{
|
||||
"echo > /sys/kernel/config/usb_gadget/g0/UDC",
|
||||
"ls /sys/class/udc/ | cat > /sys/kernel/config/usb_gadget/g0/UDC",
|
||||
}
|
||||
|
||||
for _, command := range commands {
|
||||
err := exec.Command("sh", "-c", command).Run()
|
||||
if err != nil {
|
||||
rsp.ErrRsp(c, -2, "execute command failed")
|
||||
return
|
||||
if resetUsb {
|
||||
commands := []string{
|
||||
"echo > /sys/kernel/config/usb_gadget/g0/UDC",
|
||||
"ls /sys/class/udc/ | cat > /sys/kernel/config/usb_gadget/g0/UDC",
|
||||
}
|
||||
|
||||
for _, command := range commands {
|
||||
err := exec.Command("sh", "-c", command).Run()
|
||||
if err != nil {
|
||||
rsp.ErrRsp(c, -2, "execute command failed")
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
rsp.OkRsp(c)
|
||||
@@ -157,9 +163,6 @@ func (s *Service) GetMountedImage(c *gin.Context) {
|
||||
}
|
||||
|
||||
image := strings.ReplaceAll(string(content), "\n", "")
|
||||
if image == imageNone {
|
||||
image = ""
|
||||
}
|
||||
|
||||
data := &proto.GetMountedImageRsp{
|
||||
File: image,
|
||||
|
||||
@@ -14,7 +14,8 @@ import (
|
||||
|
||||
const (
|
||||
virtualNetwork = "/boot/usb.rndis0"
|
||||
virtualDisk = "/boot/usb.disk0"
|
||||
virtualMedia = "/boot/usb.disk0"
|
||||
virtualDisk = "/boot/usb.disk1"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -31,16 +32,29 @@ var (
|
||||
"/etc/init.d/S03usbdev start",
|
||||
}
|
||||
|
||||
mountDiskCommands = []string{
|
||||
mountMediaCommands = []string{
|
||||
"touch /boot/usb.disk0",
|
||||
"/etc/init.d/S03usbdev stop",
|
||||
"/etc/init.d/S03usbdev start",
|
||||
}
|
||||
|
||||
unmountMediaCommands = []string{
|
||||
"/etc/init.d/S03usbdev stop",
|
||||
"rm -rf /sys/kernel/config/usb_gadget/g0/configs/c.1/mass_storage.disk0",
|
||||
"rm /boot/usb.disk0",
|
||||
"/etc/init.d/S03usbdev start",
|
||||
}
|
||||
|
||||
mountDiskCommands = []string{
|
||||
"touch /boot/usb.disk1",
|
||||
"/etc/init.d/S03usbdev stop",
|
||||
"/etc/init.d/S03usbdev start",
|
||||
}
|
||||
|
||||
unmountDiskCommands = []string{
|
||||
"/etc/init.d/S03usbdev stop",
|
||||
"rm -rf /sys/kernel/config/usb_gadget/g0/configs/c.1/mass_storage.disk0",
|
||||
"rm /boot/usb.disk0",
|
||||
"rm -rf /sys/kernel/config/usb_gadget/g0/configs/c.1/mass_storage.disk1",
|
||||
"rm /boot/usb.disk1",
|
||||
"/etc/init.d/S03usbdev start",
|
||||
}
|
||||
)
|
||||
@@ -49,10 +63,12 @@ func (s *Service) GetVirtualDevice(c *gin.Context) {
|
||||
var rsp proto.Response
|
||||
|
||||
network, _ := isDeviceExist(virtualNetwork)
|
||||
media, _ := isDeviceExist(virtualMedia)
|
||||
disk, _ := isDeviceExist(virtualDisk)
|
||||
|
||||
rsp.OkRspWithData(c, &proto.GetVirtualDeviceRsp{
|
||||
Network: network,
|
||||
Media: media,
|
||||
Disk: disk,
|
||||
})
|
||||
log.Debugf("get virtual device success")
|
||||
@@ -80,6 +96,15 @@ func (s *Service) UpdateVirtualDevice(c *gin.Context) {
|
||||
} else {
|
||||
commands = unmountNetworkCommands
|
||||
}
|
||||
case "media":
|
||||
device = virtualMedia
|
||||
|
||||
exist, _ := isDeviceExist(device)
|
||||
if !exist {
|
||||
commands = mountMediaCommands
|
||||
} else {
|
||||
commands = unmountMediaCommands
|
||||
}
|
||||
case "disk":
|
||||
device = virtualDisk
|
||||
|
||||
|
||||
@@ -279,7 +279,9 @@ const en = {
|
||||
},
|
||||
hidOnly: 'HID-Only Mode',
|
||||
disk: 'Virtual Disk',
|
||||
diskDesc: 'Mount virtual U-disk on the remote host',
|
||||
diskDesc: 'Mount SD card on the remote host',
|
||||
media: "Virtual Image",
|
||||
mediaDesc: 'Attach virtual image device to the remote host',
|
||||
network: 'Virtual Network',
|
||||
networkDesc: 'Mount virtual network card on the remote host',
|
||||
reboot: 'Reboot',
|
||||
|
||||
@@ -8,8 +8,9 @@ export const VirtualDevices = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isNetworkOn, setIsNetworkOn] = useState(false);
|
||||
const [isMediaOn, setIsMediaOn] = useState(false);
|
||||
const [isDiskOn, setIsDiskOn] = useState(false);
|
||||
const [loading, setLoading] = useState(''); // '' | 'network' | 'disk'
|
||||
const [loading, setLoading] = useState(''); // '' | 'network' | 'media' | 'disk'
|
||||
|
||||
useEffect(() => {
|
||||
api.getVirtualDevice().then((rsp) => {
|
||||
@@ -18,11 +19,12 @@ export const VirtualDevices = () => {
|
||||
}
|
||||
|
||||
setIsNetworkOn(rsp.data.network);
|
||||
setIsMediaOn(rsp.data.media);
|
||||
setIsDiskOn(rsp.data.disk);
|
||||
});
|
||||
}, []);
|
||||
|
||||
function update(device: 'network' | 'disk') {
|
||||
function update(device: 'network' | 'media' | 'disk') {
|
||||
if (loading) return;
|
||||
setLoading(device);
|
||||
|
||||
@@ -33,10 +35,16 @@ export const VirtualDevices = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (device === 'network') {
|
||||
setIsNetworkOn(rsp.data.on);
|
||||
} else {
|
||||
setIsDiskOn(rsp.data.on);
|
||||
switch (device) {
|
||||
case 'network':
|
||||
setIsNetworkOn(rsp.data.on);
|
||||
break;
|
||||
case 'media':
|
||||
setIsMediaOn(rsp.data.on);
|
||||
break;
|
||||
case 'disk':
|
||||
setIsDiskOn(rsp.data.on);
|
||||
break;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -46,6 +54,15 @@ export const VirtualDevices = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col">
|
||||
<span>{t('settings.device.media')}</span>
|
||||
<span className="text-xs text-neutral-500">{t('settings.device.mediaDesc')}</span>
|
||||
</div>
|
||||
|
||||
<Switch checked={isMediaOn} loading={loading === 'media'} onChange={() => update('media')} />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col">
|
||||
<span>{t('settings.device.disk')}</span>
|
||||
|
||||
Reference in New Issue
Block a user