[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [BUG]: when using `xl restore`,xc_evtchn_alloc_unbound will raise this error





On Fri, Jan 4, 2013 at 11:23 AM, 马磊 <aware.why@xxxxxxxxx> wrote:


On Mon, Dec 31, 2012 at 8:03 PM, Wei Liu <Wei.Liu2@xxxxxxxxxx> wrote:
On Mon, 2012-12-31 at 03:10 +0000, 马磊 wrote:
>
>
>
>         I think the two files are mostly the same, but to be sure you
>         need to
>         look into the source file in both Linux and Xen. You should
>         start from
>         the hypervisor level, find out why it returns -EPERM. Root
>         user in Dom0
>         has nothing to do with privilege in hypervisor level.
>
>
>         Wei.
>
> The scene is that there are more than 10 processes, each process calls
> `xl restore` to start a VM where a virus sample will run to detect the
> sample's behaviour  about every 120 seconds.
> For a long time, such as 5 days or 15 days, the xen server where the
> processes run will raise this error with a certain probability.
> Maybe it has something to do with the hypervisor's stability.

This is not a usual scenario. Sorry I don't know how to reproduce this.

But the code path in hypervisor for evtchn_alloc_unbound is quite short,
you may try adding some debug output along the path to see which step
fails then report back.


Wei.

BTW, it's needed to tell you my environment background;
I installed centos6.2 and then installed xen rpms from  http://xenbits.xen.org/people/mayoung/EL6.xen/.

At present, I'm not sure what function used to add the debug statement (is it printk?) and where to look for the debug log info (is it /var/log/message?)  .

The returned errno is from src/xen/common/event_channel.c
874-long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)                                                                                                                                                                          
 875{                                                                                                                                                                                                                                       
 876    long rc;                                                                                                                                                                                                                            
 877                                                                                                                                                                                                                                        
 878    switch ( cmd )                                                                                                                                                                                                                      
 879    {                                                                                                                                                                                                                                   
 880    case EVTCHNOP_alloc_unbound: {                                                                                                                                                                                                      
 881        struct evtchn_alloc_unbound alloc_unbound;                                                                                                                                                                                      
 882        if ( copy_from_guest(&alloc_unbound, arg, 1) != 0 )                                                                                                                                                                             
 883            return -EFAULT;                                                                                                                                                                                                             
 884        rc = evtchn_alloc_unbound(&alloc_unbound);         // only here returns -1(EPERM) ,  others return -EFAULT                                                                                                                                                                            
 885        if ( (rc == 0) && (copy_to_guest(arg, &alloc_unbound, 1) != 0) )                                                                                                                                                                
 886            rc = -EFAULT; /* Cleaning up here would be a mess! */                                                                                                                                                                       
 887        break;                                                                                                                                                                                                                          
 888    }           

 
Two statements below may affect the rc. 
124-static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)                                                                                                                                                                        
 125{                                                                                                                                                                                                                                       
 126    struct evtchn *chn;                                                                                                                                                                                                                 
 127    struct domain *d;                                                                                                                                                                                                                   
 128    int            port;                                                                                                                                                                                                                
 129    domid_t        dom = alloc->dom;                                                                                                                                                                                                    
 130    long           rc;                                                                                                                                                                                                                  
 131                                                                                                                                                                                                                                        
 132    rc = rcu_lock_target_domain_by_id(dom, &d);                                                                                                                                                                                         
 133    if ( rc )                                                                                                                                                                                                                           
 134        return rc;                                                                                                                                                                                                                      
 135                                                                                                                                                                                                                                        
 136    spin_lock(&d->event_lock);                                                                                                                                                                                                          
 137                                                                                                                                                                                                                                        
 138    if ( (port = get_free_port(d)) < 0 )                                                                                                                                                                                                
 139        ERROR_EXIT_DOM(port, d);                                                                                                                                                                                                        
 140    chn = evtchn_from_port(d, port);                                                                                                                                                                                                    
 141                                                                                                                                                                                                                                        
 142    rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom);                                                                                                                                                                                 
 143    if ( rc )                                                                                                                                                                                                                           
 144        goto out;                                                                                                                                                                                                                       
 145                                                                                                                                                                                                                                        
 146    chn->state = ECS_UNBOUND;                                                                                                                                                                                                           
 147    if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )                                                                                                                                                              
 148        chn->u.unbound.remote_domid = current->domain->domain_id;      
149                                                                                                                                                                                                                                        
 150    alloc->port = port;                                                                                                                                                                                                                 
 151                                                                                                                                                                                                                                        
 152 out:                                                                                                                                                                                                                                   
 153    spin_unlock(&d->event_lock);                                                                                                                                                                                                        
 154    rcu_unlock_domain(d);                                                                                                                                                                                                               
 155                                                                                                                                                                                                                                        
 156    return rc;                                                                                                                                                                                                                          
 157}

I looked into it again and found that it was caused probably by src/xen/common/domain.c:
 421-int rcu_lock_target_domain_by_id(domid_t dom, struct domain **d)                                                                                                                                                                       
 422{                                                                                                                                                                                                                                       
 423    if ( dom == DOMID_SELF )                                                                                                                                                                                                            
 424    {                                                                                                                                                                                                                                   
 425        *d = rcu_lock_current_domain();                                                                                                                                                                                                 
 426        return 0;                                                                                                                                                                                                                       
 427    }                                                                                                                                                                                                                                   
 428                                                                                                                                                                                                                                        
 429    if ( (*d = rcu_lock_domain_by_id(dom)) == NULL )                                                                                                                                                                                    
 430        return -ESRCH;                                                                                                                                                                                                                  
 431                                                                                                                                                                                                                                        
 432    if ( !IS_PRIV_FOR(current->domain, *d) )                                                                                                                                                                                            
 433    {                                                                                                                                                                                                                                   
 434        rcu_unlock_domain(*d);                                                                                                                                                                                                          
 435        return -EPERM;                                                                                                                                                                                                                  
 436    }                                                                                                                                                                                                                                   
 437                                                                                                                                                                                                                                        
 438    return 0;                                                                                                                                                                                                                           
 439}

the macro `IS_PRIV_FOR` is defined here src/xen/include/xen/sched.h:
638#define IS_PRIV_FOR(_d, _t) (IS_PRIV(_d) || ((_d)->target && (_d)->target == (_t))) 

I couldn't understand that what  IS_PRIV_FOR  means?!

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.