[PATCH] common/options: Change drv struct to store drive index instead of device name.
                                
                                
                                
                                    
                                        by Richard W.M. Jones
                                    
                                
                                
                                        The device name is only used by guestfish (when using the -N option to
prepare drives).  We constructed the device name very naively,
basically ‘sprintf ("/dev/sd%c", next_drive)’.
This stores the device index instead, and only constructs the device
name in guestfish.  Also the device name is constructed properly using
guestfs_int_drive_name so it can cope with #drives > 26.
---
 align/scan.c             |  2 +-
 cat/cat.c                |  2 +-
 cat/filesystems.c        |  2 +-
 cat/log.c                |  2 +-
 cat/ls.c                 |  2 +-
 cat/tail.c               |  2 +-
 common/options/options.c | 30 +++++++++---------------------
 common/options/options.h | 20 ++++++++++----------
 df/main.c                |  2 +-
 diff/diff.c              |  4 ++--
 edit/edit.c              |  2 +-
 fish/fish.c              | 12 ++++++++----
 format/format.c          |  2 +-
 fuse/guestmount.c        |  2 +-
 inspector/inspector.c    |  2 +-
 rescue/rescue.c          |  3 +--
 rescue/suggest.c         |  2 +-
 17 files changed, 42 insertions(+), 51 deletions(-)
diff --git a/align/scan.c b/align/scan.c
index 7ae8adf..26f77fd 100644
--- a/align/scan.c
+++ b/align/scan.c
@@ -236,7 +236,7 @@ main (int argc, char *argv[])
       error (EXIT_FAILURE, 0, _("--uuid option cannot be used with -a or -d"));
 
     /* Add domains/drives from the command line (for a single guest). */
-    add_drives (drvs, 'a');
+    add_drives (drvs, 0);
 
     if (guestfs_launch (g) == -1)
       exit (EXIT_FAILURE);
diff --git a/cat/cat.c b/cat/cat.c
index 9fa8b4f..990fc90 100644
--- a/cat/cat.c
+++ b/cat/cat.c
@@ -236,7 +236,7 @@ main (int argc, char *argv[])
   }
 
   /* Add drives, inspect and mount. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
diff --git a/cat/filesystems.c b/cat/filesystems.c
index 3bedf88..39b8cc3 100644
--- a/cat/filesystems.c
+++ b/cat/filesystems.c
@@ -346,7 +346,7 @@ main (int argc, char *argv[])
   }
 
   /* Add drives. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
diff --git a/cat/log.c b/cat/log.c
index eca8459..d1d22a7 100644
--- a/cat/log.c
+++ b/cat/log.c
@@ -209,7 +209,7 @@ main (int argc, char *argv[])
   /* Add drives, inspect and mount.  Note that inspector is always true,
    * and there is no -m option.
    */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
diff --git a/cat/ls.c b/cat/ls.c
index 590e645..774cab5 100644
--- a/cat/ls.c
+++ b/cat/ls.c
@@ -359,7 +359,7 @@ main (int argc, char *argv[])
   }
 
   /* Add drives, inspect and mount. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
diff --git a/cat/tail.c b/cat/tail.c
index 0759c9d..2797b86 100644
--- a/cat/tail.c
+++ b/cat/tail.c
@@ -279,7 +279,7 @@ do_tail (int argc, char *argv[], /* list of files in the guest */
     int processed;
 
     /* Add drives, inspect and mount. */
-    add_drives (drvs, 'a');
+    add_drives (drvs, 0);
 
     if (guestfs_launch (g) == -1)
       return -1;
diff --git a/common/options/options.c b/common/options/options.c
index c9948d7..1965e1f 100644
--- a/common/options/options.c
+++ b/common/options/options.c
@@ -67,7 +67,6 @@ option_a (const char *arg, const char *format, struct drv **drvsp)
       error (EXIT_FAILURE, errno, "access: %s", uri.path);
 
     drv->type = drv_a;
-    drv->nr_drives = -1;
     drv->a.filename = uri.path;
     drv->a.format = format;
 
