@@ -26,6 +26,19 @@ func writeFile(path string, data string) error {
26
26
return os .WriteFile (path , []byte (data ), 0644 )
27
27
}
28
28
29
+ func getMassStorageImage () (string , error ) {
30
+ massStorageFunctionPath , err := gadget .GetPath ("mass_storage_lun0" )
31
+ if err != nil {
32
+ return "" , fmt .Errorf ("failed to get mass storage path: %w" , err )
33
+ }
34
+
35
+ imagePath , err := os .ReadFile (path .Join (massStorageFunctionPath , "file" ))
36
+ if err != nil {
37
+ return "" , fmt .Errorf ("failed to get mass storage image path: %w" , err )
38
+ }
39
+ return strings .TrimSpace (string (imagePath )), nil
40
+ }
41
+
29
42
func setMassStorageImage (imagePath string ) error {
30
43
massStorageFunctionPath , err := gadget .GetPath ("mass_storage_lun0" )
31
44
if err != nil {
@@ -39,19 +52,21 @@ func setMassStorageImage(imagePath string) error {
39
52
}
40
53
41
54
func setMassStorageMode (cdrom bool ) error {
42
- massStorageFunctionPath , err := gadget .GetPath ("mass_storage_lun0" )
43
- if err != nil {
44
- return fmt .Errorf ("failed to get mass storage path: %w" , err )
45
- }
46
-
47
55
mode := "0"
48
56
if cdrom {
49
57
mode = "1"
50
58
}
51
- if err := writeFile (path .Join (massStorageFunctionPath , "lun.0" , "cdrom" ), mode ); err != nil {
59
+
60
+ err , changed := gadget .OverrideGadgetConfig ("mass_storage_lun0" , "cdrom" , mode )
61
+ if err != nil {
52
62
return fmt .Errorf ("failed to set cdrom mode: %w" , err )
53
63
}
54
- return nil
64
+
65
+ if ! changed {
66
+ return nil
67
+ }
68
+
69
+ return gadget .UpdateGadgetConfig ()
55
70
}
56
71
57
72
func onDiskMessage (msg webrtc.DataChannelMessage ) {
@@ -113,20 +128,17 @@ func rpcMountBuiltInImage(filename string) error {
113
128
return mountImage (imagePath )
114
129
}
115
130
116
- func getMassStorageMode () (bool , error ) {
131
+ func getMassStorageCDROMEnabled () (bool , error ) {
117
132
massStorageFunctionPath , err := gadget .GetPath ("mass_storage_lun0" )
118
133
if err != nil {
119
134
return false , fmt .Errorf ("failed to get mass storage path: %w" , err )
120
135
}
121
-
122
- data , err := os .ReadFile (path .Join (massStorageFunctionPath , "lun.0" , "cdrom" ))
136
+ data , err := os .ReadFile (path .Join (massStorageFunctionPath , "cdrom" ))
123
137
if err != nil {
124
138
return false , fmt .Errorf ("failed to read cdrom mode: %w" , err )
125
139
}
126
-
127
140
// Trim any whitespace characters. It has a newline at the end
128
141
trimmedData := strings .TrimSpace (string (data ))
129
-
130
142
return trimmedData == "1" , nil
131
143
}
132
144
@@ -191,6 +203,60 @@ func rpcUnmountImage() error {
191
203
192
204
var httpRangeReader * httpreadat.RangeReader
193
205
206
+ func getInitialVirtualMediaState () (* VirtualMediaState , error ) {
207
+ cdromEnabled , err := getMassStorageCDROMEnabled ()
208
+ if err != nil {
209
+ return nil , fmt .Errorf ("failed to get mass storage cdrom enabled: %w" , err )
210
+ }
211
+
212
+ diskPath , err := getMassStorageImage ()
213
+ if err != nil {
214
+ return nil , fmt .Errorf ("failed to get mass storage image: %w" , err )
215
+ }
216
+
217
+ initialState := & VirtualMediaState {
218
+ Source : Storage ,
219
+ Mode : Disk ,
220
+ }
221
+
222
+ if cdromEnabled {
223
+ initialState .Mode = CDROM
224
+ }
225
+
226
+ // TODO: check if it's WebRTC or HTTP
227
+ if diskPath == "" {
228
+ return nil , nil
229
+ } else if diskPath == "/dev/nbd0" {
230
+ initialState .Source = HTTP
231
+ initialState .URL = "/"
232
+ initialState .Size = 1
233
+ } else {
234
+ initialState .Filename = filepath .Base (diskPath )
235
+ // get size from file
236
+ logger .Info ().Str ("diskPath" , diskPath ).Msg ("getting file size" )
237
+ info , err := os .Stat (diskPath )
238
+ if err != nil {
239
+ return nil , fmt .Errorf ("failed to get file info: %w" , err )
240
+ }
241
+ initialState .Size = info .Size ()
242
+ }
243
+
244
+ return initialState , nil
245
+ }
246
+
247
+ func setInitialVirtualMediaState () error {
248
+ virtualMediaStateMutex .Lock ()
249
+ defer virtualMediaStateMutex .Unlock ()
250
+ initialState , err := getInitialVirtualMediaState ()
251
+ if err != nil {
252
+ return fmt .Errorf ("failed to get initial virtual media state: %w" , err )
253
+ }
254
+ currentVirtualMediaState = initialState
255
+
256
+ logger .Info ().Interface ("initial_virtual_media_state" , initialState ).Msg ("initial virtual media state set" )
257
+ return nil
258
+ }
259
+
194
260
func rpcMountWithHTTP (url string , mode VirtualMediaMode ) error {
195
261
virtualMediaStateMutex .Lock ()
196
262
if currentVirtualMediaState != nil {
@@ -204,6 +270,11 @@ func rpcMountWithHTTP(url string, mode VirtualMediaMode) error {
204
270
return fmt .Errorf ("failed to use http url: %w" , err )
205
271
}
206
272
logger .Info ().Str ("url" , url ).Int64 ("size" , n ).Msg ("using remote url" )
273
+
274
+ if err := setMassStorageMode (mode == CDROM ); err != nil {
275
+ return fmt .Errorf ("failed to set mass storage mode: %w" , err )
276
+ }
277
+
207
278
currentVirtualMediaState = & VirtualMediaState {
208
279
Source : HTTP ,
209
280
Mode : mode ,
@@ -243,6 +314,11 @@ func rpcMountWithWebRTC(filename string, size int64, mode VirtualMediaMode) erro
243
314
Size : size ,
244
315
}
245
316
virtualMediaStateMutex .Unlock ()
317
+
318
+ if err := setMassStorageMode (mode == CDROM ); err != nil {
319
+ return fmt .Errorf ("failed to set mass storage mode: %w" , err )
320
+ }
321
+
246
322
logger .Debug ().Interface ("currentVirtualMediaState" , currentVirtualMediaState ).Msg ("currentVirtualMediaState" )
247
323
logger .Debug ().Msg ("Starting nbd device" )
248
324
nbdDevice = NewNBDDevice ()
@@ -280,6 +356,10 @@ func rpcMountWithStorage(filename string, mode VirtualMediaMode) error {
280
356
return fmt .Errorf ("failed to get file info: %w" , err )
281
357
}
282
358
359
+ if err := setMassStorageMode (mode == CDROM ); err != nil {
360
+ return fmt .Errorf ("failed to set mass storage mode: %w" , err )
361
+ }
362
+
283
363
err = setMassStorageImage (fullPath )
284
364
if err != nil {
285
365
return fmt .Errorf ("failed to set mass storage image: %w" , err )
0 commit comments