File: XendVnet.py

package info (click to toggle)
xen-3.0 3.0.3-0-2
  • links: PTS
  • area: main
  • in suites: etch-m68k
  • size: 31,772 kB
  • ctags: 70,362
  • sloc: ansic: 417,153; python: 28,855; asm: 23,892; sh: 5,157; makefile: 4,830; objc: 613; perl: 372; xml: 351
file content (181 lines) | stat: -rw-r--r-- 5,488 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================

"""Handler for vnet operations.
"""

from xen.util import Brctl
from xen.xend import sxp
from xen.xend.XendError import XendError
from xen.xend.XendLogging import log
from xen.xend.xenstore.xstransact import xstransact


def vnet_cmd(cmd):
    out = None
    try:
        try:
            out = file("/proc/vnet/policy", "wb")
            sxp.show(cmd, out)
        except IOError, ex:
            raise XendError(str(ex))
    finally:
        if out: out.close()

class XendVnetInfo:
    
    vifctl_ops = {'up': 'vif.add', 'down': 'vif.del'}

    def __init__(self, dbpath, config=None):
        if config:
            self.id = str(sxp.child_value(config, 'id'))
            self.dbid = self.id.replace(':', '-')
            self.dbpath = dbpath + '/' + self.dbid
            self.config = config
        else:
            self.dbpath = dbpath
            self.importFromDB()
            
        self.bridge = sxp.child_value(self.config, 'bridge')
        if not self.bridge:
            self.bridge = "vnet%s" % self.id
        self.vnetif = sxp.child_value(self.config, 'vnetif')
        if not self.vnetif:
            self.vnetif = "vnif%s" % self.id


    def exportToDB(self, save=False, sync=False):
        to_store = {
            'id' : self.id,
            'dbid' : self.dbid,
            'config' : sxp.to_string(self.config)
            }
        xstransact.Write(self.dbpath, to_store)


    def importFromDB(self):
        (self.id, self.dbid, c) = xstransact.Gather(self.dbpath,
                                                    ('id', str),
                                                    ('dbid', str),
                                                    ('config', str))
        self.config = sxp.from_string(c)


    def sxpr(self):
        return self.config

    def configure(self):
        log.info("Configuring vnet %s", self.id)
        val = vnet_cmd(['vnet.add'] + sxp.children(self.config))
        Brctl.bridge_create(self.bridge)
        Brctl.vif_bridge_add({'bridge': self.bridge, 'vif': self.vnetif})
        return val
        
    def delete(self):
        log.info("Deleting vnet %s", self.id)
        Brctl.vif_bridge_rem({'bridge': self.bridge, 'vif': self.vnetif})
        Brctl.bridge_del(self.bridge)
        val = vnet_cmd(['vnet.del', self.id])
        xstransact.Remove(self.dbpath)
        return val

    def vifctl(self, op, vif, vmac):
        try:
            fn = self.vifctl_ops[op]
            return vnet_cmd([fn, ['vnet', self.id], ['vif', vif], ['vmac', vmac]])
        except XendError:
            log.warning("vifctl failed: op=%s vif=%s mac=%s", op, vif, vmac)

class XendVnet:
    """Index of all vnets. Singleton.
    """

    dbpath = "/vnet"

    def __init__(self):
        # Table of vnet info indexed by vnet id.
        self.vnet = {}
        listing = xstransact.List(self.dbpath)
        for entry in listing:
            try:
                info = XendVnetInfo(self.dbpath + '/' + entry)
                self.vnet[info.id] = info
                info.configure()
            except XendError, ex:
                log.warning("Failed to configure vnet %s: %s", str(info.id), str(ex))
            except Exception, ex:
                log.exception("Vnet error")
                xstransact.Remove(self.dbpath + '/' + entry)

    def vnet_of_bridge(self, bridge):
        """Get the vnet for a bridge (if any).

        @param bridge: bridge name
        @return vnet or None
        """
        for v in self.vnet.values():
            if v.bridge == bridge:
                return v
        else:
            return None

    def vnet_ls(self):
        """List all vnet ids.
        """
        return self.vnet.keys()

    def vnets(self):
        """List all vnets.
        """
        return self.vnet.values()

    def vnet_get(self, id):
        """Get a vnet.

        @param id vnet id
        """
        id = str(id)
        return self.vnet.get(id)

    def vnet_create(self, config):
        """Create a vnet.

        @param config: config
        """
        info = XendVnetInfo(self.dbpath, config=config)
        self.vnet[info.id] = info
        info.exportToDB()
        info.configure()

    def vnet_delete(self, id):
        """Delete a vnet.

        @param id: vnet id
        """
        info = self.vnet_get(id)
        if info:
            del self.vnet[id]
            info.delete()

def instance():
    global inst
    try:
        inst
    except:
        inst = XendVnet()
    return inst