@@ -76,7 +75,6 @@ option_a (const char *arg, const char *format, struct drv **drvsp)
   else {
     /* Remote storage. */
     drv->type = drv_uri;
-    drv->nr_drives = -1;
     drv->uri.path = uri.path;
     drv->uri.protocol = uri.protocol;
     drv->uri.server = uri.server;
@@ -103,7 +101,6 @@ option_d (const char *arg, struct drv **drvsp)
     error (EXIT_FAILURE, errno, "calloc");
 
   drv->type = drv_d;
-  drv->nr_drives = -1;
   drv->d.guest = optarg;
 
   drv->next = *drvsp;
@@ -111,22 +108,15 @@ option_d (const char *arg, struct drv **drvsp)
 }
 
 char
-add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive)
+add_drives_handle (guestfs_h *g, struct drv *drv, size_t drive_index)
 {
   int r;
   struct guestfs_add_drive_opts_argv ad_optargs;
 
-  if (next_drive > 'z')
-    error (EXIT_FAILURE, 0, _("too many drives added on the command line"));
-
   if (drv) {
-    next_drive = add_drives (drv->next, next_drive);
+    drive_index = add_drives (drv->next, drive_index);
 
-    free (drv->device);
-    drv->device = NULL;
-
-    if (asprintf (&drv->device, "/dev/sd%c", next_drive) == -1)
-      error (EXIT_FAILURE, errno, "asprintf");
+    drv->drive_index = drive_index;
 
     switch (drv->type) {
     case drv_a:
@@ -153,7 +143,7 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive)
         exit (EXIT_FAILURE);
 
       drv->nr_drives = 1;
-      next_drive++;
+      drive_index++;
       break;
 
     case drv_uri:
@@ -186,7 +176,7 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive)
         exit (EXIT_FAILURE);
 
       drv->nr_drives = 1;
-      next_drive++;
+      drive_index++;
       break;
 
     case drv_d:
@@ -195,7 +185,7 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive)
         exit (EXIT_FAILURE);
 
       drv->nr_drives = r;
-      next_drive += r;
+      drive_index += r;
       break;
 
     case drv_N:
@@ -208,7 +198,7 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive)
         exit (EXIT_FAILURE);
 
       drv->nr_drives = 1;
-      next_drive++;
+      drive_index++;
       break;
 
     case drv_scratch:
@@ -218,7 +208,7 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive)
         exit (EXIT_FAILURE);
 
       drv->nr_drives = 1;
-      next_drive++;
+      drive_index++;
       break;
 
     default: /* keep GCC happy */
@@ -226,7 +216,7 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive)
     }
   }
 
-  return next_drive;
+  return drive_index;
 }
 
 static void display_mountpoints_on_failure (const char *mp_device, const char *user_supplied_options);
@@ -320,8 +310,6 @@ free_drives (struct drv *drv)
   if (!drv) return;
   free_drives (drv->next);
 
-  free (drv->device);
-
   switch (drv->type) {
   case drv_a:
     free (drv->a.filename);
diff --git a/common/options/options.h b/common/options/options.h
index 1598daf..7e4d269 100644
--- a/common/options/options.h
+++ b/common/options/options.h
@@ -43,14 +43,14 @@ extern int in_virt_rescue;
 struct drv {
   struct drv *next;
 
-  char *device;    /* Device name inside the appliance (eg. /dev/sda).
-                    * This is filled in when we add the drives in
-                    * add_drives.  Note that guests (-d option) may
-                    * have multiple drives, in which case this is the
-                    * first drive, and nr_drives is the number of
-                    * drives used.
-                    */
-  int nr_drives;   /* number of drives for this guest */
+  /* Drive index.  This is filled in by add_drives(). */
+  size_t drive_index;
+
+  /* Number of drives represented by this 'drv' struct.  For -d this
+   * can be != 1 because a guest can have more than one disk.  For
+   * others it is always 1.  This is filled in by add_drives().
+   */
+  size_t nr_drives;
 
   enum {
     drv_a,                      /* -a option (without URI) */
@@ -123,8 +123,8 @@ extern char *read_key (const char *param);
 /* in options.c */
 extern void option_a (const char *arg, const char *format, struct drv **drvsp);
 extern void option_d (const char *arg, struct drv **drvsp);
-extern char add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive);
-#define add_drives(drv, next_drive) add_drives_handle (g, drv, next_drive)
+extern char add_drives_handle (guestfs_h *g, struct drv *drv, size_t drive_index);
+#define add_drives(drv, drive_index) add_drives_handle (g, drv, drive_index)
 extern void mount_mps (struct mp *mp);
 extern void free_drives (struct drv *drv);
 extern void free_mps (struct mp *mp);
diff --git a/df/main.c b/df/main.c
index 19ae77a..1c8159d 100644
--- a/df/main.c
+++ b/df/main.c
@@ -278,7 +278,7 @@ main (int argc, char *argv[])
     CLEANUP_FREE char *name = NULL;
 
     /* Add domains/drives from the command line (for a single guest). */
-    add_drives (drvs, 'a');
+    add_drives (drvs, 0);
 
     if (guestfs_launch (g) == -1)
       exit (EXIT_FAILURE);
diff --git a/diff/diff.c b/diff/diff.c
index 92ebdf7..7effcba 100644
--- a/diff/diff.c
+++ b/diff/diff.c
@@ -362,7 +362,7 @@ main (int argc, char *argv[])
   unsigned errors = 0;
 
   /* Mount up first guest. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
@@ -373,7 +373,7 @@ main (int argc, char *argv[])
     errors++;
 
   /* Mount up second guest. */
-  add_drives_handle (g2, drvs2, 'a');
+  add_drives_handle (g2, drvs2, 0);
 
   if (guestfs_launch (g2) == -1)
     exit (EXIT_FAILURE);
diff --git a/edit/edit.c b/edit/edit.c
index a5ef7f9..6e608a8 100644
--- a/edit/edit.c
+++ b/edit/edit.c
@@ -261,7 +261,7 @@ main (int argc, char *argv[])
   }
 
   /* Add drives. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
diff --git a/fish/fish.c b/fish/fish.c
index c47576f..183c800 100644
--- a/fish/fish.c
+++ b/fish/fish.c
@@ -362,7 +362,6 @@ main (int argc, char *argv[])
       if (!drv)
         error (EXIT_FAILURE, errno, "calloc");
       drv->type = drv_N;
-      drv->nr_drives = -1;
       p = strchr (optarg, '=');
       if (p != NULL) {
         *p = '\0';
@@ -466,7 +465,7 @@ main (int argc, char *argv[])
   CHECK_OPTION_format_consumed;
 
   /* If we've got drives to add, add them now. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   /* If we've got mountpoints or prepared drives or -i option, we must
    * launch the guest and mount them.
@@ -586,8 +585,13 @@ prepare_drives (struct drv *drv)
 {
   if (drv) {
     prepare_drives (drv->next);
-    if (drv->type == drv_N)
-      prepare_drive (drv->N.filename, drv->N.data, drv->device);
+    if (drv->type == drv_N) {
+      char device[64];
+
+      strcpy (device, "/dev/sd");
+      guestfs_int_drive_name (drv->drive_index, &device[7]);
+      prepare_drive (drv->N.filename, drv->N.data, device);
+    }
   }
 }
 
diff --git a/format/format.c b/format/format.c
index 4e6ed26..ec6d33f 100644
--- a/format/format.c
+++ b/format/format.c
@@ -249,7 +249,7 @@ main (int argc, char *argv[])
     const char *wipefs[] = { "wipefs", NULL };
 
     /* Add domains/drives from the command line (for a single guest). */
-    add_drives (drvs, 'a');
+    add_drives (drvs, 0);
 
     if (guestfs_launch (g) == -1)
       exit (EXIT_FAILURE);
diff --git a/fuse/guestmount.c b/fuse/guestmount.c
index 98933bc..a711603 100644
--- a/fuse/guestmount.c
+++ b/fuse/guestmount.c
@@ -360,7 +360,7 @@ main (int argc, char *argv[])
     exit (EXIT_FAILURE);
 
   /* Do the guest drives and mountpoints. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
   if (inspector)
diff --git a/inspector/inspector.c b/inspector/inspector.c
index 1120776..3672e3c 100644
--- a/inspector/inspector.c
+++ b/inspector/inspector.c
@@ -271,7 +271,7 @@ main (int argc, char *argv[])
   /* Add drives, inspect and mount.  Note that inspector is always true,
    * and there is no -m option.
    */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
diff --git a/rescue/rescue.c b/rescue/rescue.c
index 19baa87..2bf5f26 100644
--- a/rescue/rescue.c
+++ b/rescue/rescue.c
@@ -372,7 +372,7 @@ main (int argc, char *argv[])
     exit (EXIT_FAILURE);
 
   /* Do the guest drives and mountpoints. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
   if (guestfs_launch (g) == -1)
     exit (EXIT_FAILURE);
   if (inspector)
@@ -673,7 +673,6 @@ add_scratch_disk (struct drv **drvs)
   if (!drv)
     error (EXIT_FAILURE, errno, "calloc");
   drv->type = drv_scratch;
-  drv->nr_drives = -1;
   drv->scratch.size = INT64_C (10737418240);
   drv->next = *drvs;
   *drvs = drv;
diff --git a/rescue/suggest.c b/rescue/suggest.c
index 78792f2..f1d0fb6 100644
--- a/rescue/suggest.c
+++ b/rescue/suggest.c
@@ -54,7 +54,7 @@ do_suggestion (struct drv *drvs)
   read_only = 1;
 
   /* Add drives. */
-  add_drives (drvs, 'a');
+  add_drives (drvs, 0);
 
   /* Free up data structures, no longer needed after this point. */
   free_drives (drvs);
-- 
2.9.3
                                
                         
                        
                                
                                8 years, 6 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [Bug #1406906] [PATCH] python: fix segmentation fault when setting non UTF-8 strings
                                
                                
                                
                                    
                                        by Matteo Cafasso
                                    
                                
                                
                                        When constructing the returned objects, check the return value of
Python APIs.
A RuntimeError will be raised on failure pointing to the problematic
entry and the field name.
Signed-off-by: Matteo Cafasso <noxdafox(a)gmail.com>
---
 generator/python.ml | 143 +++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 97 insertions(+), 46 deletions(-)
diff --git a/generator/python.ml b/generator/python.ml
index 11dc48102..7d86131b1 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -152,12 +152,20 @@ and generate_python_structs () =
     pr "PyObject *\n";
     pr "guestfs_int_py_put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
     pr "{\n";
-    pr "  PyObject *list;\n";
+    pr "  PyObject *list, *element;\n";
     pr "  size_t i;\n";
     pr "\n";
     pr "  list = PyList_New (%ss->len);\n" typ;
-    pr "  for (i = 0; i < %ss->len; ++i)\n" typ;
-    pr "    PyList_SetItem (list, i, guestfs_int_py_put_%s (&%ss->val[i]));\n" typ typ;
+    pr "  if (list == NULL) {\n";
+    pr "    PyErr_SetString (PyExc_RuntimeError, \"PyList_New\");\n";
+    pr "    return NULL;\n";
+    pr "  }\n";
+    pr "  for (i = 0; i < %ss->len; ++i) {\n" typ;
+    pr "    element = guestfs_int_py_put_%s (&%ss->val[i]);\n" typ typ;
+    pr "    if (element == NULL)\n";
+    pr "      return NULL;\n";
+    pr "    PyList_SetItem (list, i, element);\n";
+    pr "  }\n";
     pr "  return list;\n";
     pr "};\n";
     pr "#endif\n";
@@ -171,73 +179,112 @@ and generate_python_structs () =
       pr "PyObject *\n";
       pr "guestfs_int_py_put_%s (struct guestfs_%s *%s)\n" typ typ typ;
       pr "{\n";
-      pr "  PyObject *dict;\n";
+      pr "  PyObject *dict, *value;\n";
       pr "\n";
       pr "  dict = PyDict_New ();\n";
+      pr "  if (dict == NULL) {\n";
+      pr "    PyErr_SetString (PyExc_RuntimeError, \"PyDict_New\");\n";
+      pr "    return NULL;\n";
+      pr "  }\n";
       List.iter (
         function
         | name, FString ->
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
-            pr "                        PyString_FromString (%s->%s));\n"
-              typ name;
+            pr "  value = PyString_FromString (%s->%s);\n" typ name;
             pr "#else\n";
-            pr "                        PyUnicode_FromString (%s->%s));\n"
-              typ name;
-            pr "#endif\n"
+            pr "  value = PyUnicode_FromString (%s->%s);\n" typ name;
+            pr "#endif\n";
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
         | name, FBuffer ->
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
-            pr "                        PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
+            pr "  value = PyString_FromStringAndSize (%s->%s, %s->%s_len);\n"
               typ name typ name;
             pr "#else\n";
-            pr "                        PyBytes_FromStringAndSize (%s->%s, %s->%s_len));\n"
+            pr "  value = PyBytes_FromStringAndSize (%s->%s, %s->%s_len);\n"
               typ name typ name;
-            pr "#endif\n"
+            pr "#endif\n";
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
         | name, FUUID ->
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
-            pr "                        PyString_FromStringAndSize (%s->%s, 32));\n"
-              typ name;
+            pr "  value = PyString_FromStringAndSize (%s->%s, 32);\n" typ name;
             pr "#else\n";
-            pr "                        PyBytes_FromStringAndSize (%s->%s, 32));\n"
-              typ name;
-            pr "#endif\n"
+            pr "  value = PyBytes_FromStringAndSize (%s->%s, 32);\n" typ name;
+            pr "#endif\n";
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
         | name, (FBytes|FUInt64) ->
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
-            pr "                        PyLong_FromUnsignedLongLong (%s->%s));\n"
-              typ name
+            pr "  value = PyLong_FromUnsignedLongLong (%s->%s);\n" typ name;
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
         | name, FInt64 ->
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
-            pr "                        PyLong_FromLongLong (%s->%s));\n"
-              typ name
+            pr "  value = PyLong_FromLongLong (%s->%s);\n" typ name;
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
         | name, FUInt32 ->
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
-            pr "                        PyLong_FromUnsignedLong (%s->%s));\n"
-              typ name
+            pr "  value = PyLong_FromUnsignedLong (%s->%s);\n" typ name;
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
         | name, FInt32 ->
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
-            pr "                        PyLong_FromLong (%s->%s));\n"
-              typ name
+            pr "  value = PyLong_FromLong (%s->%s);\n" typ name;
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
         | name, FOptPercent ->
-            pr "  if (%s->%s >= 0)\n" typ name;
-            pr "    PyDict_SetItemString (dict, \"%s\",\n" name;
-            pr "                          PyFloat_FromDouble ((double) %s->%s));\n"
-              typ name;
+            pr "  if (%s->%s >= 0) {\n" typ name;
+            pr "    value = PyFloat_FromDouble ((double) %s->%s);\n" typ name;
+            pr "    if (value == NULL) {\n";
+            pr "      PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                       \"Error setting %s.%s\");\n" typ name;
+            pr "      return NULL;\n";
+            pr "    }\n";
+            pr "    PyDict_SetItemString (dict, \"%s\", value);\n" name;
+            pr "  }\n";
             pr "  else {\n";
             pr "    Py_INCREF (Py_None);\n";
             pr "    PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
             pr "  }\n"
         | name, FChar ->
             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
-            pr "                        PyString_FromStringAndSize (&%s->%s, 1));\n"
-              typ name;
+            pr "  value = PyString_FromStringAndSize (&%s->%s, 1);\n" typ name;
             pr "#else\n";
-            pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
-            pr "                        PyUnicode_FromStringAndSize (&%s->%s, 1));\n"
+            pr "  value = PyUnicode_FromStringAndSize (&%s->%s, 1);\n"
               typ name;
-            pr "#endif\n"
+            pr "#endif\n";
+            pr "  if (value == NULL) {\n";
+            pr "    PyErr_SetString (PyExc_RuntimeError,\n";
+            pr "                     \"Error setting %s.%s\");\n" typ name;
+            pr "    return NULL;\n";
+            pr "  }\n";
+            pr "  PyDict_SetItemString (dict, \"%s\", value);\n" name;
       ) cols;
       pr "  return dict;\n";
       pr "};\n";
@@ -517,16 +564,20 @@ and generate_python_actions actions () =
            pr "  if (py_r == NULL) goto out;\n";
        | RStringList _ ->
            pr "  py_r = guestfs_int_py_put_string_list (r);\n";
-           pr "  guestfs_int_free_string_list (r);\n"
+           pr "  guestfs_int_free_string_list (r);\n";
+           pr "  if (py_r == NULL) goto out;\n";
        | RStruct (_, typ) ->
            pr "  py_r = guestfs_int_py_put_%s (r);\n" typ;
-           pr "  guestfs_free_%s (r);\n" typ
+           pr "  guestfs_free_%s (r);\n" typ;
+           pr "  if (py_r == NULL) goto out;\n";
        | RStructList (_, typ) ->
            pr "  py_r = guestfs_int_py_put_%s_list (r);\n" typ;
-           pr "  guestfs_free_%s_list (r);\n" typ
+           pr "  guestfs_free_%s_list (r);\n" typ;
+           pr "  if (py_r == NULL) goto out;\n";
        | RHashtable n ->
            pr "  py_r = guestfs_int_py_put_table (r);\n";
-           pr "  guestfs_int_free_string_list (r);\n"
+           pr "  guestfs_int_free_string_list (r);\n";
+           pr "  if (py_r == NULL) goto out;\n";
        | RBufferOut _ ->
            pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
            pr "  py_r = PyString_FromStringAndSize (r, size);\n";
--
2.11.0
                                
                         
                        
                                
                                8 years, 6 months
                        
                        
                 
         
 
        
            
        
        
        
            
        
        
        
                
                        
                                
                                
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH] appliance: reorder the steps to search for appliance
                                
                                
                                
                                    
                                        by Pavel Butsykin
                                    
                                
                                
                                        The patch changes the order of the steps to search for fixed/supermin
appliance in accordance with documentation:
"If the fixed appliance is found, libguestfs skips supermin entirely
 and just runs qemu with the kernel, initrd and root disk from the
 fixed appliance."
Signed-off-by: Pavel Butsykin <pbutsykin(a)virtuozzo.com>
---
 lib/appliance.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/lib/appliance.c b/lib/appliance.c
index f12918573..06ee06f71 100644
--- a/lib/appliance.c
+++ b/lib/appliance.c
@@ -137,16 +137,6 @@ build_appliance (guestfs_h *g,
   CLEANUP_FREE char *path = NULL;
 
   /* Step (1). */
-  r = find_path (g, contains_supermin_appliance, NULL, &supermin_path);
-  if (r == -1)
-    return -1;
-
-  if (r == 1)
-    /* Step (2): build supermin appliance. */
-    return build_supermin_appliance (g, supermin_path,
-                                     kernel, initrd, appliance);
-
-  /* Step (3). */
   r = find_path (g, contains_fixed_appliance, NULL, &path);
   if (r == -1)
     return -1;
@@ -162,7 +152,7 @@ build_appliance (guestfs_h *g,
     return 0;
   }
 
-  /* Step (4). */
+  /* Step (2). */
   r = find_path (g, contains_old_style_appliance, NULL, &path);
   if (r == -1)
     return -1;
@@ -177,6 +167,16 @@ build_appliance (guestfs_h *g,
     return 0;
   }
 
+  /* Step (3). */
+  r = find_path (g, contains_supermin_appliance, NULL, &supermin_path);
+  if (r == -1)
+    return -1;
+
+  if (r == 1)
+    /* Step (4): build supermin appliance. */
+    return build_supermin_appliance (g, supermin_path,
+                                     kernel, initrd, appliance);
+
   error (g, _("cannot find any suitable libguestfs supermin, fixed or old-style appliance on LIBGUESTFS_PATH (search path: %s)"),
          g->path);
   return -1;
-- 
2.11.0
                                
                         
                        
                                
                                8 years, 6 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH v6 0/1] v2v bootloaders and augeas
                                
                                
                                
                                    
                                        by Pavel Butsykin
                                    
                                
                                
                                        I dare to raise an old topic :) It seemed to me that this patch already applied,
