void _sigchld(int sig, short what, void *data) {
  int pid;
  int *fds = (int *)data;

  printf("SIGCHLD\n");
  while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
    startproc(fds[1]);
  }
}
int main() {
  struct bufferevent *bev;
  int childfd[2];
  int pid;

  event_init();

  pipe(childfd);

  /* have a bufferevent watch our child's stdout */
  bev = bufferevent_new(childfd[0], bufread, NULL, NULL, "childwatch");
  bufferevent_enable(bev, EV_READ);
  startproc(childfd[1]);
  
  filewatch();

  struct event sigevent;
  signal_set(&sigevent, SIGCHLD, _sigchld, &childfd);
  signal_add(&sigevent, NULL);

  event_dispatch();

  return 0;
}
Example #3
0
/*
 * Process private IOCTL messages (typically from scctrl)
 */
int sc_ioctl(int card, scs_ioctl *data)
{
	int		status;
	RspMessage	*rcvmsg;
	char		*spid;
	char		*dn;
	char		switchtype;
	char		speed;

	rcvmsg = kmalloc(sizeof(RspMessage), GFP_KERNEL);
	if (!rcvmsg)
		return -ENOMEM;

	switch(data->command) {
	case SCIOCRESET:	/* Perform a hard reset of the adapter */
	{
		pr_debug("%s: SCIOCRESET: ioctl received\n",
			sc_adapter[card]->devicename);
		sc_adapter[card]->StartOnReset = 0;
		return (reset(card));
	}

	case SCIOCLOAD:
	{
		char *srec;

		srec = kmalloc(SCIOC_SRECSIZE, GFP_KERNEL);
		if (!srec) {
			kfree(rcvmsg);
			return -ENOMEM;
		}
		pr_debug("%s: SCIOLOAD: ioctl received\n",
				sc_adapter[card]->devicename);
		if(sc_adapter[card]->EngineUp) {
			pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n",
				sc_adapter[card]->devicename);
			kfree(rcvmsg);
			kfree(srec);
			return -1;
		}

		/*
		 * Get the SRec from user space
		 */
		if (copy_from_user(srec, data->dataptr, sizeof(srec))) {
			kfree(rcvmsg);
			kfree(srec);
			return -EFAULT;
		}

		status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc,
				0, sizeof(srec), srec, rcvmsg, SAR_TIMEOUT);
		kfree(rcvmsg);
		kfree(srec);

		if(status) {
			pr_debug("%s: SCIOCLOAD: command failed, status = %d\n", 
				sc_adapter[card]->devicename, status);
			return -1;
		}
		else {
			pr_debug("%s: SCIOCLOAD: command successful\n",
					sc_adapter[card]->devicename);
			return 0;
		}
	}

	case SCIOCSTART:
	{
		pr_debug("%s: SCIOSTART: ioctl received\n",
				sc_adapter[card]->devicename);
		if(sc_adapter[card]->EngineUp) {
			pr_debug("%s: SCIOCSTART: command failed, engine already running.\n",
				sc_adapter[card]->devicename);
			return -1;
		}

		sc_adapter[card]->StartOnReset = 1;
		startproc(card);
		return 0;
	}

	case SCIOCSETSWITCH:
	{
		pr_debug("%s: SCIOSETSWITCH: ioctl received\n",
				sc_adapter[card]->devicename);

		/*
		 * Get the switch type from user space
		 */
		if (copy_from_user(&switchtype, data->dataptr, sizeof(char))) {
			kfree(rcvmsg);
			return -EFAULT;
		}

		pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n",
			sc_adapter[card]->devicename,
			switchtype);
		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallSetSwitchType,
						0, sizeof(char),&switchtype, rcvmsg, SAR_TIMEOUT);
		if(!status && !(rcvmsg->rsp_status)) {
			pr_debug("%s: SCIOCSETSWITCH: command successful\n",
				sc_adapter[card]->devicename);
			kfree(rcvmsg);
			return 0;
		}
		else {
			pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n",
				sc_adapter[card]->devicename, status);
			kfree(rcvmsg);
			return status;
		}
	}
		
	case SCIOCGETSWITCH:
	{
		pr_debug("%s: SCIOGETSWITCH: ioctl received\n",
				sc_adapter[card]->devicename);

		/*
		 * Get the switch type from the board
		 */
		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 
			ceReqCallGetSwitchType, 0, 0, NULL, rcvmsg, SAR_TIMEOUT);
		if (!status && !(rcvmsg->rsp_status)) {
			pr_debug("%s: SCIOCGETSWITCH: command successful\n",
					sc_adapter[card]->devicename);
		}
		else {
			pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n",
				sc_adapter[card]->devicename, status);
			kfree(rcvmsg);
			return status;
		}

		switchtype = rcvmsg->msg_data.byte_array[0];

		/*
		 * Package the switch type and send to user space
		 */
		if (copy_to_user(data->dataptr, &switchtype,
				 sizeof(char))) {
			kfree(rcvmsg);
			return -EFAULT;
		}

		kfree(rcvmsg);
		return 0;
	}

	case SCIOCGETSPID:
	{
		pr_debug("%s: SCIOGETSPID: ioctl received\n",
				sc_adapter[card]->devicename);

		spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL);
		if(!spid) {
			kfree(rcvmsg);
			return -ENOMEM;
		}
		/*
		 * Get the spid from the board
		 */
		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetSPID,
					data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
		if (!status) {
			pr_debug("%s: SCIOCGETSPID: command successful\n",
					sc_adapter[card]->devicename);
		}
		else {
			pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
				sc_adapter[card]->devicename, status);
			kfree(rcvmsg);
			return status;
		}
		strcpy(spid, rcvmsg->msg_data.byte_array);

		/*
		 * Package the switch type and send to user space
		 */
		if (copy_to_user(data->dataptr, spid, SCIOC_SPIDSIZE)) {
			kfree(spid);
			kfree(rcvmsg);
			return -EFAULT;
		}

		kfree(spid);
		kfree(rcvmsg);
		return 0;
	}	

	case SCIOCSETSPID:
	{
		pr_debug("%s: DCBIOSETSPID: ioctl received\n",
				sc_adapter[card]->devicename);

		spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL);
		if(!spid) {
			kfree(rcvmsg);
			return -ENOMEM;
		}

		/*
		 * Get the spid from user space
		 */
		if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) {
			kfree(rcvmsg);
			return -EFAULT;
		}

		pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n", 
			sc_adapter[card]->devicename, data->channel, spid);
		status = send_and_receive(card, CEPID, ceReqTypeCall, 
			ceReqClass0, ceReqCallSetSPID, data->channel, 
			strlen(spid), spid, rcvmsg, SAR_TIMEOUT);
		if(!status && !(rcvmsg->rsp_status)) {
			pr_debug("%s: SCIOCSETSPID: command successful\n", 
				sc_adapter[card]->devicename);
			kfree(rcvmsg);
			kfree(spid);
			return 0;
		}
		else {
			pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n",
				sc_adapter[card]->devicename, status);
			kfree(rcvmsg);
			kfree(spid);
			return status;
		}
	}

	case SCIOCGETDN:
	{
		pr_debug("%s: SCIOGETDN: ioctl received\n",
				sc_adapter[card]->devicename);

		/*
		 * Get the dn from the board
		 */
		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber,
					data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
		if (!status) {
			pr_debug("%s: SCIOCGETDN: command successful\n",
					sc_adapter[card]->devicename);
		}
		else {
			pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n",
				sc_adapter[card]->devicename, status);
			kfree(rcvmsg);
			return status;
		}

		dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL);
		if (!dn) {
			kfree(rcvmsg);
			return -ENOMEM;
		}
		strcpy(dn, rcvmsg->msg_data.byte_array);
		kfree(rcvmsg);

		/*
		 * Package the dn and send to user space
		 */
		if (copy_to_user(data->dataptr, dn, SCIOC_DNSIZE)) {
			kfree(dn);
			return -EFAULT;
		}
		kfree(dn);
		return 0;
	}	

	case SCIOCSETDN:
	{
		pr_debug("%s: SCIOSETDN: ioctl received\n",
				sc_adapter[card]->devicename);

		dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL);
		if (!dn) {
			kfree(rcvmsg);
			return -ENOMEM;
		}
		/*
		 * Get the spid from user space
		 */
		if (copy_from_user(dn, data->dataptr, SCIOC_DNSIZE)) {
			kfree(rcvmsg);
			kfree(dn);
			return -EFAULT;
		}

		pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n", 
			sc_adapter[card]->devicename, data->channel, dn);
		status = send_and_receive(card, CEPID, ceReqTypeCall, 
			ceReqClass0, ceReqCallSetMyNumber, data->channel, 
			strlen(dn),dn,rcvmsg, SAR_TIMEOUT);
		if(!status && !(rcvmsg->rsp_status)) {
			pr_debug("%s: SCIOCSETDN: command successful\n", 
				sc_adapter[card]->devicename);
			kfree(rcvmsg);
			kfree(dn);
			return 0;
		}
		else {
			pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n",
				sc_adapter[card]->devicename, status);
			kfree(rcvmsg);
			kfree(dn);
			return status;
		}
	}

	case SCIOCTRACE:

		pr_debug("%s: SCIOTRACE: ioctl received\n",
				sc_adapter[card]->devicename);
