Hi Brian, I now had more time to look at it - thanks for your patience and your 
detailed report!
The around that currently is this in libvirt doing that is like this:

 110 #if defined(HAVE_STRUCT_IFREQ) && defined(__linux__)                       
      
 111 /*                                                                         
      
 112  * Bridge parameters can be set via sysfs on newish kernels,               
      
 113  * or by  ioctl on older kernels. Perhaps we could just use                
      
 114  * ioctl for every kernel, but its not clear what the long                 
      
 115  * term lifespan of the ioctl interface is...                              
      
 116  */                                                                        
      
 117 static int virNetDevBridgeSet(const char *brname,                          
      
 118                               const char *paramname,  /* sysfs param name 
*/     
 119                               unsigned long value,    /* new value */      
      
 120                               int fd,                 /* control socket */ 
      
 121                               struct ifreq *ifr)      /* pre-filled bridge 
name */
 122 {                                                                          
      
 123     VIR_AUTOFREE(char *) path = NULL;                                      
      
 124                                                                            
      
 125     if (virAsprintf(&path, SYSFS_NET_DIR "%s/bridge/%s", brname, 
paramname) < 0) 
 126         return -1;                                                         
      
 127                                                                            
      
 128     if (virFileExists(path)) {                                             
      
 129         char valuestr[INT_BUFSIZE_BOUND(value)];                           
      
 130         snprintf(valuestr, sizeof(valuestr), "%lu", value);                
      
 131         if (virFileWriteStr(path, valuestr, 0) < 0) {                      
      
 132             virReportSystemError(errno,                                    
      
 133                                  _("Unable to set bridge %s %s"), brname, 
paramname);
 134             return -1;                                                     
      
 135         }                                                                  
      
 136     } else {                                                               
      
 137         unsigned long paramid;                                             
      
 138         if (STREQ(paramname, "stp_state")) {                               
      
 139             paramid = BRCTL_SET_BRIDGE_STP_STATE;                          
      
 140         } else if (STREQ(paramname, "forward_delay")) {                    
      
 141             paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY;                      
      
 142         } else {                                                           
      
 143             virReportSystemError(EINVAL,                                   
      
 144                                  _("Unable to set bridge %s %s"), brname, 
paramname);
 145             return -1;                                                     
      
 146         }                                                                  
      
 147         unsigned long args[] = { paramid, value, 0, 0 };                   
      
 148         ifr->ifr_data = (char*)&args;                                      
      
 149         if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) {                          
      
 150             virReportSystemError(errno,                                    
      
 151                                  _("Unable to set bridge %s %s"), brname, 
paramname);
 152             return -1;                                                     
      
 153         }                                                                  
      
 154     }                                                                      
      
 155                                                                            
      
 156     return 0;                                                              
      
 157 }


Which means if the sysfs path exists it tries through sysfs (only) and only 
otherwise with the older ioctl interface.
The code is stable from libvirt 4.0 as in Ubuntu 18.04 until todays 4.9 just 
released upstream.

I think it would not be unreasonable to modify that be a fallback
instead of an if/else.

I have coded something up (experimentally) that I'd want you to test from [1].
If that is working for you as expected than I'd suggest the same upstream in a 
polished way.
Please let me know what happens if you use this libvirt 4.0.0-1ubuntu8.7~ppa1 
(in your container).

[1]: https://launchpad.net/~ci-train-ppa-
service/+archive/ubuntu/3525/+packages

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1802906

Title:
  libvirt inside lxd container cannot start virbr0 (Unable to set bridge
  virbr0 forward_delay: Permission denied)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1802906/+subscriptions

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to