Statistics
| Branch: | Tag: | Revision:

root / lib / jstore.py @ 66e884e1

History | View | Annotate | Download (3.7 kB)

1
#
2
#
3

    
4
# Copyright (C) 2006, 2007 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Module implementing the job queue handling."""
23

    
24
import errno
25

    
26
from ganeti import constants
27
from ganeti import errors
28
from ganeti import runtime
29
from ganeti import utils
30

    
31

    
32
def _ReadNumericFile(file_name):
33
  """Reads a file containing a number.
34

35
  @rtype: None or int
36
  @return: None if file is not found, otherwise number
37

38
  """
39
  try:
40
    return int(utils.ReadFile(file_name))
41
  except EnvironmentError, err:
42
    if err.errno in (errno.ENOENT, ):
43
      return None
44
    raise
45

    
46

    
47
def ReadSerial():
48
  """Read the serial file.
49

50
  The queue should be locked while this function is called.
51

52
  """
53
  return _ReadNumericFile(constants.JOB_QUEUE_SERIAL_FILE)
54

    
55

    
56
def ReadVersion():
57
  """Read the queue version.
58

59
  The queue should be locked while this function is called.
60

61
  """
62
  return _ReadNumericFile(constants.JOB_QUEUE_VERSION_FILE)
63

    
64

    
65
def InitAndVerifyQueue(must_lock):
66
  """Open and lock job queue.
67

68
  If necessary, the queue is automatically initialized.
69

70
  @type must_lock: bool
71
  @param must_lock: Whether an exclusive lock must be held.
72
  @rtype: utils.FileLock
73
  @return: Lock object for the queue. This can be used to change the
74
           locking mode.
75

76
  """
77
  getents = runtime.GetEnts()
78

    
79
  # Lock queue
80
  queue_lock = utils.FileLock.Open(constants.JOB_QUEUE_LOCK_FILE)
81
  try:
82
    # The queue needs to be locked in exclusive mode to write to the serial and
83
    # version files.
84
    if must_lock:
85
      queue_lock.Exclusive(blocking=True)
86
      holding_lock = True
87
    else:
88
      try:
89
        queue_lock.Exclusive(blocking=False)
90
        holding_lock = True
91
      except errors.LockError:
92
        # Ignore errors and assume the process keeping the lock checked
93
        # everything.
94
        holding_lock = False
95

    
96
    if holding_lock:
97
      # Verify version
98
      version = ReadVersion()
99
      if version is None:
100
        # Write new version file
101
        utils.WriteFile(constants.JOB_QUEUE_VERSION_FILE,
102
                        uid=getents.masterd_uid, gid=getents.masterd_gid,
103
                        data="%s\n" % constants.JOB_QUEUE_VERSION)
104

    
105
        # Read again
106
        version = ReadVersion()
107

    
108
      if version != constants.JOB_QUEUE_VERSION:
109
        raise errors.JobQueueError("Found job queue version %s, expected %s",
110
                                   version, constants.JOB_QUEUE_VERSION)
111

    
112
      serial = ReadSerial()
113
      if serial is None:
114
        # Write new serial file
115
        utils.WriteFile(constants.JOB_QUEUE_SERIAL_FILE,
116
                        uid=getents.masterd_uid, gid=getents.masterd_gid,
117
                        data="%s\n" % 0)
118

    
119
        # Read again
120
        serial = ReadSerial()
121

    
122
      if serial is None:
123
        # There must be a serious problem
124
        raise errors.JobQueueError("Can't read/parse the job queue"
125
                                   " serial file")
126

    
127
      if not must_lock:
128
        # There's no need for more error handling. Closing the lock
129
        # file below in case of an error will unlock it anyway.
130
        queue_lock.Unlock()
131

    
132
  except:
133
    queue_lock.Close()
134
    raise
135

    
136
  return queue_lock