Beispiel #1
0
static int sym_entry(const char *symname, void *ptr,
		     char *lib_from, char *lib_to, La_regs *regs)
{
	int argret = -1;
	char *argbuf = "", *argdbuf = "";
	struct timeval tv;
	struct lt_symbol *sym = NULL;

	PRINT_VERBOSE(&cfg, 2, "%s@%s\n", symname, lib_to);

	if (cfg.flow_below_cnt && !check_flow_below(symname, 1))
		return 0;

	if (lt_sh(&cfg, timestamp) || lt_sh(&cfg, counts))
		gettimeofday(&tv, NULL);

	if (lt_sh(&cfg, global_symbols))
		sym = lt_symbol_get(cfg.sh, ptr, symname);

#ifdef CONFIG_ARCH_HAVE_ARGS
	argret = lt_sh(&cfg, args_enabled) ?
		lt_args_sym_entry(cfg.sh, sym, regs, &argbuf, &argdbuf) : -1;
#endif

	if (lt_sh(&cfg, pipe)) {
		char buf[FIFO_MSG_MAXLEN];
		int len;

		if (!pipe_fd)
			pipe_fd = lt_fifo_create(&cfg, cfg.dir);

		len = lt_fifo_msym_get(&cfg, buf, FIFO_MSG_TYPE_ENTRY, &tv,
				(char*) symname, lib_to, argbuf, argdbuf);

		free_argbuf(argret, argbuf, argdbuf);
		return lt_fifo_send(&cfg, pipe_fd, buf, len);
	}

	indent_depth++;

	lt_out_entry(cfg.sh, &tv, syscall(SYS_gettid),
			indent_depth,
			symname, lib_to,
			argbuf, argdbuf);

	free_argbuf(argret, argbuf, argdbuf);
	return 0;
}
Beispiel #2
0
/*
 * release_files
 * Used to release files and directories and to set releaser
 * attributes for files and directories.
 *
 *
 * Attr Flags
 * RL_OPT_RECURSIVE
 * RL_OPT_NEVER
 * RL_OPT_WHEN_1
 * RL_OPT_PARTIAL
 * RL_OPT_DEFAULTS
 *
 * If any attrubute other than RL_OPT_RECURSIVE is specified the disk space
 * will not be released. Instead the indicated attributes will be set
 * for each file in the file list.
 *
 * The RL_OPT_NEVER & RL_OPT_ALWAYS_WHEN_1 are
 * mutually exclusive.
 *
 * PARAMS:
 *   sqm_lst_t  *files,	 IN - list of fully quallified file names
 *   int32_t options	 IN - bit fields indicate release options (see above).
 *   int32_t *partial_sz IN -
 * RETURNS:
 *   success -  0	operation successfully issued release not necessarily
 *			complete.
 *   error   -  -1
 */
