Пример #1
0
static int create_files(struct kernfs_node *parent, struct kobject *kobj,
			const struct attribute_group *grp, int update)
{
	struct attribute *const *attr;
	struct bin_attribute *const *bin_attr;
	int error = 0, i;

	if (grp->attrs) {
		for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) {
			umode_t mode = (*attr)->mode;

			/*
			 * In update mode, we're changing the permissions or
			 * visibility.  Do this by first removing then
			 * re-adding (if required) the file.
			 */
			if (update)
				kernfs_remove_by_name(parent, (*attr)->name);
			if (grp->is_visible) {
				mode = grp->is_visible(kobj, *attr, i);
				if (!mode)
					continue;
			}

			WARN(mode & ~(SYSFS_PREALLOC | 0664),
			     "Attribute %s: Invalid permissions 0%o\n",
			     (*attr)->name, mode);

			mode &= SYSFS_PREALLOC | 0664;
			error = sysfs_add_file_mode_ns(parent, *attr, false,
						       mode, NULL);
			if (unlikely(error))
				break;
		}
		if (error) {
			remove_files(parent, grp);
			goto exit;
		}
	}

	if (grp->bin_attrs) {
		for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
			if (update)
				kernfs_remove_by_name(parent,
						(*bin_attr)->attr.name);
			error = sysfs_add_file_mode_ns(parent,
					&(*bin_attr)->attr, true,
					(*bin_attr)->attr.mode, NULL);
			if (error)
				break;
		}
		if (error)
			remove_files(parent, grp);
	}
exit:
	return error;
}
Пример #2
0
static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
			const struct attribute_group *grp, int update)
{
	struct attribute *const* attr;
	struct bin_attribute *const* bin_attr;
	int error = 0, i;

	if (grp->attrs) {
		for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) {
			umode_t mode = 0;

			/*
			 * In update mode, we're changing the permissions or
			 * visibility.  Do this by first removing then
			 * re-adding (if required) the file.
			 */
			if (update)
				sysfs_hash_and_remove(dir_sd, NULL,
						      (*attr)->name);
			if (grp->is_visible) {
				mode = grp->is_visible(kobj, *attr, i);
				if (!mode)
					continue;
			}
			error = sysfs_add_file_mode(dir_sd, *attr,
						    SYSFS_KOBJ_ATTR,
						    (*attr)->mode | mode);
			if (unlikely(error))
				break;
		}
		if (error) {
			remove_files(dir_sd, kobj, grp);
			goto exit;
		}
	}

	if (grp->bin_attrs) {
		for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
			if (update)
				sysfs_remove_bin_file(kobj, *bin_attr);
			error = sysfs_create_bin_file(kobj, *bin_attr);
			if (error)
				break;
		}
		if (error)
			remove_files(dir_sd, kobj, grp);
	}
exit:
	return error;
}
Пример #3
0
void panic(char *str)
{
    errmsg(str);
    printf("\n");
    remove_files();
    exit(-1);
}
Пример #4
0
void sys_panic(char *str)
{
    printf("panic\n");
    perror(str);
    remove_files();
    exit(-1);
}
Пример #5
0
void *thread_worker_remove(void *arg)
{
	struct my_thread_arg *arg1 = (struct my_thread_arg*)arg;
	remove_files(arg1->dir, arg1->nums);

	return NULL;
}
Пример #6
0
Файл: group.c Проект: 7799/linux
/**
 * sysfs_remove_group: remove a group from a kobject
 * @kobj:	kobject to remove the group from
 * @grp:	group to remove
 *
 * This function removes a group of attributes from a kobject.  The attributes
 * previously have to have been created for this group, otherwise it will fail.
 */
