Commit 4d5fe81b authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Merge commit 'origin/next' into branch-2.1

* commit 'origin/next':
  Fix gnt-node modify online help
  Fix gnt-job info entry in gnt-job(8)
  locking: Don't swallow exceptions
  Add check for duplicate MACs in instance add
  scripts/gnt-node: fix a help string
  Optimise multi-job submit
  Extend gnt-debug with more debugging options

Conflicts:
	scripts/gnt-debug: Trivial
	scripts/gnt-node: Trivial
parents b757f830 b3fd544f
......@@ -5398,6 +5398,12 @@ class LUCreateInstance(LogicalUnit):
if not utils.IsValidMac(mac.lower()):
raise errors.OpPrereqError("Invalid MAC address specified: %s" %
mac)
else:
# or validate/reserve the current one
if self.cfg.IsMacInUse(mac):
raise errors.OpPrereqError("MAC address %s already in use"
" in cluster" % mac)
# bridge verification
bridge = nic.get("bridge", None)
link = nic.get("link", None)
......
......@@ -801,26 +801,31 @@ class JobQueue(object):
"""
return str(int(job_id) / JOBS_PER_ARCHIVE_DIRECTORY)
def _NewSerialUnlocked(self):
def _NewSerialsUnlocked(self, count):
"""Generates a new job identifier.
Job identifiers are unique during the lifetime of a cluster.
@type count: integer
@param count: how many serials to return
@rtype: str
@return: a string representing the job identifier.
"""
assert count > 0
# New number
serial = self._last_serial + 1
serial = self._last_serial + count
# Write to file
self._WriteAndReplicateFileUnlocked(constants.JOB_QUEUE_SERIAL_FILE,
"%s\n" % serial)
result = [self._FormatJobID(v)
for v in range(self._last_serial, serial + 1)]
# Keep it only if we were able to write the file
self._last_serial = serial
return self._FormatJobID(serial)
return result
@staticmethod
def _GetJobPath(job_id):
......@@ -984,12 +989,14 @@ class JobQueue(object):
return True
@_RequireOpenQueue
def _SubmitJobUnlocked(self, ops):
def _SubmitJobUnlocked(self, job_id, ops):
"""Create and store a new job.
This enters the job into our job queue and also puts it on the new
queue, in order for it to be picked up by the queue processors.
@type job_id: job ID
@param jod_id: the job ID for the new job
@type ops: list
@param ops: The list of OpCodes that will become the new job.
@rtype: job ID
......@@ -1011,8 +1018,6 @@ class JobQueue(object):
if size >= constants.JOB_QUEUE_SIZE_HARD_LIMIT:
raise errors.JobQueueFull()
# Get job identifier
job_id = self._NewSerialUnlocked()
job = _QueuedJob(self, job_id, ops)
# Write to disk
......@@ -1034,7 +1039,8 @@ class JobQueue(object):
@see: L{_SubmitJobUnlocked}
"""
return self._SubmitJobUnlocked(ops)
job_id = self._NewSerialsUnlocked(1)[0]
return self._SubmitJobUnlocked(job_id, ops)
@utils.LockedMethod
@_RequireOpenQueue
......@@ -1045,9 +1051,10 @@ class JobQueue(object):
"""
results = []
for ops in jobs:
all_job_ids = self._NewSerialsUnlocked(len(jobs))
for job_id, ops in zip(all_job_ids, jobs):
try:
data = self._SubmitJobUnlocked(ops)
data = self._SubmitJobUnlocked(job_id, ops)
status = True
except errors.GenericError, err:
data = str(err)
......
......@@ -498,7 +498,7 @@ class LockSet:
# Of course something is going to be really wrong, after this.
if lock._is_owned():
lock.release()
raise
raise
except:
# If something went wrong and we had the set-lock let's release it...
......
......@@ -145,7 +145,10 @@
<cmdsynopsis>
<command>submit-job</command>
<arg choice="opt">--verbose</arg>
<arg choice="opt">--timing-stats</arg>
<arg choice="opt">--job-repeat <option>N</option></arg>
<arg choice="opt">--op-repeat <option>N</option></arg>
<arg choice="req" rep="repeat">opcodes_file</arg>
</cmdsynopsis>
......@@ -156,6 +159,24 @@
command line.
</para>
<para>
The <option>verbose</option> option will job the job IDs of
the submitted jobs and the progress in waiting for the jobs;
the <option>timing-stats</option> option will show some
overall statistics with the number of total opcodes and jobs
submitted, and time time for each stage (submit, exec, total).
</para>
<para>
The <option>job-repeat</option> and <option>op-repeat</option>
options allow to submit multiple copies of the passed
arguments; the job repeat will cause N copies of each job
(input file) to be submitted (equivalent to passing the
arguments N times) while the op repeat will cause each job to
contain multiple copies of the opcodes (equivalent to each
file containing N copies of the opcodes).
</para>
</refsect2>
</refsect1>
......
......@@ -69,14 +69,39 @@ def GenericOpCodes(opts, args):
"""
cl = cli.GetClient()
jex = cli.JobExecutor(cl=cl)
for fname in args:
op_data = simplejson.loads(utils.ReadFile(fname))
op_list = [opcodes.OpCode.LoadOpCode(val) for val in op_data]
jex.QueueJob("file %s" % fname, *op_list)
jex = cli.JobExecutor(cl=cl, verbose=opts.verbose)
job_cnt = 0
op_cnt = 0
if opts.timing_stats:
ToStdout("Loading...")
for job_idx in range(opts.rep_job):
for fname in args:
op_data = simplejson.loads(utils.ReadFile(fname))
op_list = [opcodes.OpCode.LoadOpCode(val) for val in op_data]
op_list = op_list * opts.rep_op
jex.QueueJob("file %s/%d" % (fname, job_idx), *op_list)
op_cnt += len(op_list)
job_cnt += 1
if opts.timing_stats:
t1 = time.time()
ToStdout("Submitting...")
jex.SubmitPending()
if opts.timing_stats:
t2 = time.time()
ToStdout("Executing...")
jex.GetResults()
if opts.timing_stats:
t3 = time.time()
ToStdout("C:op %4d" % op_cnt)
ToStdout("C:job %4d" % job_cnt)
ToStdout("T:submit %4.4f" % (t2-t1))
ToStdout("T:exec %4.4f" % (t3-t2))
ToStdout("T:total %4.4f" % (t3-t1))
return 0
......@@ -139,7 +164,23 @@ commands = {
help="Select nodes to sleep on"),
],
"[opts...] <duration>", "Executes a TestDelay OpCode"),
'submit-job': (GenericOpCodes, [ArgFile(min=1)], [DEBUG_OPT],
'submit-job': (GenericOpCodes, [ArgFile(min=1)],
[DEBUG_OPT,
cli_option("--op-repeat", type="int", default="1",
dest="rep_op",
help="Repeat the opcode sequence this number"
" of times"),
cli_option("--job-repeat", type="int", default="1",
dest="rep_job",
help="Repeat the job this number"
" of times"),
cli_option("-v", "--verbose", default=False,
action="store_true",
help="Make the operation more verbose"),
cli_option("--timing-stats", default=False,
action="store_true",
help="Show timing stats"),
],
"<op_list_file...>", "Submits jobs built from json files"
" containing a list of serialized opcodes"),
'allocator': (TestAllocator, ARGS_ONE_INSTANCE,
......
......@@ -697,7 +697,7 @@ commands = {
choices=('yes', 'no'), default=None,
help="Set the drained flag on the node"),
],
"<node>", "Alters the parameters of a node"),
"<node_name>", "Alters the parameters of a node"),
'powercycle': (PowercycleNode, ARGS_ONE_NODE,
[DEBUG_OPT, FORCE_OPT, CONFIRM_OPT],
"<node_name>", "Tries to forcefully powercycle a node"),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment