launch: don't add a drive twice
authorWanlong Gao <gaowanlong@cn.fujitsu.com>
Mon, 9 Jan 2012 07:22:43 +0000 (15:22 +0800)
committerRichard W.M. Jones <rjones@redhat.com>
Mon, 9 Jan 2012 14:08:26 +0000 (14:08 +0000)
1. Change the g->path to restore a absolute path instead of the mixed.
2. Check that if the adding drive is duplicated with the added drive.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
RWMJ:

- Make sure abs_path is NULL before it is assigned, so freeing it
  will work along the error path.

- Fix the test which added /dev/null multiple times.

src/launch.c
tests/c-api/test-add-drive-opts.c

index 588ace1..8a64b5e 100644 (file)
@@ -285,6 +285,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename,
   char *format;
   char *iface;
   char *name;
   char *format;
   char *iface;
   char *name;
+  char *abs_path = NULL;
   int use_cache_off;
 
   if (strchr (filename, ',') != NULL) {
   int use_cache_off;
 
   if (strchr (filename, ',') != NULL) {
@@ -327,24 +328,33 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename,
     }
   }
 
     }
   }
 
+  abs_path = realpath (filename, NULL);
   struct drive **i = &(g->drives);
   struct drive **i = &(g->drives);
-  while (*i != NULL) i = &((*i)->next);
+  while (*i != NULL) {
+    if (STREQ((*i)->path, abs_path)) {
+      error (g, _("drive %s can't be added twice"), abs_path);
+      goto err_out;
+    }
+    i = &((*i)->next);
+  }
 
   *i = safe_malloc (g, sizeof (struct drive));
   (*i)->next = NULL;
 
   *i = safe_malloc (g, sizeof (struct drive));
   (*i)->next = NULL;
-  (*i)->path = safe_strdup (g, filename);
+  (*i)->path = safe_strdup (g, abs_path);
   (*i)->readonly = readonly;
   (*i)->format = format;
   (*i)->iface = iface;
   (*i)->name = name;
   (*i)->use_cache_off = use_cache_off;
 
   (*i)->readonly = readonly;
   (*i)->format = format;
   (*i)->iface = iface;
   (*i)->name = name;
   (*i)->use_cache_off = use_cache_off;
 
+  free (abs_path);
   return 0;
 
 err_out:
   free (format);
   free (iface);
   free (name);
   return 0;
 
 err_out:
   free (format);
   free (iface);
   free (name);
+  free (abs_path);
   return -1;
 }
 
   return -1;
 }
 
index 897c6fa..0494450 100644 (file)
@@ -30,6 +30,28 @@ main (int argc, char *argv[])
 {
   guestfs_h *g;
   int r;
 {
   guestfs_h *g;
   int r;
+  FILE *fp;
+
+  fp = fopen ("test1.img", "w");
+  if (fp == NULL) {
+    perror ("test1.img");
+    exit (EXIT_FAILURE);
+  }
+  fclose (fp);
+
+  fp = fopen ("test2.img", "w");
+  if (fp == NULL) {
+    perror ("test2.img");
+    exit (EXIT_FAILURE);
+  }
+  fclose (fp);
+
+  fp = fopen ("test3.img", "w");
+  if (fp == NULL) {
+    perror ("test3.img");
+    exit (EXIT_FAILURE);
+  }
+  fclose (fp);
 
   g = guestfs_create ();
   if (g == NULL) {
 
   g = guestfs_create ();
   if (g == NULL) {
@@ -37,15 +59,15 @@ main (int argc, char *argv[])
     exit (EXIT_FAILURE);
   }
 
     exit (EXIT_FAILURE);
   }
 
-  r = guestfs_add_drive_opts (g, "/dev/null", -1);
+  r = guestfs_add_drive_opts (g, "test1.img", -1);
   if (r == -1)
     exit (EXIT_FAILURE);
   if (r == -1)
     exit (EXIT_FAILURE);
-  r = guestfs_add_drive_opts (g, "/dev/null",
+  r = guestfs_add_drive_opts (g, "test2.img",
                               GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
                               -1);
   if (r == -1)
     exit (EXIT_FAILURE);
                               GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
                               -1);
   if (r == -1)
     exit (EXIT_FAILURE);
-  r = guestfs_add_drive_opts (g, "/dev/null",
+  r = guestfs_add_drive_opts (g, "test3.img",
                               GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
                               GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
                               -1);
                               GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
                               GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
                               -1);
@@ -54,5 +76,9 @@ main (int argc, char *argv[])
 
   guestfs_close (g);
 
 
   guestfs_close (g);
 
+  unlink ("test1.img");
+  unlink ("test2.img");
+  unlink ("test3.img");
+
   exit (EXIT_SUCCESS);
 }
   exit (EXIT_SUCCESS);
 }