コード例 #1
0
/**
 * call_usermodehelper_keys - start a usermode application
 * @path: pathname for the application
 * @argv: null-terminated argument list
 * @envp: null-terminated environment list
 * @session_keyring: session keyring for process (NULL for an empty keyring)
 * @wait: wait for the application to finish and return status.
 *
 * Runs a user-space application.  The application is started
 * asynchronously if wait is not set, and runs as a child of keventd.
 * (ie. it runs with full root capabilities).
 *
 * Must be called from process context.  Returns a negative error code
 * if program was not execed successfully, or 0.
 */
int call_usermodehelper_keys(char *path, char **argv, char **envp,
			     struct key *session_keyring, int wait)
{
	DECLARE_COMPLETION(done);
	struct subprocess_info sub_info = {
		.complete	= &done,
		.path		= path,
		.argv		= argv,
		.envp		= envp,
		.ring		= session_keyring,
		.wait		= wait,
		.retval		= 0,
	};

	DECLARE_WORK(work, __call_usermodehelper, &sub_info);

	OSA_REGISTER_SPINLOCK(&done.wait.lock, "wait_queue_head_t->lock", 23);

	if (!khelper_wq)
		return -EBUSY;

	if (path[0] == '\0')
		return 0;

	queue_work(khelper_wq, &work);
	wait_for_completion(&done);
	return sub_info.retval;
}
EXPORT_SYMBOL(call_usermodehelper_keys);

void __init usermodehelper_init(void)
{
	khelper_wq = create_singlethread_workqueue("khelper");
	BUG_ON(!khelper_wq);
}
コード例 #2
0
ファイル: scsi_ioctl.c プロジェクト: sarnobat/knoppix
static int blk_do_rq(request_queue_t *q, struct block_device *bdev, 
		     struct request *rq)
{
	char sense[SCSI_SENSE_BUFFERSIZE];
	DECLARE_COMPLETION(wait);
	int err = 0;

	rq->rq_disk = bdev->bd_disk;

	/*
	 * we need an extra reference to the request, so we can look at
	 * it after io completion
	 */
	rq->ref_count++;

	if (!rq->sense) {
		memset(sense, 0, sizeof(sense));
		rq->sense = sense;
		rq->sense_len = 0;
	}

	rq->flags |= REQ_NOMERGE;
	rq->waiting = &wait;
	elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
	generic_unplug_device(q);
	wait_for_completion(&wait);

	if (rq->errors)
		err = -EIO;

