aboutsummaryrefslogtreecommitdiffstats
path: root/tools/python/xen/xend/XendVnet.py
blob: d95fd204aa39a4ed96d871bac97989b27ce4c3f3 (plain)
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
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>

"""Handler for vnet operations.
"""

from xen.util import Brctl

import sxp
import XendDB
from XendError import XendError
from XendLogging import log

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, config):
        self.config = config
        self.id = sxp.child_value(config, 'id')
        self.id = str(self.id)
        self.bridge = sxp.child_value(config, 'bridge')
        if not self.bridge:
            self.bridge = "vnet%s" % self.id
        self.vnetif = sxp.child_value(config, 'vnetif')
        if not self.vnetif:
            self.vnetif = "vnetif%s" % self.id

    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)
        return vnet_cmd(['vnet.del', self.id])

    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 = {}
        self.db = XendDB.XendDB(self.dbpath)
        vnets = self.db.fetchall("")
        for config in vnets.values():
            info = XendVnetInfo(config)
            self.vnet[info.id] = info
            try:
                info.configure()
            except XendError, ex:
                log.warning("Failed to configure vnet %s: %s", str(info.id), str(ex))

    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(config)
        self.vnet[info.id] = info
        self.db.save(info.id, info.sxpr())
        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]
            self.db.delete(id)
            info.delete()

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