Revision f78ede4e lib/config.py

b/lib/config.py
37 37
import re
38 38

  
39 39
from ganeti import errors
40
from ganeti import locking
40 41
from ganeti import logger
41 42
from ganeti import utils
42 43
from ganeti import constants
......
46 47
from ganeti import ssconf
47 48

  
48 49

  
50
_config_lock = locking.SharedLock()
51

  
52

  
49 53
def ValidateConfig():
50 54
  sstore = ssconf.SimpleStore()
51 55

  
......
62 66
  """
63 67
  def __init__(self, cfg_file=None, offline=False):
64 68
    self.write_count = 0
69
    self._lock = _config_lock
65 70
    self._config_data = None
66 71
    self._config_time = None
67 72
    self._config_size = None
......
86 91
    """
87 92
    return os.path.exists(constants.CLUSTER_CONF_FILE)
88 93

  
94
  @locking.ssynchronized(_config_lock, shared=1)
89 95
  def GenerateMAC(self):
90 96
    """Generate a MAC for an instance.
91 97

  
......
108 114
      raise errors.ConfigurationError("Can't generate unique MAC")
109 115
    return mac
110 116

  
117
  @locking.ssynchronized(_config_lock, shared=1)
111 118
  def IsMacInUse(self, mac):
112 119
    """Predicate: check if the specified MAC is in use in the Ganeti cluster.
113 120

  
......
131 138
        lvnames.update(lv_list)
132 139
    return lvnames
133 140

  
141
  @locking.ssynchronized(_config_lock, shared=1)
134 142
  def GenerateUniqueID(self, exceptions=None):
135 143
    """Generate an unique disk name.
136 144

  
......
177 185

  
178 186
    return result
179 187

  
188
  @locking.ssynchronized(_config_lock, shared=1)
180 189
  def VerifyConfig(self):
181 190
    """Stub verify function.
182 191
    """
......
202 211
          seen_macs.append(nic.mac)
203 212
    return result
204 213

  
205
  def SetDiskID(self, disk, node_name):
214
  def _UnlockedSetDiskID(self, disk, node_name):
206 215
    """Convert the unique ID to the ID needed on the target nodes.
207 216

  
208 217
    This is used only for drbd, which needs ip/port configuration.
......
211 220
    this helps when the only the top device is passed to the remote
212 221
    node.
213 222

  
223
    This function is for internal use, when the config lock is already held.
224

  
214 225
    """
215 226
    if disk.children:
216 227
      for child in disk.children:
217
        self.SetDiskID(child, node_name)
228
        self._UnlockedSetDiskID(child, node_name)
218 229

  
219 230
    if disk.logical_id is None and disk.physical_id is not None:
220 231
      return
......
223 234
      if node_name not in (pnode, snode):
224 235
        raise errors.ConfigurationError("DRBD device not knowing node %s" %
225 236
                                        node_name)
226
      pnode_info = self.GetNodeInfo(pnode)
227
      snode_info = self.GetNodeInfo(snode)
237
      pnode_info = self._UnlockedGetNodeInfo(pnode)
238
      snode_info = self._UnlockedGetNodeInfo(snode)
228 239
      if pnode_info is None or snode_info is None:
229 240
        raise errors.ConfigurationError("Can't find primary or secondary node"
230 241
                                        " for %s" % str(disk))
......
238 249
      disk.physical_id = disk.logical_id
239 250
    return
240 251

  
252
  @locking.ssynchronized(_config_lock)
253
  def SetDiskID(self, disk, node_name):
254
    """Convert the unique ID to the ID needed on the target nodes.
255

  
256
    This is used only for drbd, which needs ip/port configuration.
257

  
258
    The routine descends down and updates its children also, because
259
    this helps when the only the top device is passed to the remote
260
    node.
261

  
262
    """
263
    return self._UnlockedSetDiskID(disk, node_name)
264

  
265
  @locking.ssynchronized(_config_lock)
241 266
  def AddTcpUdpPort(self, port):
242 267
    """Adds a new port to the available port pool.