	return err;
}
コード例 #3
0
int start_sync_thread(int state, char *mcast_ifn)
{
	DECLARE_COMPLETION(startup);
	pid_t pid;

	if (sync_pid)
		return -EEXIST;

	IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
	IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %d bytes\n",
		  sizeof(struct ip_vs_sync_conn));

	ip_vs_sync_state = state;
	strcpy(ip_vs_mcast_ifn, mcast_ifn);

  repeat:
	if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) {
		IP_VS_ERR("could not create fork_sync_thread due to %d... "
			  "retrying.\n", pid);
		current->state = TASK_UNINTERRUPTIBLE;
		schedule_timeout(HZ);
		goto repeat;
	}

	wait_for_completion(&startup);

	return 0;
}
コード例 #4
0
ファイル: tbio.c プロジェクト: Altiscale/sig-core-t_ltp
static int send_request(request_queue_t * q, struct bio *bio,
			struct block_device *bdev, struct tbio_interface *inter,
			int writing)
{
	struct request *rq;
	void *buffer = NULL;
	unsigned long start_time;
	int err;

	rq = blk_get_request(q, writing ? WRITE : READ, __GFP_WAIT);
	rq->cmd_len = inter->cmd_len;
	//printk("inter.cmd %s\n" , inter->cmd);
	if (copy_from_user(rq->cmd, inter->cmd, inter->cmd_len))
		goto out_request;
	//printk("tbio: rq->cmd : %s\n",rq->cmd);
	if (sizeof(rq->cmd) != inter->cmd_len)
		memset(rq->cmd + inter->cmd_len, 0,
		       sizeof(rq->cmd) - inter->cmd_len);

	rq->bio = rq->biotail = NULL;

	blk_rq_bio_prep(q, rq, bio);

	rq->data = buffer;
	rq->data_len = inter->data_len;

	rq->timeout = 0;
	if (!rq->timeout)
		rq->timeout = q->sg_timeout;
	if (!rq->timeout)
		rq->timeout = BLK_DEFAULT_TIMEOUT;

	start_time = jiffies;

	DECLARE_COMPLETION(wait);

	rq->rq_disk = bdev->bd_disk;

	rq->waiting = &wait;
	elv_add_request(q, rq, 1, 1);
	generic_unplug_device(q);
	wait_for_completion(&wait);
	//printk("tbio: completion\n");
	if (rq->errors) {
		err = -EIO;
		printk("tbio: rq->errors\n");
		return err;
	}

	blk_put_request(rq);

	return 0;
out_request:
	blk_put_request(rq);
	return -EFAULT;

}
コード例 #5
0
int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
    DECLARE_COMPLETION(complete);

    mrq->done_data = &complete;
    mrq->done = mmc_wait_done;

    mmc_start_request(host, mrq);

    wait_for_completion(&complete);

    return 0;
}
コード例 #6
0
static int erase_write (struct mtd_info *mtd, unsigned long pos,
			int len, const char *buf)
{
	struct erase_info erase = {};
	DECLARE_COMPLETION(erase_completion);
	size_t retlen;
	int ret;

	/*
	 * First, let's erase the flash block.
	 */

	erase.mtd = mtd;
	erase.priv = (u_long)&erase_completion;
	erase.callback = erase_callback;
	erase.addr = pos;
	erase.len = len;


	ret = mtd->erase(mtd, &erase);
	if (ret) {
		printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "
				     "on \"%s\" failed\n",
			pos, len, mtd->name);
		return ret;
	}

	wait_for_completion_interruptible(&erase_completion);

	/*
	 * Next, writhe data to flash.
	 */

	ret = mtd->write(mtd, pos, len, &retlen, buf);
	if (ret)
		return ret;
	if (retlen != len)
		return -EIO;
	return 0;
}
コード例 #7
0
ファイル: kmod.c プロジェクト: rroart/freevms
/**
 * call_usermodehelper - start a usermode application
 * @path: pathname for the application
 * @argv: null-terminated argument list
 * @envp: null-terminated environment list
 *
 * Runs a user-space application.  The application is started asynchronously.  It
 * runs as a child of keventd.  It runs with full root capabilities.  keventd silently
 * reaps the child when it exits.
 *
 * Must be called from process context.  Returns zero on success, else a negative
 * error code.
 */
int call_usermodehelper(char *path, char **argv, char **envp)
{
    DECLARE_COMPLETION(work);
    struct subprocess_info sub_info =
    {
complete:
        &work,
path:
        path,
argv:
        argv,
envp:
        envp,
        retval:		0,
    };
    struct tq_struct tqs =
    {
routine:
        __call_usermodehelper,
data:
        &sub_info,
    };
コード例 #8
0
ファイル: hub.c プロジェクト: NieHao/Tomato-RAF
/*
 * This should be a separate module.
 */
int usb_hub_init(void)
{
    DECLARE_COMPLETION(startup);

    if (usb_register(&hub_driver) < 0) {
        err("Unable to register USB hub driver");
        return -1;
    }

    if (kernel_thread(usb_hub_thread, &startup,
                      CLONE_FS | CLONE_FILES | CLONE_SIGHAND) >= 0) {
        wait_for_completion(&startup);

        return 0;
    }

    /* Fall through if kernel_thread failed */
    usb_deregister(&hub_driver);
    err("failed to start usb_hub_thread");

    return -1;
}
コード例 #9
0
ファイル: xixfs_callbacks.c プロジェクト: cpady/ndas4linux
int
xixcore_call
xixcore_HaveLotLock(
	uint8		* HostMac,
	uint8		* LockOwnerMac,
	uint64		LotNumber,
	uint8		* VolumeId,
	uint8		* LockOwnerId
)
{
	// Request LotLock state to Lock Owner
	
	
	int							RC = 0;
	PXIXFSDG_PKT				pPacket = NULL;
	PXIXFS_LOCK_REQUEST		pPacketData = NULL;
	int							waitStatus = LOCK_INVALID;						
	DECLARE_COMPLETION(wait);
	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("Enter xixfs_AreYouHaveLotLock \n"));

	
	 RC = xixfs_AllocDGPkt(
					&pPacket, 
					HostMac, 
					LockOwnerMac, 
					XIXFS_TYPE_LOCK_REQUEST
					) ;
	 
	if(RC < 0  )
	{
		DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
			("Error (0x%x) xixfs_AreYouHaveLotLock:xixfs_AllocDGPkt  \n",
				RC));
		
		return RC;
	}

	

	// Changed by ILGU HONG
	//	chesung suggest
	
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("Packet Dest Info  [0x%02x:%02x:%02x:%02x:%02x:%02x]\n",
		LockOwnerMac[26], LockOwnerMac[27], LockOwnerMac[28],
		LockOwnerMac[29], LockOwnerMac[30], LockOwnerMac[31]));

	pPacketData = &(pPacket->RawDataDG.LockReq);
	memcpy(pPacketData->LotOwnerID, LockOwnerId, 6);
	// Changed by ILGU HONG
	//	chesung suggest
	memcpy(pPacketData->VolumeId, VolumeId, 16);
	memcpy(pPacketData->LotOwnerMac, LockOwnerMac, 32);
	pPacketData->LotNumber = XI_HTONLL(LotNumber);
	pPacketData->PacketNumber = XI_HTONL(atomic_read(&(xixfs_linux_global.EventCtx.PacketNumber)));
	atomic_inc(&(xixfs_linux_global.EventCtx.PacketNumber));

	pPacket->TimeOut = xixcore_GetCurrentTime64()+ DEFAULT_REQUEST_MAX_TIMEOUT;
	pPacket->PkCtl.PktCompletion = &wait;
	pPacket->PkCtl.status=&waitStatus;


	printk(KERN_DEBUG "WAIT lock request\n");
	xixfs_Pkt_add_sendqueue(
			&xixfs_linux_global.EventCtx,
			pPacket 
			);
	
	wait_for_completion(&wait);
	
	printk(KERN_DEBUG "END WAIT lock request\n");
	
	if(waitStatus == LOCK_OWNED_BY_OWNER){
		DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit xixfs_AreYouHaveLotLock Lock is realy acquired by other \n"));
		return 1;
	}else{
		DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit XifsdAreYouHaveLotLock Lock is status(0x%x) \n", waitStatus));
		return 0;
	}
}
コード例 #10
0
/*
 * This is the task which runs the usermode application
 */
static int ____call_usermodehelper(void *data)
{
	struct subprocess_info *sub_info = data;
	int retval;

	/* Install input pipe when needed */
	if (sub_info->stdin) {
		struct files_struct *f = current->files;
		struct fdtable *fdt;
		/* no races because files should be private here */
		sys_close(0);
		fd_install(0, sub_info->stdin);
		spin_lock(&f->file_lock);
		fdt = files_fdtable(f);
		FD_SET(0, fdt->open_fds);
		FD_CLR(0, fdt->close_on_exec);
		spin_unlock(&f->file_lock);

		/* and disallow core files too */
		current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
	}
 

	/* We can run anywhere, unlike our parent keventd(). */
	set_cpus_allowed(current, CPU_MASK_ALL);

	retval = __exec_usermodehelper(sub_info->path,
			sub_info->argv, sub_info->envp, sub_info->ring);

	/* Exec failed? */
	sub_info->retval = retval;
	do_exit(0);
}

/* Keventd can't block, but this (a child) can. */
static int wait_for_helper(void *data)
{
	struct subprocess_info *sub_info = data;
	pid_t pid;
	struct k_sigaction sa;

	/* Install a handler: if SIGCLD isn't handled sys_wait4 won't
	 * populate the status, but will return -ECHILD. */
	sa.sa.sa_handler = SIG_IGN;
	sa.sa.sa_flags = 0;
	siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
	do_sigaction(SIGCHLD, &sa, NULL);
	allow_signal(SIGCHLD);

	pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
	if (pid < 0) {
		sub_info->retval = pid;
	} else {
		/*
		 * Normally it is bogus to call wait4() from in-kernel because
		 * wait4() wants to write the exit code to a userspace address.
		 * But wait_for_helper() always runs as keventd, and put_user()
		 * to a kernel address works OK for kernel threads, due to their
		 * having an mm_segment_t which spans the entire address space.
		 *
		 * Thus the __user pointer cast is valid here.
		 */
		sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL);
	}

	complete(sub_info->complete);
	return 0;
}

/* This is run by khelper thread  */
static void __call_usermodehelper(void *data)
{
	struct subprocess_info *sub_info = data;
	pid_t pid;
	int wait = sub_info->wait;

	/* CLONE_VFORK: wait until the usermode helper has execve'd
	 * successfully We need the data structures to stay around
	 * until that is done.  */
	if (wait)
		pid = kernel_thread(wait_for_helper, sub_info,
				    CLONE_FS | CLONE_FILES | SIGCHLD);
	else
		pid = kernel_thread(____call_usermodehelper, sub_info,
				    CLONE_VFORK | SIGCHLD);

	if (pid < 0) {
		sub_info->retval = pid;
		complete(sub_info->complete);
	} else if (!wait)
		complete(sub_info->complete);
}

/**
 * call_usermodehelper_keys - start a usermode application
 * @path: pathname for the application
 * @argv: null-terminated argument list
 * @envp: null-terminated environment list
 * @session_keyring: session keyring for process (NULL for an empty keyring)
 * @wait: wait for the application to finish and return status.
 *
 * Runs a user-space application.  The application is started
 * asynchronously if wait is not set, and runs as a child of keventd.
 * (ie. it runs with full root capabilities).
 *
 * Must be called from process context.  Returns a negative error code
 * if program was not execed successfully, or 0.
 */
int call_usermodehelper_keys(char *path, char **argv, char **envp,
			     struct key *session_keyring, int wait)
{
	DECLARE_COMPLETION_ONSTACK(done);
	struct subprocess_info sub_info = {
		.complete	= &done,
		.path		= path,
		.argv		= argv,
		.envp		= envp,
		.ring		= session_keyring,
		.wait		= wait,
		.retval		= 0,
	};
	DECLARE_WORK(work, __call_usermodehelper, &sub_info);

	if (!khelper_wq)
		return -EBUSY;

	if (path[0] == '\0')
		return 0;

	queue_work(khelper_wq, &work);
	wait_for_completion(&done);
	return sub_info.retval;
}
EXPORT_SYMBOL(call_usermodehelper_keys);

int call_usermodehelper_pipe(char *path, char **argv, char **envp,
			     struct file **filp)
{
	DECLARE_COMPLETION(done);
	struct subprocess_info sub_info = {
		.complete	= &done,
		.path		= path,
		.argv		= argv,
		.envp		= envp,
		.retval		= 0,
	};
	struct file *f;
	DECLARE_WORK(work, __call_usermodehelper, &sub_info);

	if (!khelper_wq)
		return -EBUSY;

	if (path[0] == '\0')
		return 0;

	f = create_write_pipe();
	if (!f)
		return -ENOMEM;
	*filp = f;

	f = create_read_pipe(f);
	if (!f) {
		free_write_pipe(*filp);
		return -ENOMEM;
	}
	sub_info.stdin = f;

	queue_work(khelper_wq, &work);
	wait_for_completion(&done);
	return sub_info.retval;
}
EXPORT_SYMBOL(call_usermodehelper_pipe);

void __init usermodehelper_init(void)
{
	khelper_wq = create_singlethread_workqueue("khelper");
	BUG_ON(!khelper_wq);
}