but recently discovered that it is not. 
As far as I understand we can't do a strict requirement to use Augeas >= 1.7.0.
But initially, the patch solves another problem. If we still can't do a hard
requirement for Augeas, let's use workaround proposed by Pino:
  let () =
    (* Apply the "grub" lens if it is not handling the file
     * already -- Augeas < 1.7.0 will error out otherwise.
     *)
    if g#aug_ls ("/files" ^ grub_config) = [||] then
      g#aug_transform "grub" grub_config in
As a temporary solution looks fine.
Pavel Butsykin (1):
  v2v: bootloaders: search grub config for all  distributions
 v2v/linux_bootloaders.ml | 86 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 31 deletions(-)
-- 
2.11.0
                                
                         
                        
                                
                                8 years, 6 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                         [PATCH v9 0/7] Feature: Yara file scanning
                                
                                
                                
                                    
                                        by Matteo Cafasso
                                    
                                
                                
                                        v9:
- fixes according to comments
Matteo Cafasso (7):
  daemon: expose file upload logic
  appliance: add yara dependency
  New API: yara_load
  New API: yara_destroy
  New API: internal_yara_scan
  New API: yara_scan
  yara_scan: added API tests
 appliance/packagelist.in                 |   4 +
 configure.ac                             |   1 +
 daemon/Makefile.am                       |   4 +-
 daemon/cleanups.c                        |   9 +
 daemon/cleanups.h                        |   2 +
 daemon/daemon.h                          |   3 +
 daemon/upload.c                          |  66 ++++---
 daemon/yara.c                            | 315 +++++++++++++++++++++++++++++++
 docs/guestfs-building.pod                |   4 +
 generator/Makefile.am                    |   3 +
 generator/actions.ml                     |   6 +-
 generator/actions_yara.ml                |  92 +++++++++
 generator/actions_yara.mli               |  22 +++
 generator/proc_nr.ml                     |   3 +
 generator/structs.ml                     |   9 +
 gobject/Makefile.inc                     |   2 +
 java/Makefile.inc                        |   1 +
 java/com/redhat/et/libguestfs/.gitignore |   1 +
 lib/MAX_PROC_NR                          |   2 +-
 lib/Makefile.am                          |   1 +
 lib/yara.c                               | 132 +++++++++++++
 m4/guestfs_daemon.m4                     |  14 ++
 tests/yara/Makefile.am                   |  26 +++
 tests/yara/test-yara-scan.sh             |  61 ++++++
 24 files changed, 750 insertions(+), 33 deletions(-)
 create mode 100644 daemon/yara.c
 create mode 100644 generator/actions_yara.ml
 create mode 100644 generator/actions_yara.mli
 create mode 100644 lib/yara.c
 create mode 100644 tests/yara/Makefile.am
 create mode 100755 tests/yara/test-yara-scan.sh
