Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicated network setup for stacks #476

Closed
yomimono opened this issue Dec 4, 2015 · 5 comments
Closed

Duplicated network setup for stacks #476

yomimono opened this issue Dec 4, 2015 · 5 comments

Comments

@yomimono
Copy link
Contributor

yomimono commented Dec 4, 2015

For unikernels that request a stack (like the network example in mirage-skeleton), Mirage currently generates a main.ml that duplicates connection code many times over and results in a stack built with distinct (but identically configured) records for the underlying implementations. For example, here's the snippet that generates the tcp and udp records, from a main.ml made with mirage configure --xen in the aforementioned example:

let udp1 () =                                                                   
  let __ipv411 = ipv411 () in                                                   
  __ipv411 >>= function                                                         
  | `Error _e -> fail (Failure "ipv411")                                        
  | `Ok _ipv411 ->                                                              
  Udp1.connect _ipv411                                                          

let tcp1 () =                                                                   
  let __ipv411 = ipv411 () in                                                   
  let __time1 = time1 () in                                                     
  let __clock1 = clock1 () in                                                   
  let __random1 = random1 () in                                                 
  __ipv411 >>= function                                                         
  | `Error _e -> fail (Failure "ipv411")                                        
  | `Ok _ipv411 ->                                                              
  __time1 >>= function                                                          
  | `Error _e -> fail (Failure "time1")                                         
  | `Ok _time1 ->                                                               
  __clock1 >>= function                                                         
  | `Error _e -> fail (Failure "clock1")                                        
  | `Ok _clock1 ->                                                              
  __random1 >>= function                                                        
  | `Error _e -> fail (Failure "random1")                                       
  | `Ok _random1 ->                                                             
  Tcp1.connect _ipv411                           

Each calls ipv411 (), which results in a new ip record. ipv411 () itself generates new underlying records each time it's called, resulting in output like the following when the unikernel starts up:

Netif: add resume hook
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netif.connect 0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
Netfront.create: id=0 domid=0
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce
MAC: 00:16:3e:13:06:ce

Functions like tcp1 and udp1 should probably take the required subcomponents as arguments, rather than generating them within the function and not exposing them.

@Drup
Copy link
Member

Drup commented Dec 4, 2015

Functions like tcp1 and udp1 should probably take the required subcomponents as arguments, rather than generating them within the function and not exposing them.

Alternatively, instead of a unit function, we return a Lazy, this should solve the problem once and for all.

@yomimono
Copy link
Contributor Author

yomimono commented Dec 4, 2015

Would you not still have the problem of distinct records (rather than everything being built on top of the same netif/ethif/ip/arp/etc record) with the lazy approach?

@Drup
Copy link
Member

Drup commented Dec 4, 2015

I don't think so. The udp example would look like that :

let udp1 = lazy (
  let __ipv411 = Lazy.force ipv411 in                                                   
  __ipv411 >>= function                                                         
  | `Error _e -> fail (Failure "ipv411")                                        
  | `Ok _ipv411 ->                                                              
  Udp1.connect _ipv411)

@yallop
Copy link
Member

yallop commented Dec 31, 2015

This appears to have been fixed by mirage/functoria#44. @yomimono, can you confirm?

@yomimono
Copy link
Contributor Author

yomimono commented Jan 4, 2016

Yes, all appears to be well now; closing.

@yomimono yomimono closed this as completed Jan 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants