2014-01-30 15:06:37 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 Red Hat, Inc.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Author: Osier Yang <jyang@redhat.com>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "virscsi.h"
|
|
|
|
#include "testutils.h"
|
2014-03-29 18:58:32 +08:00
|
|
|
#include "virlog.h"
|
2014-01-30 15:06:37 +08:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
|
|
|
#define VIR_SCSI_DATA "/virscsidata"
|
|
|
|
|
2014-03-29 18:58:32 +08:00
|
|
|
VIR_LOG_INIT("tests.scsitest");
|
|
|
|
|
2014-01-30 15:06:37 +08:00
|
|
|
static const char *abs_top_srcdir;
|
2014-10-29 02:38:04 +08:00
|
|
|
static char *virscsi_prefix;
|
2014-01-30 15:06:37 +08:00
|
|
|
|
|
|
|
static int
|
|
|
|
test1(const void *data ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
char *name = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!(name = virSCSIDeviceGetDevName(virscsi_prefix,
|
|
|
|
"scsi_host1", 0, 0, 0)))
|
|
|
|
return -1;
|
|
|
|
|
2014-01-30 19:48:23 +08:00
|
|
|
if (STRNEQ(name, "sdh"))
|
2014-01-30 15:06:37 +08:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 14:53:44 +08:00
|
|
|
cleanup:
|
2014-01-30 15:06:37 +08:00
|
|
|
VIR_FREE(name);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Two test devices are used, one has address "0:0:0:0", the
|
|
|
|
* other has address "1:0:0:0", see "virscsidata/" for more
|
|
|
|
* details.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
test2(const void *data ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virSCSIDeviceListPtr list = NULL;
|
|
|
|
virSCSIDevicePtr dev = NULL;
|
|
|
|
virSCSIDevicePtr dev1 = NULL;
|
|
|
|
bool free_dev = true;
|
|
|
|
bool free_dev1 = true;
|
|
|
|
virSCSIDevicePtr tmp = NULL;
|
|
|
|
char *sgname = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
sgname = virSCSIDeviceGetSgName(virscsi_prefix,
|
|
|
|
"scsi_host1", 0, 0, 0);
|
|
|
|
|
2014-01-30 19:48:23 +08:00
|
|
|
if (!sgname || STRNEQ(sgname, "sg8"))
|
2014-01-30 15:06:37 +08:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(dev = virSCSIDeviceNew(virscsi_prefix, "scsi_host1",
|
|
|
|
0, 0, 0, false, true)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (STRNEQ_NULLABLE(virSCSIDeviceGetName(dev), "1:0:0:0") ||
|
|
|
|
virSCSIDeviceGetAdapter(dev) != 1 ||
|
|
|
|
virSCSIDeviceGetBus(dev) != 0 ||
|
|
|
|
virSCSIDeviceGetTarget(dev) != 0 ||
|
|
|
|
virSCSIDeviceGetUnit(dev) != 0 ||
|
|
|
|
virSCSIDeviceGetReadonly(dev) ||
|
|
|
|
!virSCSIDeviceGetShareable(dev))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!virSCSIDeviceIsAvailable(dev))
|
|
|
|
goto cleanup;
|
|
|
|
|
2014-03-01 14:28:56 +08:00
|
|
|
if (virSCSIDeviceSetUsedBy(dev, "QEMU", "fc18") < 0)
|
2014-01-30 15:06:37 +08:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virSCSIDeviceIsAvailable(dev))
|
|
|
|
goto cleanup;
|
|
|
|
|
2014-03-01 14:28:56 +08:00
|
|
|
if (virSCSIDeviceSetUsedBy(dev, "QEMU", "fc20") < 0)
|
2014-01-30 15:06:37 +08:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virSCSIDeviceIsAvailable(dev))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(list = virSCSIDeviceListNew()))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virSCSIDeviceListAdd(list, dev) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* virSCSIDeviceListDispose will take care of freeing
|
|
|
|
* the device.
|
|
|
|
*/
|
|
|
|
free_dev = false;
|
|
|
|
|
|
|
|
if (!virSCSIDeviceListFind(list, dev))
|
|
|
|
goto cleanup;
|
|
|
|
|
2014-03-01 14:28:56 +08:00
|
|
|
virSCSIDeviceListDel(list, dev, "QEMU", "fc20");
|
2014-01-30 15:06:37 +08:00
|
|
|
|
|
|
|
if (!virSCSIDeviceListFind(list, dev))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virSCSIDeviceIsAvailable(dev))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virSCSIDeviceListCount(list) != 1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(dev1 = virSCSIDeviceNew(virscsi_prefix, "scsi_host0",
|
|
|
|
0, 0, 0, true, false)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virSCSIDeviceListAdd(list, dev1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* virSCSIDeviceListDispose will take care of freeing
|
|
|
|
* the device.
|
|
|
|
*/
|
|
|
|
free_dev1 = false;
|
|
|
|
|
|
|
|
if (virSCSIDeviceListCount(list) != 2)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(tmp = virSCSIDeviceListSteal(list, dev1)))
|
|
|
|
goto cleanup;
|
|
|
|
virSCSIDeviceFree(tmp);
|
|
|
|
|
|
|
|
if (virSCSIDeviceListCount(list) != 1)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 14:53:44 +08:00
|
|
|
cleanup:
|
2014-01-30 15:06:37 +08:00
|
|
|
VIR_FREE(sgname);
|
|
|
|
if (free_dev)
|
|
|
|
virSCSIDeviceFree(dev);
|
|
|
|
if (free_dev1)
|
|
|
|
virSCSIDeviceFree(dev1);
|
|
|
|
virObjectUnref(list);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-03-29 18:58:32 +08:00
|
|
|
static int
|
|
|
|
create_symlink(const char *tmpdir, const char *src_name, const char *dst_name)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
char *src_path = NULL;
|
|
|
|
char *dst_path = NULL;
|
|
|
|
|
|
|
|
if (virAsprintf(&src_path, "%s/%s", virscsi_prefix, src_name) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virAsprintf(&dst_path, "%s/%s", tmpdir, dst_name) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (symlink(src_path, dst_path) < 0) {
|
|
|
|
VIR_WARN("Failed to create symlink '%s' to '%s'", src_path, dst_path);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(src_path);
|
|
|
|
VIR_FREE(dst_path);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-01-30 15:06:37 +08:00
|
|
|
static int
|
|
|
|
mymain(void)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
2014-03-29 18:58:32 +08:00
|
|
|
char *tmpdir = NULL;
|
|
|
|
char template[] = "/tmp/libvirt_XXXXXX";
|
2014-01-30 15:06:37 +08:00
|
|
|
|
|
|
|
abs_top_srcdir = getenv("abs_top_srcdir");
|
|
|
|
if (!abs_top_srcdir)
|
|
|
|
abs_top_srcdir = abs_srcdir "/..";
|
|
|
|
|
|
|
|
if (virAsprintf(&virscsi_prefix, "%s" VIR_SCSI_DATA, abs_srcdir) < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2014-03-29 18:58:32 +08:00
|
|
|
tmpdir = mkdtemp(template);
|
|
|
|
|
|
|
|
if (tmpdir == NULL) {
|
|
|
|
VIR_WARN("Failed to create temporary directory");
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2017-11-03 20:09:47 +08:00
|
|
|
#define CREATE_SYMLINK(src_name, dst_name) \
|
|
|
|
do { \
|
2014-03-29 18:58:32 +08:00
|
|
|
if (create_symlink(tmpdir, src_name, dst_name) < 0) { \
|
2017-11-03 20:09:47 +08:00
|
|
|
ret = -1; \
|
|
|
|
goto cleanup; \
|
|
|
|
} \
|
2014-03-29 18:58:32 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
CREATE_SYMLINK("0-0-0-0", "0:0:0:0");
|
|
|
|
CREATE_SYMLINK("1-0-0-0", "1:0:0:0");
|
|
|
|
CREATE_SYMLINK("sg0", "sg0");
|
|
|
|
CREATE_SYMLINK("sg8", "sg8");
|
|
|
|
|
|
|
|
VIR_FREE(virscsi_prefix);
|
|
|
|
|
|
|
|
if (VIR_STRDUP(virscsi_prefix, tmpdir) < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-05-26 23:01:50 +08:00
|
|
|
if (virTestRun("test1", test1, NULL) < 0)
|
2014-01-30 15:06:37 +08:00
|
|
|
ret = -1;
|
2016-05-26 23:01:50 +08:00
|
|
|
if (virTestRun("test2", test2, NULL) < 0)
|
2014-01-30 15:06:37 +08:00
|
|
|
ret = -1;
|
|
|
|
|
2014-03-25 14:53:44 +08:00
|
|
|
cleanup:
|
2015-09-16 04:33:36 +08:00
|
|
|
if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
|
2014-03-29 18:58:32 +08:00
|
|
|
virFileDeleteTree(tmpdir);
|
2014-01-30 15:06:37 +08:00
|
|
|
VIR_FREE(virscsi_prefix);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-03-29 22:45:42 +08:00
|
|
|
VIR_TEST_MAIN(mymain)
|