int
release_files(ctx_t *c /* ARGSUSED */, sqm_lst_t *files, int32_t options,
    int32_t partial_sz, char **job_id) {

	char		buf[32];
	char		**command;
	node_t		*n;
	argbuf_t 	*arg;
	size_t		len = MAXPATHLEN * 2;
	boolean_t	found_one = B_FALSE;
	pid_t		pid;
	int		ret;
	int		status;
	FILE		*out;
	FILE		*err;
	exec_cleanup_info_t *cl;
	char release_s_buf[32];
	int arg_cnt;
	int cur_arg = 0;

	if (ISNULL(files, job_id)) {
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}


	/*
	 * Determine how many args to the command and create the command
	 * array. Note that command is malloced because the number of files
	 * is not known prior to execution. The arguments themselves need
	 * not be malloced because the child process will get a copy.
	 * Include space in the command array for:
	 * - the command
	 * - all possible options
	 * - an entry for each file in the list.
	 * - entry for the NULL
	 */
	arg_cnt = 1 + 6 + files->length + 1;
	command = (char **)calloc(arg_cnt, sizeof (char *));
	if (command == NULL) {
		setsamerr(SE_NO_MEM);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}
	command[cur_arg++] = RELEASE_FILES_CMD;

	*buf = '\0';
	if (partial_sz) {
		snprintf(release_s_buf, sizeof (release_s_buf), "-s%d ",
		    partial_sz);
		command[cur_arg++] = release_s_buf;
	}
	if (options & RL_OPT_NEVER) {
		command[cur_arg++] = "-n";
	}
	if (options & RL_OPT_WHEN_1) {
		command[cur_arg++] = "-a";
	}
	if (options & RL_OPT_PARTIAL) {
		command[cur_arg++] = "-p";
	}
	if (options & RL_OPT_DEFAULTS) {
		command[cur_arg++] = "-d";
	}
	/* Recursive must be specified last */
	if (options & RL_OPT_RECURSIVE) {
		command[cur_arg++] = "-r";
	}

	/* make the argument buffer for the activity */
	arg = (argbuf_t *)mallocer(sizeof (releasebuf_t));
	if (arg == NULL) {
		free(command);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}

	arg->rl.filepaths = lst_create();
	if (arg->rl.filepaths == NULL) {
		free(command);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}
	arg->rl.options = options;
	arg->rl.partial_sz = partial_sz;

	/* add the file names to the cmd string and the argument buffer */
	for (n = files->head; n != NULL; n = n->next) {
		if (n->data != NULL) {
			char *cur_file;
			command[cur_arg++] = (char *)n->data;

			found_one = B_TRUE;
			cur_file = copystr(n->data);
			if (cur_file == NULL) {
				free(command);
				free_argbuf(SAMA_RELEASEFILES, arg);
				Trace(TR_ERR, "release files failed:%s",
				    samerrmsg);
				return (-1);
			}
			if (lst_append(arg->rl.filepaths, cur_file) != 0) {
				free(command);
				free(cur_file);
				free_argbuf(SAMA_RELEASEFILES, arg);
				Trace(TR_ERR, "release files failed:%s",
				    samerrmsg);
				return (-1);
			}
		}
	}

	/*
	 * Check that at least one file was found.
	 */
	if (!found_one) {
		free(command);
		free_argbuf(SAMA_RELEASEFILES, arg);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}

	/* create the activity */
	ret = start_activity(display_release_activity, kill_fork,
	    SAMA_RELEASEFILES, arg, job_id);
	if (ret != 0) {
		free(command);
		free_argbuf(SAMA_RELEASEFILES, arg);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}

	/*
	 * create the cleanup struct prior to the exec because it is
	 * easier to cleanup here  if the malloc fails.
	 */
	cl = (exec_cleanup_info_t *)mallocer(sizeof (exec_cleanup_info_t));
	if (cl == NULL) {
		free(command);
		lst_free_deep(arg->rl.filepaths);
		end_this_activity(*job_id);
		Trace(TR_ERR, "release files failed, error:%d %s",
		    samerrno, samerrmsg);
		return (-1);
	}

	/* exec the process */
	pid = exec_mgmt_cmd(&out, &err, command);
	if (pid < 0) {
		free(command);
		lst_free_deep(arg->rl.filepaths);
		end_this_activity(*job_id);
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	}
	free(command);
	set_pid_or_tid(*job_id, pid, 0);


	/* setup struct for call to cleanup */
	strlcpy(cl->func, RELEASE_FILES_CMD, sizeof (cl->func));
	cl->pid = pid;
	strlcpy(cl->job_id, *job_id, MAXNAMELEN);
	cl->streams[0] = out;
	cl->streams[1] = err;


	/* possibly return the results or async notification */
	ret = bounded_activity_wait(&status, 10, *job_id, pid, cl,
	    cleanup_after_exec_get_output);

	if (ret == -1) {
		samerrno = SE_RELEASE_FILES_FAILED;
		snprintf(samerrmsg, MAX_MSG_LEN,
		    GetCustMsg(SE_RELEASE_FILES_FAILED));

		free(*job_id);
		*job_id = NULL;
		Trace(TR_ERR, "release files failed:%s", samerrmsg);
		return (-1);
	} else if (ret == 0) {
		/*
		 * job_id was set by start_activity. Clear it now
		 * so that the caller knows the request has been submitted.
		 */
		free(*job_id);
		*job_id = NULL;
		Trace(TR_MISC, "release files completed");
	}

	Trace(TR_MISC, "leaving release files");
	return (0);
}