--
2.11.0
                                
                         
                        
                                
                                8 years, 6 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH] appliance: more reliable check for the supermin appliance
                                
                                
                                
                                    
                                        by Pavel Butsykin
                                    
                                
                                
                                        At least two control files (packages and base.tar.gz) are necessary for the
supermin appliance.
Signed-off-by: Pavel Butsykin <pbutsykin(a)virtuozzo.com>
---
 lib/appliance.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/appliance.c b/lib/appliance.c
index f12918573..5738e4e7f 100644
--- a/lib/appliance.c
+++ b/lib/appliance.c
@@ -199,7 +199,9 @@ contains_fixed_appliance (guestfs_h *g, const char *path, void *data)
 static int
 contains_supermin_appliance (guestfs_h *g, const char *path, void *data)
 {
-  return dir_contains_files (g, path, "supermin.d", NULL);
+  return dir_contains_files (g, path,
+                             "supermin.d/base.tar.gz",
+                             "supermin.d/packages", NULL);
 }
 
 /**
-- 
2.11.0
                                
                         
                        
                                
                                8 years, 6 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH] launch: Error if you try to launch with too many drives.
                                
                                
                                
                                    
                                        by Richard W.M. Jones
                                    
                                
                                
                                        In particular the virt-rescue --scratch option makes it very easy to
add huge numbers of drives.  Since the per-backend max_disks limit was
never checked anywhere you could get peculiar failures.  Now you'll
get a clear error message:
$ virt-rescue --scratch=256
libguestfs: error: too many drives have been added, the current backend only supports 255 drives
---
 lib/launch.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
diff --git a/lib/launch.c b/lib/launch.c
index 7f06c69..a977db5 100644
--- a/lib/launch.c
+++ b/lib/launch.c
@@ -55,12 +55,23 @@ static struct backend {
 int
 guestfs_impl_launch (guestfs_h *g)
 {
+  int r;
+
   /* Configured? */
   if (g->state != CONFIG) {
     error (g, _("the libguestfs handle has already been launched"));
     return -1;
   }
 
