示例#1
0
文件: main.c 项目: kyokuki/whatAmessy
int automatedTest(int argc, char* argv[])
{
  CU_BOOL Run = CU_FALSE ;

  setvbuf(stdout, NULL, _IONBF, 0);

  if (argc > 1) {
    if (!strcmp("-i", argv[1])) {
      Run = CU_TRUE ;
      CU_set_error_action(CUEA_IGNORE);
    }
    else if (!strcmp("-f", argv[1])) {
      Run = CU_TRUE ;
      CU_set_error_action(CUEA_FAIL);
    }
    else if (!strcmp("-A", argv[1])) {
      Run = CU_TRUE ;
      CU_set_error_action(CUEA_ABORT);
    }
//    else if (!strcmp("-e", argv[1])) {
//      print_example_results();
//    }
    else {
      printf("\nUsage:  AutomatedTest [option]\n\n"
               "        Options: -i  Run, ignoring framework errors [default].\n"
               "                 -f  Run, failing on framework error.\n"
               "                 -A  Run, aborting on framework error.\n"
//               "                 -e  Print expected test results and exit.\n"
               "                 -h  Print this message.\n\n");
    }
  }
  else {
    Run = CU_TRUE;
    CU_set_error_action(CUEA_IGNORE);
  }

  if (CU_TRUE == Run) {
    if (CU_initialize_registry()) {
      printf("\nInitialization of Test Registry failed.");
    }
    else {
      AddTests();
      CU_set_output_filename("TestAutomated");
      CU_list_tests_to_file();
      CU_automated_run_tests();
      CU_cleanup_registry();
    }
  }

  return 0;
}
示例#2
0
文件: jotto.c 项目: dblack/cjotto
int main() {
    CU_BasicRunMode mode = CU_BRM_VERBOSE;
    CU_ErrorAction error_action = CUEA_IGNORE;
  
    CU_ErrorCode cue = CU_initialize_registry();
    if (cue != CUE_SUCCESS) { 
	printf("ERROR in CU_initialize_registry\n");
	return;
    }
    CU_basic_set_mode(mode);
    CU_set_error_action(error_action);
  
    CU_pSuite hitCounting, wordAdding, wordChomping, wordChecking;

    hitCounting = CU_add_suite("Hit counting", my_suite_init, my_suite_clean);
    wordAdding = CU_add_suite("Word adding", my_suite_init, my_suite_clean);
    wordChecking = CU_add_suite("Word checking", my_suite_init, my_suite_clean);

    CU_ADD_TEST(hitCounting, test_5_hits);  
    CU_ADD_TEST(hitCounting, test_1_hits);  
    CU_ADD_TEST(hitCounting, test_no_hits);  
    CU_ADD_TEST(hitCounting, test_hits_out_of_order_do_not_count);


    CU_ADD_TEST(wordChecking, test_check_for_word_in_jdict);
    CU_ADD_TEST(wordChecking, test_winnowing_jdict);
  
    CU_basic_run_tests();
    CU_cleanup_registry();
}
示例#3
0
文件: main.c 项目: jjgreen/pia
int main(void)
{
  CU_BasicRunMode mode = CU_BRM_VERBOSE;
  CU_ErrorAction error_action = CUEA_IGNORE;
  setvbuf(stdout, NULL, _IONBF, 0);

  if (CU_initialize_registry())
    {
      fprintf(stderr,"failed to initialise registry\n");
      return EXIT_FAILURE;
    }

  tests_load();
  CU_basic_set_mode(mode);
  CU_set_error_action(error_action);

  int
    status = CU_basic_run_tests(),
    nfail = CU_get_number_of_failures();

  CU_cleanup_registry();
  printf("\nSuite returned %d.\n", status);

  return (nfail > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
示例#4
0
/*
 * Register test suites to be run via odp_cunit_run()
 */
int odp_cunit_register(odp_suiteinfo_t testsuites[])
{
    /* call test executable init hook, if any */
    if (global_init_term.global_init_ptr) {
        if ((*global_init_term.global_init_ptr)(&instance) == 0) {
            /* After ODP initialization, set main thread's
             * CPU affinity to the 1st available control CPU core
             */
            int cpu = 0;
            odp_cpumask_t cpuset;

            odp_cpumask_zero(&cpuset);
            if (odp_cpumask_default_control(&cpuset, 1) == 1) {
                cpu = odp_cpumask_first(&cpuset);
                odph_odpthread_setaffinity(cpu);
            }
        } else {
            /* ODP initialization failed */
            return -1;
        }
    }

    CU_set_error_action(CUEA_ABORT);

    CU_initialize_registry();
    global_testsuites = testsuites;
    cunit_register_suites(testsuites);
    CU_set_fail_on_inactive(CU_FALSE);

    return 0;
}
示例#5
0
int main(char** args) {

  // En cas de problème de la librairie, le programme de test s'arrete et affiche un message (par exemple : memory allocation failed).
  CU_set_error_action(CUEA_ABORT) ;

  // Initialisation
  printf("Initialisation des tests.\n") ;
  CU_initialize_registry() ;
  init_suites() ;
  
  // Lancement
  printf("Lancement des tests.\n") ;

  // Variante 1 : fabriquer un fichier XML
  CU_automated_run_tests() ;
  printf("Pour observer les resultats, ouvrir le fichier .xml dans firefox\n") ;
  printf("Copier le fichier de style dans le meme repertoire : \n") ;
  printf("cp /usr/local/share/CUnit/CUnit-Run.xsl .\n\n") ;
  
  // Variante 2 : interface interactive dans le terminal.
  //CU_curses_run_tests() ;
  CU_basic_run_tests();
  // Nettoyage final
  CU_cleanup_registry() ;
  
}
示例#6
0
int main(int argc, char **argv) {
	// use CUnit test framework
	CU_pSuite pSuite = NULL;

	// initialize the CUnit test registry
   if (CUE_SUCCESS != CU_initialize_registry())
      return CU_get_error();

	// add a suite to the registry 
   pSuite = CU_add_suite("Header", NULL, NULL);
   if(!pSuite) {
      CU_cleanup_registry();
      return CU_get_error();
   }

	// add the tests to the suite
   if(!CU_add_test(pSuite, "First header byte construction", testHeaderFirstByteConstruction)) {
      CU_cleanup_registry();
      return CU_get_error();
	}

   if(!CU_add_test(pSuite, "Method codes", testMethodCodes)) {
      CU_cleanup_registry();
      return CU_get_error();
   }

   if(!CU_add_test(pSuite, "Message ID", testMessageID)) {
      CU_cleanup_registry();
      return CU_get_error();
   }

   if(!CU_add_test(pSuite, "Token insertion", testTokenInsertion)) {
      CU_cleanup_registry();
      return CU_get_error();
   }

   if(!CU_add_test(pSuite, "Option insertion", testOptionInsertion)) {
      CU_cleanup_registry();
      return CU_get_error();
   }

   if(!CU_add_test(pSuite, "URI setting", testURISetting)) {
      CU_cleanup_registry();
      return CU_get_error();
   }

	CU_pTest payloadTest = CU_add_test(pSuite, "Payload setting", testPayload);
   if(!payloadTest) {
      CU_cleanup_registry();
      return CU_get_error();
   }

   // Run all tests using the CUnit Basic interface
   CU_basic_set_mode(CU_BRM_VERBOSE);
	CU_set_error_action(CUEA_ABORT);
   CU_basic_run_tests();
   CU_cleanup_registry();
	//optionInsertionTest();
   return CU_get_error();
}
示例#7
0
int main(int argc, char *argv[])
{
  int basic;
  int console;
  int automated;

  /* parse the command line options */
  while ((c = getopt(argc, argv, "abc")) != -1)
  {
    switch (c)
    {
      case 'a': /* basic mode */
        basic = 1;
        break;
      case 'b': /* basic mode */
        basic = 1;
        break;
      case 'c': /* run from command line */
        console = 1;
        break;
      default: /* error, print usage */
        usage(argv[0]);
        return -1;
    }
  }

  if (CU_initialize_registry())
  {

    fprintf(stderr, "\nInitialization of Test Registry failed.\n");
    exit(EXIT_FAILURE);
  }
  else
  {
    AddTests();

    // set up the run mode and run the tests
    if (automated)
    {
      CU_set_output_filename("TestOutput.xml");
      CU_list_tests_to_file();
      CU_automated_run_tests();
    }
    else if (basic)
    {
      CU_BasicRunMode mode = CU_BRM_VERBOSE;
      CU_ErrorAction error_action = CUEA_IGNORE;
      CU_basic_set_mode(mode);
      CU_set_error_action(error_action);
      CU_basic_run_tests();
    }
    else if (console)
    {
      CU_console_run_tests();
    }
    CU_cleanup_registry();
  }
  return 0;
}
示例#8
0
文件: CUError.c 项目: GameCTO/CUnit
void test_cunit_CUError(void)
{
  CU_ErrorCode old_err = CU_get_error();
  CU_ErrorAction old_action = CU_get_error_action();

  test_cunit_start_tests("CUError.c");

  /* CU_set_error() & CU_get_error() */
  CU_set_error(CUE_NOMEMORY);
  TEST(CU_get_error() != CUE_SUCCESS);
  TEST(CU_get_error() == CUE_NOMEMORY);

  CU_set_error(CUE_NOREGISTRY);
  TEST(CU_get_error() != CUE_SUCCESS);
  TEST(CU_get_error() == CUE_NOREGISTRY);

  /* CU_get_error_msg() */
  CU_set_error(CUE_SUCCESS);
  TEST(!strcmp(CU_get_error_msg(), get_error_desc(CUE_SUCCESS)));

  CU_set_error(CUE_NOTEST);
  TEST(!strcmp(CU_get_error_msg(), get_error_desc(CUE_NOTEST)));

  CU_set_error(CUE_NOMEMORY);
  TEST(!strcmp(CU_get_error_msg(), get_error_desc(CUE_NOMEMORY)));
  TEST(strcmp(CU_get_error_msg(), get_error_desc(CUE_SCLEAN_FAILED)));

  TEST(!strcmp(get_error_desc(100), "Undefined Error"));

  /* CU_set_error_action() & CU_get_error_action() */
  CU_set_error_action(CUEA_FAIL);
  TEST(CU_get_error_action() != CUEA_IGNORE);
  TEST(CU_get_error_action() == CUEA_FAIL);
  TEST(CU_get_error_action() != CUEA_ABORT);

  CU_set_error_action(CUEA_ABORT);
  TEST(CU_get_error_action() != CUEA_IGNORE);
  TEST(CU_get_error_action() != CUEA_FAIL);
  TEST(CU_get_error_action() == CUEA_ABORT);

  /* reset  values */
  CU_set_error(old_err);
  CU_set_error_action(old_action);

  test_cunit_end_tests();
}
示例#9
0
int main(int argc, char* argv[])
{
  CU_BOOL Run = CU_FALSE ;

  setvbuf(stdout, NULL, _IONBF, 0);

  if (argc > 1) {
    if (!strcmp("-i", argv[1])) {
      Run = CU_TRUE ;
      CU_set_error_action(CUEA_IGNORE);
    }
    else if (!strcmp("-f", argv[1])) {
      Run = CU_TRUE ;
      CU_set_error_action(CUEA_FAIL);
    }
    else if (!strcmp("-A", argv[1])) {
      Run = CU_TRUE ;
      CU_set_error_action(CUEA_ABORT);
    }
    else {
      printf("\nUsage:  ConsoleTest [option]\n\n"
               "Options:   -i   Run, ignoring framework errors [default].\n"
               "           -f   Run, failing on framework error.\n"
               "           -A   run, aborting on framework error.\n"
               "           -h   Print this message.\n\n");
    }
  }
  else {
    Run = CU_TRUE;
    CU_set_error_action(CUEA_IGNORE);
  }

  if (CU_TRUE == Run) {
    if (CU_initialize_registry()) {
      printf("\nInitialization of Test Registry failed.");
    }
    else {
      //AddTests();
      AddEglTests();
      CU_console_run_tests();
      CU_cleanup_registry();
    }
  }

  return 0;
}
示例#10
0
文件: main.c 项目: kyokuki/whatAmessy
int basicTest(int argc, char* argv[])
{
  CU_BasicRunMode mode = CU_BRM_VERBOSE;
  CU_ErrorAction error_action = CUEA_IGNORE;
  int i;

  setvbuf(stdout, NULL, _IONBF, 0);

  for (i=1 ; i<argc ; i++) {
    if (!strcmp("-i", argv[i])) {
      error_action = CUEA_IGNORE;
    }
    else if (!strcmp("-f", argv[i])) {
      error_action = CUEA_FAIL;
    }
    else if (!strcmp("-A", argv[i])) {
      error_action = CUEA_ABORT;
    }
    else if (!strcmp("-s", argv[i])) {
      mode = CU_BRM_SILENT;
    }
    else if (!strcmp("-n", argv[i])) {
      mode = CU_BRM_NORMAL;
    }
    else if (!strcmp("-v", argv[i])) {
      mode = CU_BRM_VERBOSE;
    }
//    else if (!strcmp("-e", argv[i])) {
//      print_example_results();
//      return 0;
//    }
    else {
      printf("\nUsage:  BasicTest [options]\n\n"
               "Options:   -i   ignore framework errors [default].\n"
               "           -f   fail on framework error.\n"
               "           -A   abort on framework error.\n\n"
               "           -s   silent mode - no output to screen.\n"
               "           -n   normal mode - standard output to screen.\n"
               "           -v   verbose mode - max output to screen [default].\n\n"
//               "           -e   print expected test results and exit.\n"
               "           -h   print this message and exit.\n\n");
      return 0;
    }
  }

  if (CU_initialize_registry()) {
    printf("\nInitialization of Test Registry failed.");
  }
  else {
    AddTests();
    CU_basic_set_mode(mode);
    CU_set_error_action(error_action);
    printf("\nTests completed with return value %d.\n", CU_basic_run_tests());
    CU_cleanup_registry();
  }

  return 0;
}
示例#11
0
int main(int args, char *argv[])
{
    CU_BasicRunMode mode = CU_BRM_VERBOSE;
    CU_ErrorAction error_action = CUEA_FAIL;

    setvbuf(stdout, 0, _IONBF, 0);

    if (CU_initialize_registry()) {
        printf("\nTest init error\n");
    } else {
        AddTests();
        CU_basic_set_mode(mode);
        CU_set_error_action(error_action);
        printf("\nTests completed with return value %d. \n", CU_basic_run_tests());
        CU_cleanup_registry();
    }
}
示例#12
0
int main(int argc, char* argv[])
{
    CU_BasicRunMode mode = CU_BRM_VERBOSE;
    CU_ErrorAction error_action = CUEA_IGNORE;

    setvbuf(stdout, NULL, _IONBF, 0);

    if (CU_initialize_registry()) {
        fprintf(stderr, "\nInitialization of Test Registry failed.");
	exit(EXIT_FAILURE);
    }
    
    add_tests();
    CU_basic_set_mode(mode);
    CU_set_error_action(error_action);
    CU_basic_run_tests();
    CU_cleanup_registry();

    return EXIT_SUCCESS;
}
示例#13
0
int main(int argc, char* argv[])
{
    CU_BasicRunMode mode = CU_BRM_VERBOSE;
    CU_ErrorAction error_action = CUEA_IGNORE;
    int i;

    setvbuf(stdout, NULL, _IONBF, 0);

    for (i=1 ; i<argc ; i++) {
        if (!strcmp("-i", argv[i])) {
            error_action = CUEA_IGNORE;
        }
        else if (!strcmp("-f", argv[i])) {
            error_action = CUEA_FAIL;
        }
        else if (!strcmp("-A", argv[i])) {
            error_action = CUEA_ABORT;
        }
        else if (!strcmp("-s", argv[i])) {
            mode = CU_BRM_SILENT;
        }
        else if (!strcmp("-n", argv[i])) {
            mode = CU_BRM_NORMAL;
        }
        else if (!strcmp("-v", argv[i])) {
            mode = CU_BRM_VERBOSE;
        }
        else if (!strcmp("-e", argv[i])) {
            print_example_results();
            return 0;
        }
        else {
            printf("\nUsage:  BasicTest [options]\n\n"
                   "Options:   -i   ignore framework errors [default].\n"
                   "           -f   fail on framework error.\n"
                   "           -A   abort on framework error.\n\n"
                   "           -s   silent mode - no output to screen.\n"
                   "           -n   normal mode - standard output to screen.\n"
                   "           -v   verbose mode - max output to screen [default].\n\n"
                   "           -e   print expected test results and exit.\n"
                   "           -h   print this message and exit.\n\n");
            return 0;
        }
    }

    if (CU_initialize_registry()) {
        printf("\nInitialization of Test Registry failed.");
    }
    else {
        // add Tests
        CU_pSuite pSuite = NULL;


        // First Suite
        pSuite = CU_add_suite("Dictionary", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "NullFree", testFreeNullDict)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Basic dictionary methods", testBasicDict)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Dictionary methods", testDict)) {
            CU_cleanup_registry();
            return CU_get_error();
        }


        // 2nd Suite
        pSuite = CU_add_suite("List", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "NullFree", testFreeNullList)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Basic list methods", testList)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Copy list method", testCreateCopy)) {
            CU_cleanup_registry();
            return CU_get_error();
        }


        // 3rd Suite
        pSuite = CU_add_suite("Applications", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "Simple App", test_simple_app)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Advanced App", test_advanced_app)) {
            CU_cleanup_registry();
            return CU_get_error();
        }

        // 4th Suite
        pSuite = CU_add_suite("Session Management", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "Get Empty Session List", test_empty_jsession_list)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Basic Session Handling", test_basic_session_methods)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Multiple Sessions", test_multiple_sessions)) {
            CU_cleanup_registry();
            return CU_get_error();
        }


        // 5th Suite
        pSuite = CU_add_suite("Job Session", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "Session Invalidation", test_jsession_invalidation)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Getter Methods", test_jsession_getter_methods)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Job Lists", test_job_list)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Job Categories", test_job_categories)) {
            CU_cleanup_registry();
            return CU_get_error();
        }


        // 6th Suite
        pSuite = CU_add_suite("Monitoring Session", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "Reservation Lists", test_reservation_lists)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Job Lists", test_job_lists)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Queue Lists", test_get_queues)) {
            CU_cleanup_registry();
            return CU_get_error();
        }


        // 7th Suite
        pSuite = CU_add_suite("Reservation Session", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "Session Invalidation", test_rsession_invalidation)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Getter Methods", test_rsession_getter_methods)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Get reservation", test_rsession_get_reservation)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Get reservations", test_rsession_get_reservations)) {
            CU_cleanup_registry();
            return CU_get_error();
        }


        // 8th Suite
        pSuite = CU_add_suite("Reservation", NULL, NULL);
        if (NULL == pSuite) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        /* add the tests to the suite */
        if (NULL == CU_add_test(pSuite, "Get reservation info", test_r_get_info)) {
            CU_cleanup_registry();
            return CU_get_error();
        }
        if (NULL == CU_add_test(pSuite, "Get reservation template", test_r_get_template)) {
            CU_cleanup_registry();
            return CU_get_error();
        }



        CU_basic_set_mode(mode);
        CU_set_error_action(error_action);
        printf("\nTests completed with return value %d.\n", CU_basic_run_tests());
        CU_cleanup_registry();
    }

    return 0;
}
示例#14
0
int
main(int argc, char *argv[])
{
	char *testname_re = NULL;
	int lun;
	CU_BasicRunMode mode = CU_BRM_VERBOSE;
	CU_ErrorAction error_action = CUEA_IGNORE;
	int res;
	struct scsi_readcapacity10 *rc10;
	struct scsi_task *inq_task = NULL;
	struct scsi_task *inq_lbp_task = NULL;
	struct scsi_task *inq_bdc_task = NULL;
	struct scsi_task *inq_bl_task = NULL;
	struct scsi_task *rc16_task = NULL;
	struct scsi_task *rsop_task = NULL;
	int full_size;
	int is_usb = 0;
	int xml_mode = 0;
	static struct option long_opts[] = {
		{ "help", no_argument, 0, '?' },
		{ "list", no_argument, 0, 'l' },
		{ "initiator-name", required_argument, 0, 'i' },
		{ "initiator-name-2", required_argument, 0, 'I' },
		{ "test", required_argument, 0, 't' },
		{ "dataloss", no_argument, 0, 'd' },
		{ "allow-sanitize", no_argument, 0, 'S' },
		{ "ignore", no_argument, 0, 'g' },
		{ "fail", no_argument, 0, 'f' },
		{ "abort", no_argument, 0, 'A' },
		{ "silent", no_argument, 0, 's' },
		{ "normal", no_argument, 0, 'n' },
		{ "usb", no_argument, 0, 'u' },
		{ "verbose", no_argument, 0, 'v' },
		{ "xml", no_argument, 0, 'x' },
		{ "Verbose-scsi", no_argument, 0, 'V' },
		{ NULL, 0, 0, 0 }
	};
	int i, c;
	int opt_idx = 0;

	while ((c = getopt_long(argc, argv, "?hli:I:t:sdgfAsSnuvxV", long_opts,
		    &opt_idx)) > 0) {
		switch (c) {
		case 'h':
		case '?':
			print_usage();
			return 0;
		case 'l':
			list_all_tests();
			return 0;
		case 'i':
			initiatorname1 = strdup(optarg);
			break;
		case 'I':
			initiatorname2 = strdup(optarg);
			break;
		case 't':
			testname_re = strdup(optarg);
			break;
		case 'd':
			data_loss++;
			break;
		case 'g':
			error_action = CUEA_IGNORE; /* default */
			break;
		case 'f':
			error_action = CUEA_FAIL;
			break;
		case 'A':
			error_action = CUEA_ABORT;
			break;
		case 's':
			mode = CU_BRM_SILENT;
			break;
		case 'S':
			allow_sanitize = 1;
			break;
		case 'n':
			mode = CU_BRM_NORMAL;
			break;
		case 'u':
			is_usb = 1;
			break;
		case 'v':
			mode = CU_BRM_VERBOSE;	/* default */
			break;
		case 'x':
		        xml_mode = 1;
			break;
		case 'V':
			loglevel = LOG_VERBOSE;
			break;
		default:
			fprintf(stderr,
			    "error: unknown option return: %c (option %s)\n",
			    c, argv[optind]);
			return 1;
		}
	}

	if (optind < argc) {
		tgt_url = strdup(argv[optind++]);
	}
	if (optind < argc) {
		fprintf(stderr, "error: too many arguments\n");
		print_usage();
		return 1;
	}

	/* XXX why is this done? */
	real_iscsi_queue_pdu = dlsym(RTLD_NEXT, "iscsi_queue_pdu");

	if (tgt_url == NULL) {
		fprintf(stderr, "You must specify the URL\n");
		print_usage();
		if (testname_re)
			free(testname_re);
		return 10;
	}

	iscsic = iscsi_context_login(initiatorname1, tgt_url, &lun);
	if (iscsic == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}

	/*
	 * find the size of the LUN
	 * All devices support readcapacity10 but only some support
	 * readcapacity16
	 */
	task = iscsi_readcapacity10_sync(iscsic, lun, 0, 0);
	if (task == NULL) {
		printf("Failed to send READCAPACITY10 command: %s\n",
		    iscsi_get_error(iscsic));
		iscsi_destroy_context(iscsic);
		return -1;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("READCAPACITY10 command: failed with sense. %s\n",
		    iscsi_get_error(iscsic));
		scsi_free_scsi_task(task);
		iscsi_destroy_context(iscsic);
		return -1;
	}
	rc10 = scsi_datain_unmarshall(task);
	if (rc10 == NULL) {
		printf("failed to unmarshall READCAPACITY10 data. %s\n",
		    iscsi_get_error(iscsic));
		scsi_free_scsi_task(task);
		iscsi_destroy_context(iscsic);
		return -1;
	}
	block_size = rc10->block_size;
	num_blocks = rc10->lba + 1;
	scsi_free_scsi_task(task);

	rc16_task = iscsi_readcapacity16_sync(iscsic, lun);
	if (rc16_task == NULL) {
		printf("Failed to send READCAPACITY16 command: %s\n",
		    iscsi_get_error(iscsic));
		iscsi_destroy_context(iscsic);
		return -1;
	}
	if (rc16_task->status == SCSI_STATUS_GOOD) {
		rc16 = scsi_datain_unmarshall(rc16_task);
		if (rc16 == NULL) {
			printf("failed to unmarshall READCAPACITY16 data. %s\n",
			    iscsi_get_error(iscsic));
			scsi_free_scsi_task(rc16_task);
			iscsi_destroy_context(iscsic);
			return -1;
		}
		block_size = rc16->block_length;
		num_blocks = rc16->returned_lba + 1;
		lbppb = 1 << rc16->lbppbe;
	}

	inq_task = iscsi_inquiry_sync(iscsic, lun, 0, 0, 64);
	if (inq_task == NULL || inq_task->status != SCSI_STATUS_GOOD) {
		printf("Inquiry command failed : %s\n", iscsi_get_error(iscsic));
		return -1;
	}
	full_size = scsi_datain_getfullsize(inq_task);
	if (full_size > inq_task->datain.size) {
		scsi_free_scsi_task(inq_task);

		/* we need more data for the full list */
		inq_task = iscsi_inquiry_sync(iscsic, lun, 0, 0, full_size);
		if (inq_task == NULL) {
			printf("Inquiry command failed : %s\n",
			    iscsi_get_error(iscsic));
			return -1;
		}
	}
	inq = scsi_datain_unmarshall(inq_task);
	if (inq == NULL) {
		printf("failed to unmarshall inquiry datain blob\n");
		scsi_free_scsi_task(inq_task);
		return -1;
	}

	sbc3_support = 0;
	for (i = 0; i < 8; i++) {
		if (inq->version_descriptor[i] == 0x04C0) {
			sbc3_support = 1;
		}
	}

	/* try reading block limits vpd */
	inq_bl_task = iscsi_inquiry_sync(iscsic, lun, 1, SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, 64);
	if (inq_bl_task && inq_bl_task->status != SCSI_STATUS_GOOD) {
		scsi_free_scsi_task(inq_bl_task);
		inq_bl_task = NULL;
	}
	if (inq_bl_task) {
		full_size = scsi_datain_getfullsize(inq_bl_task);
		if (full_size > inq_bl_task->datain.size) {
			scsi_free_scsi_task(inq_bl_task);

			if ((inq_bl_task = iscsi_inquiry_sync(iscsic, lun, 1, SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, full_size)) == NULL) {
				printf("Inquiry command failed : %s\n", iscsi_get_error(iscsic));
				return -1;
			}
		}

		inq_bl = scsi_datain_unmarshall(inq_bl_task);
		if (inq_bl == NULL) {
			printf("failed to unmarshall inquiry datain blob\n");
			return -1;
		}
	}

	/* try reading block device characteristics vpd */
	inq_bdc_task = iscsi_inquiry_sync(iscsic, lun, 1, SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS, 255);
	if (inq_bdc_task == NULL) {
		printf("Failed to read Block Device Characteristics page\n");
	}
	if (inq_bdc_task) {
		inq_bdc = scsi_datain_unmarshall(inq_bdc_task);
		if (inq_bdc == NULL) {
			printf("failed to unmarshall inquiry datain blob\n");
			return -1;
		}
	}

	/* if thin provisioned we also need to read the VPD page for it */
	if (rc16 && rc16->lbpme != 0){
		inq_lbp_task = iscsi_inquiry_sync(iscsic, lun, 1, SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, 64);
		if (inq_lbp_task == NULL || inq_lbp_task->status != SCSI_STATUS_GOOD) {
			printf("Inquiry command failed : %s\n", iscsi_get_error(iscsic));
			return -1;
		}
		full_size = scsi_datain_getfullsize(inq_lbp_task);
		if (full_size > inq_lbp_task->datain.size) {
			scsi_free_scsi_task(inq_lbp_task);

			/* we need more data for the full list */
			if ((inq_lbp_task = iscsi_inquiry_sync(iscsic, lun, 1, SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, full_size)) == NULL) {
				printf("Inquiry command failed : %s\n", iscsi_get_error(iscsic));
				return -1;
			}
		}

		inq_lbp = scsi_datain_unmarshall(inq_lbp_task);
		if (inq_lbp == NULL) {
			printf("failed to unmarshall inquiry datain blob\n");
			return -1;
		}
	}

	rsop_task = iscsi_report_supported_opcodes_sync(iscsic, lun,
		1, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0, 65535);
	if (rsop_task == NULL) {
		printf("Failed to send REPORT_SUPPORTED_OPCODES command: %s\n",
		    iscsi_get_error(iscsic));
		iscsi_destroy_context(iscsic);
		return -1;
	}
	if (rsop_task->status == SCSI_STATUS_GOOD) {
		rsop = scsi_datain_unmarshall(rsop_task);
		if (rsop == NULL) {
			printf("failed to unmarshall REPORT_SUPPORTED_OPCODES "
			       "data. %s\n",
			       iscsi_get_error(iscsic));
			scsi_free_scsi_task(rsop_task);
		}
	}

	/* check if the device is write protected or not */
	task = iscsi_modesense6_sync(iscsic, lun, 0, SCSI_MODESENSE_PC_CURRENT,
				     SCSI_MODEPAGE_RETURN_ALL_PAGES,
				     0, 255);
	if (task == NULL) {
		printf("Failed to send MODE_SENSE6 command: %s\n",
		    iscsi_get_error(iscsic));
		iscsi_destroy_context(iscsic);
		return -1;
	}
	if (task->status == SCSI_STATUS_GOOD) {
		struct scsi_mode_sense *ms;

		ms = scsi_datain_unmarshall(task);
		if (ms == NULL) {
			printf("failed to unmarshall mode sense datain blob\n");
			scsi_free_scsi_task(task);
			return -1;
		}
		readonly = !!(ms->device_specific_parameter & 0x80);
	}
	scsi_free_scsi_task(task);

	iscsi_logout_sync(iscsic);
	iscsi_destroy_context(iscsic);

	if (is_usb) {
		printf("USB device. Clamping maximum transfer length to 120k\n");
		maximum_transfer_length = 120 *1024 / block_size;
	}

	if (CU_initialize_registry() != 0) {
		fprintf(stderr, "error: unable to initialize test registry\n");
		return 1;
	}
	if (CU_is_test_running()) {
		fprintf(stderr, "error: test suite(s) already running!?\n");
		exit(1);
	}

	parse_and_add_tests(testname_re);
	if (testname_re)
		free(testname_re);

	CU_basic_set_mode(mode);
	CU_set_error_action(error_action);
	printf("\n");

	/*
	 * this actually runs the tests ...
	 */

	if (xml_mode) {
	  CU_list_tests_to_file();
	  CU_automated_run_tests();
	} else {
	  res = CU_basic_run_tests();
	  printf("Tests completed with return value: %d\n", res);
	}

	CU_cleanup_registry();
	free(discard_const(tgt_url));

	if (inq_task != NULL) {
		scsi_free_scsi_task(inq_task);
	}
	if (inq_bl_task != NULL) {
		scsi_free_scsi_task(inq_bl_task);
	}
	if (inq_lbp_task != NULL) {
		scsi_free_scsi_task(inq_lbp_task);
	}
	if (inq_bdc_task != NULL) {
		scsi_free_scsi_task(inq_bdc_task);
	}
	if (rc16_task != NULL) {
		scsi_free_scsi_task(rc16_task);
	}
	if (rsop_task != NULL) {
		scsi_free_scsi_task(rsop_task);
	}

	return 0;
}
示例#15
0
int
main(int argc, char *argv[])
{
	char *testname_re = NULL;
	CU_BasicRunMode mode = CU_BRM_VERBOSE;
	CU_ErrorAction error_action = CUEA_IGNORE;
	int res;
	struct scsi_readcapacity10 *rc10;
	struct scsi_task *inq_task = NULL;
	struct scsi_task *inq_lbp_task = NULL;
	struct scsi_task *inq_bdc_task = NULL;
	struct scsi_task *inq_bl_task = NULL;
	struct scsi_task *rc16_task = NULL;
	struct scsi_task *rsop_task = NULL;
	int full_size;
	int xml_mode = 0;
	static struct option long_opts[] = {
		{ "help", no_argument, 0, '?' },
		{ "list", no_argument, 0, 'l' },
		{ "initiator-name", required_argument, 0, 'i' },
		{ "initiator-name-2", required_argument, 0, 'I' },
		{ "test", required_argument, 0, 't' },
		{ "dataloss", no_argument, 0, 'd' },
		{ "allow-sanitize", no_argument, 0, 'S' },
		{ "ignore", no_argument, 0, 'g' },
		{ "fail", no_argument, 0, 'f' },
		{ "abort", no_argument, 0, 'A' },
		{ "silent", no_argument, 0, 's' },
		{ "normal", no_argument, 0, 'n' },
		{ "verbose", no_argument, 0, 'v' },
		{ "xml", no_argument, 0, 'x' },
		{ "Verbose-scsi", no_argument, 0, 'V' },
		{ NULL, 0, 0, 0 }
	};
	int i, c;
	int opt_idx = 0;

	while ((c = getopt_long(argc, argv, "?hli:I:t:sdgfAsSnvxV", long_opts,
		    &opt_idx)) > 0) {
		switch (c) {
		case 'h':
		case '?':
			print_usage();
			return 0;
		case 'l':
			list_all_tests();
			return 0;
		case 'i':
			initiatorname1 = strdup(optarg);
			break;
		case 'I':
			initiatorname2 = strdup(optarg);
			break;
		case 't':
			testname_re = strdup(optarg);
			break;
		case 'd':
			data_loss++;
			break;
		case 'g':
			error_action = CUEA_IGNORE; /* default */
			break;
		case 'f':
			error_action = CUEA_FAIL;
			break;
		case 'A':
			error_action = CUEA_ABORT;
			break;
		case 's':
			mode = CU_BRM_SILENT;
			break;
		case 'S':
			allow_sanitize = 1;
			break;
		case 'n':
			mode = CU_BRM_NORMAL;
			break;
		case 'v':
			mode = CU_BRM_VERBOSE;	/* default */
			break;
		case 'x':
		        xml_mode = 1;
			break;
		case 'V':
			loglevel = LOG_VERBOSE;
			break;
		default:
			fprintf(stderr,
			    "error: unknown option return: %c (option %s)\n",
			    c, argv[optind]);
			return 1;
		}
	}

	/* parse all trailing arguments as device paths */
	mp_num_sds = 0;
	while (optind < argc) {
		if (mp_num_sds >= MPATH_MAX_DEVS) {
			fprintf(stderr, "Too many multipath device URLs\n");
			print_usage();
			free(testname_re);
			return 10;
		}

		mp_sds[mp_num_sds] = malloc(sizeof(struct scsi_device));
		memset(mp_sds[mp_num_sds], '\0', sizeof(struct scsi_device));
		mp_sds[mp_num_sds]->sgio_fd = -1;

		if (!strncmp(argv[optind], "iscsi://", 8)) {
			mp_sds[mp_num_sds]->iscsi_url = strdup(argv[optind++]);
#ifdef HAVE_SG_IO
		} else {
			mp_sds[mp_num_sds]->sgio_dev = strdup(argv[optind++]);
#endif
		}
		mp_num_sds++;
	}

	/* So that we can override iscsi_queue_pdu in tests
	 * and replace or mutate the blob that we are about to write to the
	 * wire.
	 * This allows such tests to do their mutates and then call out
	 * to the real queueing function once they have modified the data.
	 */
	real_iscsi_queue_pdu = dlsym(RTLD_NEXT, "iscsi_queue_pdu");

	if ((mp_num_sds == 0) || (mp_sds[0]->iscsi_url == NULL
					&& mp_sds[0]->sgio_dev == NULL)) {
#ifdef HAVE_SG_IO
		fprintf(stderr, "You must specify either an iSCSI URL or a device file\n");
#else
		fprintf(stderr, "You must specify an iSCSI URL\n");
#endif
		print_usage();
		if (testname_re)
			free(testname_re);
		return 10;
	}

	/* sd remains an alias for the first device */
	sd = mp_sds[0];

	for (i = 0; i < mp_num_sds; i++) {
		res = connect_scsi_device(mp_sds[i], initiatorname1);
		if (res < 0) {
			fprintf(stderr,
				"Failed to connect to SCSI device %d\n", i);
			goto err_sds_free;
		}
	}

	if (mp_num_sds > 1) {
		/* check that all multipath sds identify as the same LU */
		res = mpath_check_matching_ids(mp_num_sds, mp_sds);
		if (res < 0) {
			fprintf(stderr, "multipath devices don't match\n");
			goto err_sds_free;
		}
	}

	/*
	 * find the size of the LUN
	 * All devices support readcapacity10 but only some support
	 * readcapacity16
	 */
	task = NULL;
	readcapacity10(sd, &task, 0, 0, EXPECT_STATUS_GOOD);
	if (task == NULL) {
		printf("Failed to send READCAPACITY10 command: %s\n", sd->error_str);
		goto err_sds_free;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("READCAPACITY10 command: failed with sense. %s\n", sd->error_str);
		scsi_free_scsi_task(task);
		goto err_sds_free;
	}
	rc10 = scsi_datain_unmarshall(task);
	if (rc10 == NULL) {
		printf("failed to unmarshall READCAPACITY10 data.\n");
		scsi_free_scsi_task(task);
		goto err_sds_free;
	}
	block_size = rc10->block_size;
	num_blocks = rc10->lba + 1;
	scsi_free_scsi_task(task);

	rc16_task = NULL;
	readcapacity16(sd, &rc16_task, 96, EXPECT_STATUS_GOOD);
	if (rc16_task == NULL) {
		printf("Failed to send READCAPACITY16 command: %s\n", sd->error_str);
		goto err_sds_free;
	}
	if (rc16_task->status == SCSI_STATUS_GOOD) {
		rc16 = scsi_datain_unmarshall(rc16_task);
		if (rc16 == NULL) {
			printf("failed to unmarshall READCAPACITY16 data. %s\n", sd->error_str);
			scsi_free_scsi_task(rc16_task);
			goto err_sds_free;
		}
		block_size = rc16->block_length;
		num_blocks = rc16->returned_lba + 1;
		lbppb = 1 << rc16->lbppbe;
	}

	inq_task = NULL;
	inquiry(sd, &inq_task, 0, 0, 64, EXPECT_STATUS_GOOD);
	if (inq_task == NULL || inq_task->status != SCSI_STATUS_GOOD) {
		printf("Inquiry command failed : %s\n", sd->error_str);
		goto err_sds_free;
	}
	full_size = scsi_datain_getfullsize(inq_task);
	if (full_size > inq_task->datain.size) {
		scsi_free_scsi_task(inq_task);

		/* we need more data for the full list */
		inq_task = NULL;
		inquiry(sd, &inq_task, 0, 0, full_size, EXPECT_STATUS_GOOD);
		if (inq_task == NULL) {
			printf("Inquiry command failed : %s\n", sd->error_str);
			goto err_sds_free;
		}
	}
	inq = scsi_datain_unmarshall(inq_task);
	if (inq == NULL) {
		printf("failed to unmarshall inquiry datain blob\n");
		scsi_free_scsi_task(inq_task);
		goto err_sds_free;
	}

	sbc3_support = 0;
	for (i = 0; i < 8; i++) {
		if (inq->version_descriptor[i] == 0x04C0) {
			sbc3_support = 1;
		}
	}

	/* try reading block limits vpd */
	inq_bl_task = NULL;
	inquiry(sd, &inq_bl_task, 1, SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, 64, EXPECT_STATUS_GOOD);
	if (inq_bl_task && inq_bl_task->status != SCSI_STATUS_GOOD) {
		scsi_free_scsi_task(inq_bl_task);
		inq_bl_task = NULL;
	}
	if (inq_bl_task) {
		full_size = scsi_datain_getfullsize(inq_bl_task);
		if (full_size > inq_bl_task->datain.size) {
			scsi_free_scsi_task(inq_bl_task);

			inq_bl_task = NULL;
			inquiry(sd, &inq_bl_task, 1, SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, full_size,
				EXPECT_STATUS_GOOD);
			if (inq_bl_task == NULL) {
				printf("Inquiry command failed : %s\n", sd->error_str);
				goto err_sds_free;
			}
		}

		inq_bl = scsi_datain_unmarshall(inq_bl_task);
		if (inq_bl == NULL) {
			printf("failed to unmarshall inquiry datain blob\n");
			goto err_sds_free;
		}
	}

	/* try reading block device characteristics vpd */
	inquiry(sd, &inq_bdc_task, 1, SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS, 255,
		EXPECT_STATUS_GOOD);
	if (inq_bdc_task == NULL || inq_bdc_task->status != SCSI_STATUS_GOOD) {
		printf("Failed to read Block Device Characteristics page\n");
	} else {
		inq_bdc = scsi_datain_unmarshall(inq_bdc_task);
		if (inq_bdc == NULL) {
			printf("failed to unmarshall inquiry datain blob\n");
			goto err_sds_free;
		}
	}

	/* if thin provisioned we also need to read the VPD page for it */
	if (rc16 && rc16->lbpme != 0){
		inq_lbp_task = NULL;
		inquiry(sd, &inq_lbp_task, 1, SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, 64,
			EXPECT_STATUS_GOOD);
		if (inq_lbp_task == NULL || inq_lbp_task->status != SCSI_STATUS_GOOD) {
			printf("Inquiry command failed : %s\n", sd->error_str);
			goto err_sds_free;
		}
		full_size = scsi_datain_getfullsize(inq_lbp_task);
		if (full_size > inq_lbp_task->datain.size) {
			scsi_free_scsi_task(inq_lbp_task);

			/* we need more data for the full list */
			inq_lbp_task = NULL;
			inquiry(sd, &inq_lbp_task, 1, SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
				full_size, EXPECT_STATUS_GOOD);
			if (inq_lbp_task == NULL) {
				printf("Inquiry command failed : %s\n", sd->error_str);
				goto err_sds_free;
			}
		}

		inq_lbp = scsi_datain_unmarshall(inq_lbp_task);
		if (inq_lbp == NULL) {
			printf("failed to unmarshall inquiry datain blob\n");
			goto err_sds_free;
		}
	}

	rsop_task = NULL;
	report_supported_opcodes(sd, &rsop_task, 1, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0, 65535,
				 EXPECT_STATUS_GOOD);
	if (rsop_task == NULL) {
		printf("Failed to send REPORT_SUPPORTED_OPCODES command: %s\n", sd->error_str);
		goto err_sds_free;
	}
	if (rsop_task->status == SCSI_STATUS_GOOD) {
		rsop = scsi_datain_unmarshall(rsop_task);
		if (rsop == NULL) {
			printf("failed to unmarshall REPORT_SUPPORTED_OPCODES data.\n");
			scsi_free_scsi_task(rsop_task);
			rsop_task = NULL;
		}
	}

	/* check if the device is write protected or not */
	task = NULL;
	modesense6(sd, &task, 0, SCSI_MODESENSE_PC_CURRENT, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
		   EXPECT_STATUS_GOOD);
	if (task == NULL) {
		printf("Failed to send MODE_SENSE6 command: %s\n", sd->error_str);
		goto err_sds_free;
	}
	if (task->status == SCSI_STATUS_GOOD) {
		struct scsi_mode_sense *ms;

		ms = scsi_datain_unmarshall(task);
		if (ms == NULL) {
			printf("failed to unmarshall mode sense datain blob\n");
			scsi_free_scsi_task(task);
			goto err_sds_free;
		}
		readonly = !!(ms->device_specific_parameter & 0x80);
	}
	scsi_free_scsi_task(task);

	if (maxsectbytes) {
		maximum_transfer_length = maxsectbytes / block_size;
		printf("Bus transfer size is limited to %d bytes. Clamping "
		       "max transfers accordingly.\n", maxsectbytes);
	}

	if (CU_initialize_registry() != 0) {
		fprintf(stderr, "error: unable to initialize test registry\n");
		goto err_sds_free;
	}
	if (CU_is_test_running()) {
		fprintf(stderr, "error: test suite(s) already running!?\n");
		exit(1);
	}

	parse_and_add_tests(testname_re);
	if (testname_re)
		free(testname_re);

	CU_basic_set_mode(mode);
	CU_set_error_action(error_action);
	printf("\n");

	/*
	 * this actually runs the tests ...
	 */

	if (xml_mode) {
	  CU_list_tests_to_file();
	  CU_automated_run_tests();
	} else {
	  res = CU_basic_run_tests();
	  printf("Tests completed with return value: %d\n", res);
	}

	CU_cleanup_registry();

	if (inq_task != NULL) {
		scsi_free_scsi_task(inq_task);
	}
	if (inq_bl_task != NULL) {
		scsi_free_scsi_task(inq_bl_task);
	}
	if (inq_lbp_task != NULL) {
		scsi_free_scsi_task(inq_lbp_task);
	}
	if (inq_bdc_task != NULL) {
		scsi_free_scsi_task(inq_bdc_task);
	}
	if (rc16_task != NULL) {
		scsi_free_scsi_task(rc16_task);
	}
	if (rsop_task != NULL) {
		scsi_free_scsi_task(rsop_task);
	}
	for (i = 0; i < mp_num_sds; i++) {
		free_scsi_device(mp_sds[i]);
	}

	return 0;

err_sds_free:
	for (i = 0; i < mp_num_sds; i++) {
		free_scsi_device(mp_sds[i]);
	}
	return -1;
}