/*		sc_adapter[card]->trace = !sc_adapter[card]->trace;
		pr_debug("%s: SCIOCTRACE: tracing turned %s\n",
				sc_adapter[card]->devicename,
			sc_adapter[card]->trace ? "ON" : "OFF"); */
		break;

	case SCIOCSTAT:
	{
		boardInfo *bi;

		pr_debug("%s: SCIOSTAT: ioctl received\n",
				sc_adapter[card]->devicename);

		bi = kmalloc (sizeof(boardInfo), GFP_KERNEL);
		if (!bi) {
			kfree(rcvmsg);
			return -ENOMEM;
		}

		kfree(rcvmsg);
		GetStatus(card, bi);

		if (copy_to_user(data->dataptr, bi, sizeof(boardInfo))) {
			kfree(bi);
			return -EFAULT;
		}

		kfree(bi);
		return 0;
	}

	case SCIOCGETSPEED:
	{
		pr_debug("%s: SCIOGETSPEED: ioctl received\n",
				sc_adapter[card]->devicename);

		/*
		 * Get the speed from the board
		 */
		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 
			ceReqCallGetCallType, data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
		if (!status && !(rcvmsg->rsp_status)) {
			pr_debug("%s: SCIOCGETSPEED: command successful\n",
				sc_adapter[card]->devicename);
		}
		else {
			pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n",
				sc_adapter[card]->devicename, status);
			kfree(rcvmsg);
			return status;
		}

		speed = rcvmsg->msg_data.byte_array[0];

		kfree(rcvmsg);

		/*
		 * Package the switch type and send to user space
		 */

		if (copy_to_user(data->dataptr, &speed, sizeof(char)))
			return -EFAULT;

		return 0;
	}

	case SCIOCSETSPEED:
		pr_debug("%s: SCIOCSETSPEED: ioctl received\n",
				sc_adapter[card]->devicename);
		break;

	case SCIOCLOOPTST:
		pr_debug("%s: SCIOCLOOPTST: ioctl received\n",
				sc_adapter[card]->devicename);
		break;

	default:
		kfree(rcvmsg);
		return -1;
	}

	kfree(rcvmsg);
	return 0;
}
Example #4
0
void
main(int argc, char *argv[])
{
	Filsys *fs;
	int ream, fsok;
	int newbufsize, nocheck;
	char buf[NAMELEN];
	int pid, ctl;

	progname = "kfs";
	procname = "init";

	/*
	 * insulate from invoker's environment and keep it from swapping
	 */
	rfork(RFNAMEG|RFNOTEG|RFREND);

	confinit();
	sfd = -1;
	ream = 0;
	newbufsize = 0;
	nocheck = 0;
	wrenfile = "/dev/sdC0/fs";

	pid = getpid();
	snprint(buf, sizeof buf, "/proc/%d/ctl", pid);
	ctl = open(buf, OWRITE);
	fprint(ctl, "noswap\n");
	close(ctl);

	buf[0] = '\0';

	ARGBEGIN{
	case 'b':
		newbufsize = atol(ARGF());
		break;
	case 'c':
		nocheck = 1;
		break;
	case 'f':
		wrenfile = ARGF();
		break;
	case 'm':
		nwren = atol(ARGF());
		break;
	case 'n':
		strncpy(buf, ARGF(), NAMELEN-1);
		buf[NAMELEN-1] = '\0';
		break;
	case 'p':
		cmdmode = atol(ARGF());
		break;
	case 'r':
		ream = 1;
		break;
	case 's':
		sfd = 0;
		rfd = dup(1, -1);
		close(1);
		if(open("/dev/cons", OWRITE) < 0)
			open("#c/cons", OWRITE);
		break;
	case 'B':
		conf.niobuf = strtoul(ARGF(), 0, 0);
		break;
	case 'C':
		chat = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 0)
		usage();

	cmdfd = 2;

	if (access(wrenfile, AREAD|AWRITE) == -1)
		sysfatal("%s cannot access device", wrenfile);

	formatinit();
	sublockinit();

	if(buf[0])
		sprint(service, "kfs.%s", buf);
	else
		strcpy(service, "kfs");
	chan = chaninit(service);
	consinit();
	tlocks = ialloc(NTLOCK * sizeof *tlocks);
	uid = ialloc(conf.nuid * sizeof(*uid));
	uidspace = ialloc(conf.uidspace * sizeof(*uidspace));
	gidspace = ialloc(conf.gidspace * sizeof(*gidspace));

	/*
	 * init global locks
	 */
	wlock(&mainlock); wunlock(&mainlock);

	/*
	 * init the file system, ream it if needed, and get the block sizes
	 */
	ream = fsinit(ream, newbufsize);
	iobufinit();
	for(fs=filesys; fs->name; fs++)
		if(fs->flags & FREAM){		/* set by fsinit if reamed */
			ream++;
			rootream(fs->dev, getraddr(fs->dev));
			superream(fs->dev, superaddr(fs->dev));
		}

	boottime = time(nil);

	consserve();
	fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0);
	if(!nocheck && !ream && !fsok)
		cmd_exec("check fq");

	startproc(forkserve, "srv");
	startproc(syncproc, "sync");

	exits(0);
}