[Kimchi-devel] [PATCH v3][Kimchi 1/3] Add function 'get_next_clone_name'

Rodrigo Trujillo rodrigo.trujillo at linux.vnet.ibm.com
Tue Mar 15 17:51:10 UTC 2016


This patch moves the function 'get_next_clone_name' from Wok to Kimchi.

The function adds, originally, an incremental number in each clone name,
however this approach causes a race condiction if Kimchi tries to clone
guest multiple times, sending multiple request at once.
If clone requests are done so fast, it is possible that the plugin does
not send all resource names in all_names parameter, then the function is
going to select the same name for 2 or more clones, which is going to
cause errors.

To avoid this problem, it is better to use timestamps in the clones
names instead of incremental numbers. Then it guarantees names will
be unique. Supporting timestamps in microsecond precision, avoids this
type of error.
New clone name will be "basename-clone-timestamp-name-suffix".

Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo at linux.vnet.ibm.com>
---
 utils.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/utils.py b/utils.py
index 61b0a7f..eae16d5 100644
--- a/utils.py
+++ b/utils.py
@@ -23,6 +23,7 @@ import json
 import os
 import re
 import sqlite3
+import time
 import urllib2
 from httplib import HTTPConnection, HTTPException
 from urlparse import urlparse
@@ -208,3 +209,52 @@ def upgrade_objectstore_memory():
         if total > 0:
             wok_log.info(
                 "%d 'template' memory entries upgraded in objectstore.", total)
+
+
+def get_next_clone_name(all_names, basename, name_suffix='', ts=False):
+    """Find the next available name for a cloned resource.
+
+    If any resource named "<basename>-clone-<number><name_suffix>" is found
+    in "all_names", use the maximum "number" + 1; else, use 1.
+
+    Arguments:
+    all_names -- All existing names for the resource type. This list will
+        be used to make sure the new name won't conflict with
+        existing names.
+    basename -- The name of the original resource.
+    name_suffix -- The resource name suffix (optional). This parameter
+        exist so that a resource named "foo.img" gets the name
+        "foo-clone-1.img" instead of "foo.img-clone-1". If this parameter
+        is used, the suffix should not be present in "basename".
+    ts -- use timestamp, instead of incremental numbers
+
+    Return:
+    A UTF-8 string in the format "<basename>-clone-<number><name_suffix>".
+    """
+    re_group_num = 'num'
+
+    # Use timestamps or increase clone number
+    if ts:
+        # Microsecond precision
+        ts_suffix = int(time.time() * 1000000)
+        new_name = u'%s-clone-%d' % (basename, ts_suffix)
+    else:
+        re_expr = u'%s-clone-(?P<%s>\d+)' % (basename, re_group_num)
+        if name_suffix != '':
+            re_expr = u'%s%s' % (re_expr, name_suffix)
+
+        max_num = 0
+        re_compiled = re.compile(re_expr)
+
+        for n in all_names:
+            match = re_compiled.match(n)
+            if match is not None:
+                max_num = max(max_num, int(match.group(re_group_num)))
+
+        # increments the maximum "clone number" found
+        new_name = u'%s-clone-%d' % (basename, max_num + 1)
+
+    if name_suffix != '':
+        new_name = new_name + name_suffix
+
+    return new_name
-- 
2.1.0




More information about the Kimchi-devel mailing list