void sysfs_remove_group(struct kobject *kobj,
			const struct attribute_group *grp)
{
	struct kernfs_node *parent = kobj->sd;
	struct kernfs_node *kn;

	if (grp->name) {
		kn = kernfs_find_and_get(parent, grp->name);
		if (!kn) {
			WARN(!kn, KERN_WARNING
			     "sysfs group %p not found for kobject '%s'\n",
			     grp, kobject_name(kobj));
			return;
		}
	} else {
		kn = parent;
		kernfs_get(kn);
	}

	remove_files(kn, kobj, grp);
	if (grp->name)
		kernfs_remove(kn);

	kernfs_put(kn);
}
Пример #7
0
int file_cmd_cleanup(void)
{
  if (parse_arguments())
    return 1;

  return remove_files();
}
Пример #8
0
static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
			const struct attribute_group *grp, int update)
{
	struct attribute *const* attr;
	int error = 0, i;

	for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) {
		umode_t mode = 0;

		if (update)
			sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
		if (grp->is_visible) {
			mode = grp->is_visible(kobj, *attr, i);
			if (!mode)
				continue;
		}
		error = sysfs_add_file_mode(dir_sd, *attr, SYSFS_KOBJ_ATTR,
					    (*attr)->mode | mode);
		if (unlikely(error))
			break;
	}
	if (error)
		remove_files(dir_sd, kobj, grp);
	return error;
}
Пример #9
0
/**
@details
-# If we have not called init yet (pthread_id == 0), call init.
-# Delete existing log files.
*/
int Trick::DataRecordDispatcher::restart() {
    // if we restarted from scratch without calling init jobs, need to call init
    if ( drd_writer_thread.get_pthread_id() == 0 ) {
        init() ;
    }
    // remove the current log files
    remove_files() ;
    return 0 ;
}
Пример #10
0
char * get_input_file(Test *test) {
  char  *tmpsuff   = "testXXXXXX";
  size_t tmplen    = strlen(P_tmpdir) + strlen(tmpsuff) + 2;
  char  *name      = malloc(tmplen);
  size_t offset    = 0;
  int    fd;

  if (NULL == name) {
    perror(NULL);
    return NULL;
  }

  /* Make a temporary file */
  snprintf(name, tmplen, "%s/%s", P_tmpdir, tmpsuff);
  
  fd = mkstemp(name);
  if (-1 == fd) {
    fprintf(stderr, "Couldn't make temporary file %s : %s\n",
	    name, strerror(errno));
    free(name);
    return NULL;
  }

  /* Fill it with test data */
  if (gen_data(name, fd, test->in_len, &offset, 0, 0) < 0) {
    remove_files(&name, 1);
    free(name);
    return NULL;
  }
  assert(offset == test->in_len);

  /* Close fd as no longer needed */
  if (0 != close(fd)) {
    fprintf(stderr, "Error closing temporary file %s : %s\n",
	    name, strerror(errno));
    remove_files(&name, 1);
    free(name);
    return NULL;
  }

  return name;
}
Пример #11
0
/**
 * driver exit point
 */
static void __exit etm_exit(void)
{
	kfree(tracer.etm_info);
	kfree(tracer.etm_regs);

	remove_files();

	if (misc_deregister(&etm_device)) {
		pr_err("Fail to deregister dervice\n");
	}
}
Пример #12
0
static int cnv_board_dir(struct boardheader *bh, void *arg)
{
	printf("=======================================\n");
	printf("Boardname: %s\n", bh->filename);
	build_dir(bh->filename);
	convert_normal(bh->filename);
	convert_delete(bh->filename);
	convert_junk(bh->filename);
	convert_ding(bh->filename);
	remove_files(bh->filename);
	return 0;
}
Пример #13
0
static int create_files(struct sysfs_dirent *dir_sd,
			const struct attribute_group *grp)
{
	struct attribute *const* attr;
	int error = 0;

	for (attr = grp->attrs; *attr && !error; attr++)
		error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
	if (error)
		remove_files(dir_sd, grp);
	return error;
}
Пример #14
0
int file_cmd_prepare(void)
{
  if (parse_arguments())
    return 1;

  /*
    Make sure that files do not exist for 'sequential write' test mode,
    create test files for other test modes
  */
  if (test_mode == MODE_WRITE)
    return remove_files();

  return create_files();
}
Пример #15
0
/*
 * setup() - performs all ONE TIME setup for this test.
 */
void setup()
{
	int max_open;

	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	TEST_PAUSE;

	/* make a temporary directory and cd to it */
	tst_tmpdir();

	umask(0);
	mypid = getpid();
	sprintf(fname, "creat05.%d", mypid);
	unlink(fname);

	/* create a file to get the first file descriptor available */
	if ((first = fd = creat(fname, MODE)) == -1) {
		tst_brkm(TFAIL, cleanup, "Cannot open first file");
	}

	close(fd);
	unlink(fname);
	tst_resm(TINFO, "first file is #%d", fd);

	/* get the maximum number of files that we can open */
	max_open = getdtablesize();
	/* Allocate memory for stat and ustat structure variables */
	if ((buf = (int *)malloc(sizeof(int) * max_open - first)) == NULL) {
		tst_brkm(TBROK, NULL, "Failed to allocate Memory");
	}

	/* now open as many files as we can up to max_open */
	for (ifile = first; ifile <= max_open; ifile++) {
		sprintf(fname, "creat05.%d.%d", ifile, mypid);
		if ((fd = creat(fname, 0666)) == -1) {
			tst_resm(TINFO, "could not creat file "
				 "#%d", ifile + 1);
			if (errno != EMFILE) {
				remove_files(ifile);
				tst_brkm(TBROK | TERRNO, cleanup,
					 "Failed unexpectedly (expected EMFILE)");
			}
			break;
		}
		buf[ifile - first] = fd;
	}
}
Пример #16
0
void sysfs_remove_group(struct kobject * kobj, 
			const struct attribute_group * grp)
{
	struct dentry * dir;

	if (grp->name)
		dir = lookup_one_len(grp->name, kobj->dentry,
				strlen(grp->name));
	else
		dir = dget(kobj->dentry);

	remove_files(dir,grp);
	if (grp->name)
		sysfs_remove_subdir(dir);
	/* release the ref. taken in this routine */
	dput(dir);
}
Пример #17
0
void sysfs_remove_group(struct kobject * kobj, 
			const struct attribute_group * grp)
{
	struct sysfs_dirent *dir_sd = kobj->sd;
	struct sysfs_dirent *sd;

	if (grp->name) {
		sd = sysfs_get_dirent(dir_sd, grp->name);
		BUG_ON(!sd);
	} else
		sd = sysfs_get(dir_sd);

	remove_files(sd, grp);
	if (grp->name)
		sysfs_remove_subdir(sd);

	sysfs_put(sd);
}
Пример #18
0
/***********************************************
 Method:
	process_client_removal_request

 Description:
	Remove the clients files & connection
	information

***********************************************/
static void process_client_removal_request
	(
	p2p_serv_conn_info_t * 	conn,
	void *					request
	)
{
int i;

/*----------------------------------------
Send the response
----------------------------------------*/
udp_rdt_send_response( UDP_RDT_RESP_ID_OK, &conn->serv_state, &conn->client, NULL, 0 );

/*----------------------------------------
Remove all files given by conn
----------------------------------------*/
remove_files(conn);
}
Пример #19
0
int main(int ac, char **av)
{
	int lc;
	char *msg;

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
	}

	setup();

	TEST_EXP_ENOS(exp_enos);

	for (lc = 0; TEST_LOOPING(lc); lc++) {

		/* reset Tst_count in case we are looping */
		Tst_count = 0;

		TEST(creat(fname, MODE));

		if (TEST_RETURN != -1) {
			tst_resm(TFAIL, "call succeeded unexpectedly");
			continue;
		}

		TEST_ERROR_LOG(TEST_ERRNO);

		if (TEST_ERRNO == EMFILE) {
			tst_resm(TPASS, "call failed with expected error - "
				 "EMFILE");
		} else {
			tst_resm(TFAIL | TTERRNO, "Expected EMFILE");
		}

		remove_files(ifile);
	}
	cleanup();

	tst_exit();
}
Пример #20
0
void sysfs_remove_group(struct kobject * kobj, 
			const struct attribute_group * grp)
{
	struct sysfs_dirent *dir_sd = kobj->sd;
	struct sysfs_dirent *sd;

	if (grp->name) {
		sd = sysfs_get_dirent(dir_sd, NULL, grp->name);
		if (!sd) {
			WARN(!sd, KERN_WARNING "sysfs group %p not found for "
				"kobject '%s'\n", grp, kobject_name(kobj));
			return;
		}
	} else
		sd = sysfs_get(dir_sd);

	remove_files(sd, kobj, grp);
	if (grp->name)
		sysfs_remove_subdir(sd);

	sysfs_put(sd);
}
int run_main (int argc, ACE_TCHAR *argv [])
{
  ACE_START_TEST (ACE_TEXT ("Logging_Strategy_Test"));

  ACE_TCHAR *l_argv[4];

  if (argc > 1)
    {
      if (parse_args (argc, argv) == -1)
        ACE_ERROR_RETURN ((LM_ERROR,
                           "Invalid command-line parameters.\n"),
                          1);
    }
  else
    {
      l_argv[0] = argv[0];
      l_argv[1] =
        (ACE_TCHAR *) ACE_TEXT ("-slog/Logging_Strategy_Test")
                      ACE_LOG_FILE_EXT_NAME;
      l_argv[2] = (ACE_TCHAR *) ACE_TEXT ("-o");
      l_argv[3] = 0;

      if (parse_args (3, l_argv) == -1)
        ACE_ERROR_RETURN ((LM_ERROR,
                           "Invalid command-line parameters.\n"),
                          1);
      argv = l_argv;
      argc = 3;
    }

  // Remove existing files.
  remove_files ();

  // This is necessary only if the provided logfile name is the same
  // as the default name.  If so, nothing will be written as the
  // previous ofstream is closed only at the end (ACE_END_TEST)
  ACE_CLOSE_TEST_LOG;

  // When Dlls are used, we utilize the dynamic service configuration
  // mechanism to activate the logging strategy. This is not a must
  // though, and you may activate the logging strategy as described in
  // the non-DLL section below under DLL environments as well.

#if !defined (ACE_HAS_STATIC_LIBS) && \
  (defined (ACE_WIN32) || defined (ACE_HAS_SVR4_DYNAMIC_LINKING) || \
   defined (__hpux))

  // Platform support DLLs, and not configured to link statically
  ACE_TCHAR arg_str[250];
  ACE_OS::sprintf (arg_str,
                   ACE_TEXT ("dynamic Logger Service_Object ")
                   ACE_TEXT ("*ACE:_make_ACE_Logging_Strategy()")
                   ACE_TEXT ("\""));

  for (int i = 1; i < argc; i++)
    {
      ACE_OS::strcat (arg_str, argv[i]);
      ACE_OS::strcat (arg_str, ACE_TEXT (" "));
    }

  ACE_OS::strcat (arg_str, ACE_TEXT ("\""));

  if (ACE_Service_Config::process_directive (arg_str) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "Error opening _make_ACE_Log_Strategy.\n"),
                      1);
#else // Platform doesn't support DLLs, or configured to link
      // statically
  ACE_Logging_Strategy logging_strategy;
  char ls_argc = argc - 1;
  ACE_Auto_Basic_Ptr<ACE_TCHAR *> ls_argv (new ACE_TCHAR *[ls_argc]);

  for (char c = 0; c < ls_argc; c++)
    (ls_argv.get ())[c] = argv[c+1];

  if (logging_strategy.init (ls_argc, ls_argv.get ()) == -1)
     ACE_ERROR_RETURN
       ((LM_ERROR,
         "Error initializing the ACE_Logging_Strategy.\n"),
                       1);
#endif /* !ACE_HAS_STATIC_LIBS && (ACE_WIN32 ||
          ACE_HAS_SVR4_DYNAMIC_LINKING || __hpux) */

  // launch a new Thread
  if (ACE_Thread_Manager::instance ()->spawn
      (ACE_THR_FUNC (run_reactor)) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "Spawning Reactor.\n"),
                      1);

  // Function to print the message
  print_till_death ();

  // Counts the generated files
  count_files ();

  // Get the file order
  order ();

  // Wait for the thread to exit before we exit.
  ACE_Thread_Manager::instance ()->wait ();
  ACE_END_TEST;
  return 0;
}
Пример #22
0
int main()
{
	PASS_TWO();
	remove_files();			
}
Пример #23
0
int run_test(int argc, char **argv,
	     unsigned int test_num, Test *test, char **fifos) {
  char  *in_file   = NULL;
  int    in_fd     = -1;
  char **out_files = NULL;
  int   *out_fds   = NULL;
  int    fifo_fds[MAX_READERS];
  pid_t  child     = 0;
  int i, res = 0, wres;

  /* Write some information about the test to the log */
  print_test_info(test_num, test);

  assert(test->npipes <= MAX_READERS);

  for (i = 0; i < MAX_READERS; i++) fifo_fds[i] = -1;

  /* Open any output files needed */
  if (test->nfiles > 0) {
    if (0 != get_output_files(test, &out_files, &out_fds)) goto BAIL;
  }

  /* Create an input file if the test needs one */
  if (test->in_type == IN_FILE) {
    if (NULL == (in_file = get_input_file(test))) goto BAIL;
  }

  /* Start the program under test */
  child = start_prog(argc, argv, test, &in_fd, in_file, fifos, out_files);
  if (child < 0) goto BAIL;

  /* Open any named pipes required */
  if (test->npipes > 0) {
    if (0 != open_fifos(test->npipes, fifos, fifo_fds)) goto BAIL;
  }

  if (test->npipes) {
    /* reading from pipes, run the full poll loop */
    res = run_poll_loop(test, in_fd, fifo_fds, fifos);
    /* Close any pipes that are still open */
    if (0 != close_fifos(test->npipes, fifos, fifo_fds)) {
      res = -1;
    }
  } else if (test->in_type == IN_PIPE || test->in_type == IN_SLOW_PIPE) {
    /* only sending to a pipe, so just shove the data down it */
    size_t offset = 0;
    if (gen_data("pipe", in_fd, test->in_len, &offset, 0, 0) != test->in_len) {
      res = -1;
    }
    if (0 != close(in_fd)) {
      perror("Closing pipe");
      res = -1;
    }
  }

  /* Wait for the program to finish and check the exit status */
  wres = wait_child(child);
  if (-99 == wres) goto BAIL;
  if (wres < 0) res = -1;


  /* Check the contents of any regular files that were created */
  if (test->nfiles > 0) {
    if (0 != check_output_files(test, out_fds, out_files)) res = -1;
  }

  /* Clean up */
  if (NULL != in_file) remove_files(&in_file, 1);
  if (test->nfiles > 0) {
    remove_files(out_files, test->nfiles);
  }
  return res;

 BAIL:
  /* Something went wrong, clean up and return 99 */
  if (NULL != in_file) remove_files(&in_file, 1);
  if (test->nfiles > 0 && NULL != out_files) {
    remove_files(out_files, test->nfiles);
  }
  if (test->npipes > 0) {
    close_fifos(test->npipes, fifos, fifo_fds);
  }
  return 99;
}
Пример #24
0
int run_tests(int argc, char **argv) {
  char *fifos[MAX_READERS] = { NULL };
  /* The test schedule */
  TestSegment test_segs1[1] = {{{ 100 }}};
  TestSegment test_segs2[1] = {{{ 100, 100 }}};
  TestSegment test_segs3[2] = {{{ 100, 0 }}, {{ 0, 100 }}};
  TestSegment test_segs4[1] = {{{ 100, -1 }}};
  TestSegment test_segs5[2] = {{{ 50, 50 }}, {{ -1, -1 }}};
  TestSegment test_segs6[2] = {{{ 100, 100 }}, {{ -1, 900 }}};
  TestSegment test_segs7[20] = {{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}},
				{{1000000, 0}}, {{0, 1000000}}};
  TestSegment test_segs8[3] = {{{1000000, 1000000}},
			       {{8000000, -1}},
			       {{1000000, -1}}};
  TestSegment test_segs9[2] = {{{10000000, 0}}, {{0, 10000000}}};
  TestSegment test_segs10[2] = {{{1000000, 100}}, {{-1, -1}}};
  Test tests[] = {{ 100, IN_PIPE, 1, 0, 0, 1, NULL },
		  { 100, IN_PIPE, 2, 0, 0, 1, NULL },
		  { 100, IN_PIPE, 0, 1, 1, 1, test_segs1 },
		  { 100, IN_PIPE, 0, 1, 2, 1, test_segs2 },
		  { 100, IN_PIPE, 0, 2, 2, 1, test_segs3 },
		  { 100, IN_PIPE, 0, 1, 2, 1, test_segs4 },
		  { 100, IN_PIPE, 0, 2, 2, 1, test_segs5 },
		  { 1000, IN_PIPE, 0, 2, 2, 7, test_segs6 },
		  { 10000000, IN_PIPE, 0, 20, 2, 167, test_segs7 },
		  { 10000000, IN_PIPE, 0, 20, 2, 167, test_segs7 },
		  { 10000000, IN_PIPE, 0, 3, 2, 167, test_segs8 },
		  { 10000000, IN_PIPE, 0, 2, 2, 167, test_segs9 },
		  { 10000000, IN_PIPE, 0, 2, 2, 167, test_segs10 },
		  { 10000000, IN_PIPE, 1, 2, 2, 167, test_segs10 },
  };
  unsigned int ntests = sizeof(tests) / sizeof(tests[0]);
  unsigned int i, res, failed = 0, test_num = 0;

  /* Create the named pipes */
  if (0 != make_fifos(fifos)) {
    res = 99;
    goto BAIL;
  }

  /* Print the expected number of tests for the driver */
  printf("1..%u\n", ntests * 3);
  
  /* Run all the tests twice, once reading a pipe and once reading a file */
  for (i = 0; i < ntests; i++) {
    Test t = tests[i];
    for (t.in_type = IN_PIPE; t.in_type <= IN_FILE; t.in_type++) {
      res = run_test(argc, argv, ++test_num, &t, fifos);
      /* Print the result to the driver */
      printf("%s %d - %s\n", res ? "not ok" : "ok",
	     test_num, summarize_test(&t));
      failed |= res;
      if (res == 99) break;
    }
    if (res == 99) break;
  }

 BAIL:
  if (res == 99) {
    /* Fatal error, tell the driver we gave up */
    printf("Bail out!\n");
  }

  /* Clean up and return the overall result */
  remove_files(fifos, MAX_READERS);
  return failed;
}
Пример #25
0
int get_output_files(Test *test, char ***out_files_out, int **out_fds_out) {
  char **out_files = NULL;
  int   *out_fds   = NULL;
  char  *tmpsuff   = "testXXXXXX";
  size_t tmplen    = strlen(P_tmpdir) + strlen(tmpsuff) + 2;
  unsigned int i   = 0;
  
  /* Create the out_files and out_fds arrays */
  out_files = calloc(test->nfiles, sizeof(char *));
  if (NULL == out_files) {
    perror(NULL);
    goto fail;
  }

  out_fds = malloc(test->nfiles * sizeof(int));
  if (NULL == out_fds) {
    perror(NULL);
    goto fail;
  }
  for (i = 0; i < test->nfiles; i++) out_fds[i] = -1;

  for (i = 0; i < test->nfiles; i++) {
    /* Allocate space for the name */
    out_files[i] = malloc(tmplen);
    if (NULL == out_files[i]) {
      perror(NULL);
      goto fail;
    }

    /* Try to make the file */
    snprintf(out_files[i], tmplen, "%s/%s", P_tmpdir, tmpsuff);

    out_fds[i] = mkstemp(out_files[i]);
    if (-1 == out_fds[i]) {
      fprintf(stderr, "Couldn't make temporary file %s : %s\n",
	      out_files[i], strerror(errno));
      free(out_files[i]);  /* Remove unused name on failure */
      out_files[i] = NULL;
      goto fail;
    }
  }

  /* Pass back the array locations */
  *out_files_out = out_files;
  *out_fds_out   = out_fds;
  return 0;

 fail:
  /* Clean up */
  if (NULL != out_files) {
    unsigned int j;

    if (i > 0) remove_files(out_files, i);

    for (j = 0; j < i; j++) {
      free(out_files[j]);
    }

    free(out_files);
  }
  if (NULL != out_fds) free(out_fds);
  return -1;
}
Пример #26
0
RETINFO_t *
map_and_thread(
    char  *tmpfile,              /* name of temporary file to be created      */
    void  *(*exec_func)(void *), /* thread function to execute                */
    int    fault_type,           /* type of fault to be generated             */
    int    num_thread,           /* number of threads to create               */
    RETINFO_t *retinfo)          /* return map address and oper status        */