+  /* Too many drives? */
+  r = guestfs_max_disks (g);
+  if (r == -1)
+    return -1;
+  if (g->nr_drives > (size_t) r) {
+    error (g, _("too many drives have been added, the current backend only supports %d drives"), r);
+    return -1;
+  }
+
   /* Start the clock ... */
   gettimeofday (&g->launch_t, NULL);
   TRACE0 (launch_start);
-- 
2.9.3
                                
                         
                        
                                
                                8 years, 6 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH 1/2] v2v: -o glance: add property for UEFI firmware (RHBZ#1445659)
                                
                                
                                
                                    
                                        by Pino Toscano
                                    
                                
                                
                                        When converting a guest with UEFI firmware, set the also
hw_firmware_type=uefi property for all the disks of the guest, so Nova
can properly boot the guest.
---
 v2v/output_glance.ml | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
index b712d68..cfb19b4 100644
--- a/v2v/output_glance.ml
+++ b/v2v/output_glance.ml
@@ -41,7 +41,7 @@ object
 
   method as_options = "-o glance"
 
-  method supported_firmware = [ TargetBIOS ]
+  method supported_firmware = [ TargetBIOS; TargetUEFI ]
 
   method prepare_targets source targets =
     (* This does nothing useful except to check that the user has
@@ -66,9 +66,6 @@ object
     ) targets
 
   method create_metadata source targets _ guestcaps inspect target_firmware =
-    (* See #supported_firmware above. *)
-    assert (target_firmware = TargetBIOS);
-
     (* The first disk, assumed to be the system disk, will be called
      * "guestname".  Subsequent disks, assumed to be data disks,
      * will be called "guestname-disk2" etc.  The manual strongly
@@ -143,6 +140,11 @@ object
         (* XXX Neither memory balloon nor pvpanic are supported by
          * Glance at this time.
          *)
+        (match target_firmware with
+         | TargetBIOS -> ()
+         | TargetUEFI ->
+            push_back properties ("hw_firmware_type", "uefi")
+        );
 
         let properties =
           List.flatten (
-- 
2.9.3
                                
                         
                        
                                
                                8 years, 6 months