243 268

  
......
249 274
    self._config_data.cluster.tcpudp_port_pool.add(port)
250 275
    self._WriteConfig()
251 276

  
277
  @locking.ssynchronized(_config_lock, shared=1)
252 278
  def GetPortList(self):
253 279
    """Returns a copy of the current port list.
254 280

  
......
256 282
    self._OpenConfig()
257 283
    return self._config_data.cluster.tcpudp_port_pool.copy()
258 284

  
285
  @locking.ssynchronized(_config_lock)
259 286
  def AllocatePort(self):
260 287
    """Allocate a port.
261 288

  
......
280 307
    self._WriteConfig()
281 308
    return port
282 309

  
310
  @locking.ssynchronized(_config_lock, shared=1)
283 311
  def GetHostKey(self):
284 312
    """Return the rsa hostkey from the config.
285 313

  
......
290 318
    self._OpenConfig()
291 319
    return self._config_data.cluster.rsahostkeypub
292 320

  
321
  @locking.ssynchronized(_config_lock)
293 322
  def AddInstance(self, instance):
294 323
    """Add an instance to the config.
295 324

  
......
327 356
      instance.status = status
328 357
      self._WriteConfig()
329 358

  
359
  @locking.ssynchronized(_config_lock)
330 360
  def MarkInstanceUp(self, instance_name):
331 361
    """Mark the instance status to up in the config.
332 362

  
333 363
    """
334 364
    self._SetInstanceStatus(instance_name, "up")
335 365

  
366
  @locking.ssynchronized(_config_lock)
336 367
  def RemoveInstance(self, instance_name):
337 368
    """Remove the instance from the configuration.
338 369

  
......
344 375
    del self._config_data.instances[instance_name]
345 376
    self._WriteConfig()
346 377

  
378
  @locking.ssynchronized(_config_lock)
347 379
  def RenameInstance(self, old_name, new_name):
348 380
    """Rename an instance.
349 381

  
......
371 403
    self._config_data.instances[inst.name] = inst
372 404
    self._WriteConfig()
373 405

  
406
  @locking.ssynchronized(_config_lock)
374 407
  def MarkInstanceDown(self, instance_name):
375 408
    """Mark the status of an instance to down in the configuration.
376 409

  
377 410
    """
378 411
    self._SetInstanceStatus(instance_name, "down")
379 412

  
413
  @locking.ssynchronized(_config_lock, shared=1)
380 414
  def GetInstanceList(self):
381 415
    """Get the list of instances.
382 416

  
......
389 423

  
390 424
    return self._config_data.instances.keys()
391 425

  
426
  @locking.ssynchronized(_config_lock, shared=1)
392 427
  def ExpandInstanceName(self, short_name):
393 428
    """Attempt to expand an incomplete instance name.
394 429

  
......
398 433
    return utils.MatchNameComponent(short_name,
399 434
                                    self._config_data.instances.keys())
400 435

  
436
  @locking.ssynchronized(_config_lock, shared=1)
401 437
  def GetInstanceInfo(self, instance_name):
402 438
    """Returns informations about an instance.
403 439

  
......
418 454

  
419 455
    return self._config_data.instances[instance_name]
420 456

  
457
  @locking.ssynchronized(_config_lock)
421 458
  def AddNode(self, node):
422 459
    """Add a node to the configuration.
423 460

  
......
429 466
    self._config_data.nodes[node.name] = node
430 467
    self._WriteConfig()
431 468

  
469
  @locking.ssynchronized(_config_lock)
432 470
  def RemoveNode(self, node_name):
433 471
    """Remove a node from the configuration.
434 472

  
......
440 478
    del self._config_data.nodes[node_name]
441 479
    self._WriteConfig()
442 480

  
481
  @locking.ssynchronized(_config_lock, shared=1)
443 482
  def ExpandNodeName(self, short_name):
444 483
    """Attempt to expand an incomplete instance name.
445 484

  
......
449 488
    return utils.MatchNameComponent(short_name,
450 489
                                    self._config_data.nodes.keys())
451 490

  
452
  def GetNodeInfo(self, node_name):
491
  def _UnlockedGetNodeInfo(self, node_name):
453 492
    """Get the configuration of a node, as stored in the config.
454 493

  
494
    This function is for internal use, when the config lock is already held.
495

  
455 496
    Args: node: nodename (tuple) of the node
456 497

  
457 498
    Returns: the node object
......
464 505

  
465 506
    return self._config_data.nodes[node_name]
466 507

  
467
  def GetNodeList(self):
508

  
509
  @locking.ssynchronized(_config_lock, shared=1)
510
  def GetNodeInfo(self, node_name):
511
    """Get the configuration of a node, as stored in the config.
512

  
513
    Args: node: nodename (tuple) of the node
514

  
515
    Returns: the node object
516

  
517
    """
518
    return self._UnlockedGetNodeInfo(node_name)
519

  
520
  def _UnlockedGetNodeList(self):
468 521
    """Return the list of nodes which are in the configuration.
469 522

  
523
    This function is for internal use, when the config lock is already held.
524

  
470 525
    """
471 526
    self._OpenConfig()
472 527
    return self._config_data.nodes.keys()
473 528

  
529

  
530
  @locking.ssynchronized(_config_lock, shared=1)
531
  def GetNodeList(self):
532
    """Return the list of nodes which are in the configuration.
533

  
534
    """
535
    return self._UnlockedGetNodeList()
536

  
537
  @locking.ssynchronized(_config_lock, shared=1)
474 538
  def DumpConfig(self):
475 539
    """Return the entire configuration of the cluster.
476 540
    """
......
533 597
    if self._offline:
534 598
      return True
535 599
    bad = False
536
    nodelist = self.GetNodeList()
600
    nodelist = self._UnlockedGetNodeList()
537 601
    myhostname = self._my_hostname
538 602

  
539 603
    try:
......
579 643
    # and redistribute the config file
580 644
    self._DistributeConfig()
581 645

  
646
  @locking.ssynchronized(_config_lock)
582 647
  def InitConfig(self, node, primary_ip, secondary_ip,
583 648
                 hostkeypub, mac_prefix, vg_name, def_bridge):
584 649
    """Create the initial cluster configuration.
......
611 676
                                           cluster=globalconfig)
612 677
    self._WriteConfig()
613 678

  
679
  @locking.ssynchronized(_config_lock, shared=1)
614 680
  def GetVGName(self):
615 681
    """Return the volume group name.
616 682

  
......
618 684
    self._OpenConfig()
619 685
    return self._config_data.cluster.volume_group_name
620 686

  
687
  @locking.ssynchronized(_config_lock)
621 688
  def SetVGName(self, vg_name):
622 689
    """Set the volume group name.
623 690

  
......
626 693
    self._config_data.cluster.volume_group_name = vg_name
627 694
    self._WriteConfig()
628 695

  
696
  @locking.ssynchronized(_config_lock, shared=1)
629 697
  def GetDefBridge(self):
630 698
    """Return the default bridge.
631 699

  
......
633 701
    self._OpenConfig()
634 702
    return self._config_data.cluster.default_bridge
635 703

  
704
  @locking.ssynchronized(_config_lock, shared=1)
636 705
  def GetMACPrefix(self):
637 706
    """Return the mac prefix.
638 707

  
......
640 709
    self._OpenConfig()
641 710
    return self._config_data.cluster.mac_prefix
642 711

  
712
  @locking.ssynchronized(_config_lock, shared=1)
643 713
  def GetClusterInfo(self):
644 714
    """Returns informations about the cluster
645 715

  
......
651 721

  
652 722
    return self._config_data.cluster
653 723

  
724
  @locking.ssynchronized(_config_lock)
654 725
  def Update(self, target):
655 726
    """Notify function to be called after updates.
656 727

  

Also available in: Unified diff