{
    int  fd         = 0;         /* file descriptor of the file created       */
    int  thrd_ndx   = 0;         /* index to the number of threads created    */
    int  map_type   = 0;         /* specifies the type of the mapped object   */
    int  *th_status = 0;         /* status of the thread when it is finished  */
    long th_args[5];     	/* argument list passed to  thread_fault()   */
    char *empty_buf = NULL;      /* empty buffer used to fill temp file       */
    long pagesize                /* contains page size at runtime             */
                    = sysconf(_SC_PAGESIZE);
    static pthread_t pthread_ids[NUMTHREAD];
                                 /* contains ids of the threads created       */
    caddr_t map_addr = NULL;     /* address where the file is mapped          */

    /* Create a file with permissions 0666, and open it with RDRW perms       */
    /* if the name is not a NULL                                              */

    if (strcmp(tmpfile, "NULL"))
    {
        if ((fd = open(tmpfile, O_RDWR|O_CREAT, S_IRWXO|S_IRWXU|S_IRWXG))
                == -1 )
        {
            perror("map_and_thread(): open()");
            close(fd);
            fflush(NULL);
            retinfo->status = FAILED;
            return retinfo;
        }

        /* Write pagesize * pages_num bytes to the file */
        empty_buf = (char *)malloc(pagesize*pages_num);
        if (write(fd, empty_buf, pagesize*pages_num) != (pagesize*pages_num))
        {
            perror("map_and_thread(): write()");
            free(empty_buf);
            fflush(NULL);
            remove_files(tmpfile, NULL);
            close(fd);
            retinfo->status = FAILED;
            return retinfo;
        }
        map_type = (fault_type == COW_FAULT) ? MAP_PRIVATE : MAP_SHARED;

        /* Map the file, if the required fault type is COW_FAULT map the file */
        /* private, else map the file shared. if READ_FAULT is required to be */
        /* generated map the file with read protection else map with read -   */
        /* write protection.                               */

        if ((map_addr = (caddr_t)mmap(0, pagesize*pages_num,
                        ((fault_type == READ_FAULT) ?
			PROT_READ : PROT_READ|PROT_WRITE),
                        map_type, fd, 0))
		      == MAP_FAILED)
        {
            perror("map_and_thread(): mmap()");
            free(empty_buf);
            fflush(NULL);
            remove_files(tmpfile, NULL);
            close(fd);
            retinfo->status = FAILED;
            return retinfo;
        }
        else
        {
            retinfo->mapaddr = map_addr;
            if (verbose_print)
                tst_resm(TINFO,
                  "map_and_thread(): mmap success, address = %p", map_addr);
            fflush(NULL);
        }
    }

    /* As long as wait is set to TRUE, the thread that will be created will */
    /* loop in its exec routine */

    wait_thread = TRUE;

    /* Create a few threads, ideally number of threads equals number of CPU'S */
    /* so that we can assume that each thread will run on a single CPU in     */
    /* of SMP machines. Currently we will create NR_CPUS number of threads.   */

    th_args[1] = (long)map_addr;
    th_args[2] = pagesize;
    th_args[3] = fault_type;
    do
    {
        th_args[0] = thrd_ndx;
        th_args[4] = (long)0;

       /*************************************************************/
       /*   The way it was, args could be overwritten by subsequent uses
        *   of it before the called routine had a chance to fully initialize.
        *   This flag stops the overwrite until that routine gets to
        *   begin.  At that point, it is done initializing and it is
        *   safe for the this thread to continue (which will change
        *   args).
        *   A basic race condition.
        */
        thread_begin = TRUE;
        if (pthread_create(&pthread_ids[thrd_ndx++], NULL, exec_func,
                           (void *)&th_args))
        {
            perror("map_and_thread(): pthread_create()");
            thread_begin = FALSE;
            free(empty_buf);
            fflush(NULL);
            remove_files(tmpfile, map_addr);
            close(fd);
            retinfo->status = FAILED;
            return retinfo;
        } else {
            /***************************************************/
            /*   Yield until new thread is done with args.
             */
            while (thread_begin)
                sched_yield();
        }
    } while (thrd_ndx < num_thread);

    if (verbose_print)
        tst_resm(TINFO, "map_and_thread(): pthread_create() success");
    wait_thread = FALSE;
    th_status = malloc(sizeof(int *));

    /* suspend the execution of the calling thread till the execution of the  */
    /* other thread has been terminated.                                      */

    for (thrd_ndx = 0; thrd_ndx < NUMTHREAD; thrd_ndx++)
    {
        if (pthread_join(pthread_ids[thrd_ndx], (void **)th_status))
        {
            perror("map_and_thread(): pthread_join()");
            free(empty_buf);
            fflush(NULL);
            remove_files(tmpfile, map_addr);
            close(fd);
            retinfo->status = FAILED;
            return retinfo;
        }
        else
        {
            if ((int)*th_status == 1)
            {
                tst_resm(TINFO,
                        "thread [%ld] - process exited with errors",
                (long)pthread_ids[thrd_ndx]);
                free(empty_buf);
                remove_files(tmpfile, map_addr);
                close(fd);
                exit(1);
            }
        }
    }

    /* remove the temporary file that was created. - clean up                 */
    /* but dont try to remove special files.                                  */

    /***********************************************/
    /*   Was if !(remove_files()) ...
     *   If that routine succeeds, it returns SUCCESS, which
     *   happens to be 0.  So if the routine succeeded, the
     *   above condition would indicate failure.  This change
     *   fixes that.
     */
    if (remove_files(tmpfile, map_addr) == FAILED)
    {
        free(empty_buf);
        free(th_status);
        retinfo->status = FAILED;
        return retinfo;
    }

    free(empty_buf);
    free(th_status);
    close(fd);
    retinfo->status = SUCCESS;
    return retinfo;
}