From be47b66c3033105a2b880dbc10bfc2b163b7eafe Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Mon, 9 Jan 2012 15:22:43 +0800 Subject: [PATCH] launch: don't add a drive twice 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 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 | 14 ++++++++++++-- tests/c-api/test-add-drive-opts.c | 32 +++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/launch.c b/src/launch.c index 588ace1..8a64b5e 100644 --- a/src/launch.c +++ b/src/launch.c @@ -285,6 +285,7 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, char *format; char *iface; char *name; + char *abs_path = 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); - 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)->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; + free (abs_path); return 0; err_out: free (format); free (iface); free (name); + free (abs_path); return -1; } diff --git a/tests/c-api/test-add-drive-opts.c b/tests/c-api/test-add-drive-opts.c index 897c6fa..0494450 100644 --- a/tests/c-api/test-add-drive-opts.c +++ b/tests/c-api/test-add-drive-opts.c @@ -30,6 +30,28 @@ main (int argc, char *argv[]) { 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) { @@ -37,15 +59,15 @@ main (int argc, char *argv[]) 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); - 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); - 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); @@ -54,5 +76,9 @@ main (int argc, char *argv[]) guestfs_close (g); + unlink ("test1.img"); + unlink ("test2.img"); + unlink ("test3.img"); + exit (EXIT_SUCCESS); } -- 1.8.3.1