Projet

Général

Profil

Révision b6c6a02e

IDb6c6a02efe0189c41baff4a79329563cc229c57c
Parent 54330cc3
Enfant e0df6aa7

Ajouté par Lars Kruse il y a plus de 7 ans

kvm_net: update VM name parsing

The old parser seemed to rely on a simple "-name foo" argument format of
kvm/qemu. The changed parser also accepts the following formats:
  • name,foo=bar,baz=bot
  • guest=name,foo=bar

Voir les différences:

plugins/libvirt/kvm_net
38 38
import sys
39 39

  
40 40

  
41
VM_NAME_REGEX = re.compile("^.*\x00-{arg_name}\x00(.+)\x00.*$")
42

  
43

  
41 44
def config(vm_names):
42 45
    """ Print the plugin's config
43 46

  
......
106 109

  
107 110
    @return a dictionnary of {pids : cleaned vm name}
108 111
    """
109
    vm_name_regex = re.compile(r"^.*-name\x00([a-zA-Z0-9.-_-]*)\x00\-.*$")
110 112
    result = {}
111 113
    for pid in pids:
112
        cmdline = open("/proc/%s/cmdline" % pid, "r")
113
        result[pid] = clean_vm_name(vm_name_regex.sub(r"\1", cmdline.readline()))
114
        name = None
115
        name_arg_values = _get_kvm_process_arguments(pid, "name")
116
        if name_arg_values:
117
            name_arg_value = name_arg_values[0]
118
            if "," in name_arg_value:
119
                # the modern parameter format may look like this:
120
                #    guest=foo,debug-threads=on
121
                for index, token in enumerate(name_arg_value.split(",")):
122
                    if (index == 0) and ("=" not in token):
123
                        # the first item may the plain name
124
                        name = value
125
                    elif "=" in token:
126
                        key, value = token.split("=", 1)
127
                        if key == "guest":
128
                            name = value
129
                    else:
130
                        # unknown format (no "mapping")
131
                        pass
132
            else:
133
                name = name_arg_value
134
        if name is None:
135
            print("Failed to parse VM name from commandline of process: {}"
136
                  .format(name_arg_values), file=sys.stderr)
137
        else:
138
            result[pid] = clean_vm_name(name)
114 139
    return result
115 140

  
116 141

  
......
125 150
    return mac
126 151

  
127 152

  
153
def _get_kvm_process_arguments(pid, arg_name):
154
    """ parse all value with the given name from the process identified by PID
155

  
156
    The result is a list of tokens, that follow this argument name. The result
157
    is empty in case of problems.
158
    """
159
    # the "cmdline" (e.g. /proc/self/cmdline) is a null-separated token list
160
    try:
161
        with open("/proc/%s/cmdline" % pid, "r") as cmdline_file:
162
            cmdline = cmdline_file.read()
163
    except IOError:
164
        # the process seems to have died meanwhile
165
        return []
166
    is_value = False
167
    result = []
168
    for arg_token in cmdline.split("\0"):
169
        if is_value:
170
            # the previous token was our argument name
171
            result.append(arg_token)
172
            is_value = False
173
        elif arg_token == "-{}".format(arg_name):
174
            # this is our argument name - we want to store the next value
175
            is_value = True
176
        else:
177
            # any other irrelevant value
178
            pass
179
    return result
180

  
181

  
128 182
def list_pids():
129 183
    """ Find the pid of kvm processes
130 184

  

Formats disponibles : Unified diff