예제 #1
0
int netmgr_remote_nd(int remote_nd, int local_nd) {
	netmgr_remote_nd_t			msg;

	if(ND_NODE_CMP(remote_nd, ND_LOCAL_NODE) == 0) {
		return(local_nd);
	}
	if(ND_NODE_CMP(remote_nd, local_nd) == 0) {
		return(ND_LOCAL_NODE);
	}

	msg.i.hdr.type = _IO_MSG;
	msg.i.hdr.combine_len = sizeof msg.i;
	msg.i.hdr.mgrid = _IOMGR_NETMGR;
	msg.i.hdr.subtype = _NETMGR_REMOTE_ND;
	msg.i.remote_nd = remote_nd;
	msg.i.local_nd = local_nd;
	return __netmgr_send(&msg.i, sizeof msg.i, 0, 0, 0, 0);
}
예제 #2
0
int
RTCFUNC(set,net)(struct tm *tm, int cent_reg) {
	struct timespec	times;

	if(ND_NODE_CMP(nd, ND_LOCAL_NODE)){
		fprintf(stderr,"Cannot set remote time on Neutrino (yet...)\n");
		return -1;
	}

	times.tv_sec = mktime(tm);
	times.tv_nsec = 0L;
	if(clock_settime( CLOCK_REALTIME, &times)==-1){
		perror("clock_settime");
		return(-1);
	}
	return(0);
}
예제 #3
0
/* 
 This is an override of the C library function which just does a _connect() call.
 Unfortunately this can lead to deadlock problems so proc queries the internal
 table first for the path, and if it isn't registered then fails.  If the connection
 exists then it attempts to establish a connection with that server, and that 
 server _only_.
*/
int _netmgr_connect(int base, const char *path, mode_t mode, unsigned oflag, unsigned sflag, 
					unsigned subtype, int testcancel, unsigned accessl, unsigned file_type, 
					unsigned extra_type, unsigned extra_len, const void *extra, 
					unsigned response_len, void *response, int *status) {
	struct _io_connect_entry    entry;
	struct node_entry			*node;
	union object				*o;
	char						*newpath;
	int							ret;
	size_t  slen = strlen(path) + 1;
	
	if(!(newpath = alloca(slen))) {
		errno = ENOMEM;
		return -1;
	}		
	memcpy(newpath, path, slen);	// '\0' guaranteed to be copied
	memset(&entry, 0, sizeof(entry));

	/* Perform the lookup in the pathmgr database */
	node = pathmgr_resolve_path(pathmgr_prp->root, NULL, newpath, pathmgr_prp->root);
	for(o = (node && *newpath == '\0') ? node->object : NULL; o; o = o->hdr.next) {
		/* NOTE: We can't call netmgr_remote_nd() here because it will cause deadlock
           so regardless of the client, we always require that the /dev/netmgr be local. */
		if(o->hdr.type == OBJECT_SERVER && ND_NODE_CMP(ND_LOCAL_NODE, o->server.nd) == 0) {
			entry.nd = ND_LOCAL_NODE /* netmgr_remote_nd(ND_LOCAL_NODE, o->server.nd) */;
			entry.pid = o->server.pid;
			entry.chid = o->server.chid;
			entry.handle = o->server.handle;
			entry.file_type = o->server.file_type;
			break;
		}
	}
	pathmgr_node_detach(node);

	if(!o) {
		return -1;
	}

	if(proc_thread_pool_reserve() != 0) {
		errno = EAGAIN;
		return -1;
	}
	ret = _connect_entry(base, path, mode, oflag, sflag, subtype, testcancel, accessl, file_type, extra_type, extra_len, extra, response_len, response, status, &entry, 1);
	proc_thread_pool_reserve_done();
	return ret;
}
예제 #4
0
static int wait_unblock(resmgr_context_t *ctp, io_pulse_t *msg, void *ocb) {
	PROCESS						*prp;
	struct _msg_info			info;
	pid_t						pid;

	pid = ctp->info.pid;
	if(ND_NODE_CMP(ctp->info.nd, ND_LOCAL_NODE) != 0) {
		/* unblock for wait over network */

		pid = pathmgr_netmgr_pid();
		if(pid == 0) {
			/* netmgr is gone */
			return _RESMGR_NOREPLY;
		}
	}

	if((prp = proc_lock_pid(pid))) {
		// msg will be NULL if we're called from wait_close_ocb()
		if(msg && ((MsgInfo(ctp->rcvid, &info) == -1) || !(info.flags & _NTO_MI_UNBLOCK_REQ))) {
			proc_unlock(prp);
			return _RESMGR_NOREPLY;
		}
		if((prp->flags & (_NTO_PF_LOADING | _NTO_PF_TERMING)) == 0) {
			struct wait_entry			*p, **pp;

			for(pp = &prp->wap; (p = *pp); pp = &p->next) {
				if(p->rcvid == ctp->rcvid) {
					*pp = p->next;

					if(prp->wap == NULL) {
						(void)_resmgr_unbind(&ctp->info);
					}
					MsgError(ctp->rcvid, EINTR);
					proc_object_free(&wait_souls, p);
					break;
				}
			}
		}
		proc_unlock(prp);
	}
	return _RESMGR_NOREPLY;
}
예제 #5
0
파일: dumper.c 프로젝트: vocho/openqnx
int dump(uint32_t nd, pid_t pid, long size ) {
	int							fd;
	int							ret;
	FILE						*fp;
	char						path[PATH_MAX + 1];
	char						buff[PATH_MAX + 1];
	struct _procfs_debug_info	*map = (struct _procfs_debug_info *)buff;
	uid_t						uid = 0;
	gid_t						gid = 0;
	procfs_info					info;

	if(pid == 0) {
		return ENOENT;
	}

	if(ND_NODE_CMP(nd, ND_LOCAL_NODE) && match_pid != -1 && match_pid != pid) {
		return ENXIO;
	}

	sprintf(buff, "/proc/%d/as", pid);
	if ( requested ) {
		if((fd = open(buff, O_RDWR|O_NONBLOCK)) == -1) {
			fprintf(stderr,"dumper: error attaching to process %d - %s\n", pid, strerror(errno) ); 
			return errno;
		}
		if ((ret = devctl(fd, DCMD_PROC_STOP, NULL, 0, 0)) != EOK) {
			vprintf(("failed PROC_STOP %s\n", strerror(ret) ));
			close(fd);
			return ret;
		}
	}
	else {
		if((fd = open(buff, O_RDONLY|O_NONBLOCK)) == -1) {
			return errno;
		}
	}

	if((ret = devctl(fd, DCMD_PROC_MAPDEBUG_BASE, map, sizeof buff, 0)) != EOK) {
		close(fd);
		return ret;
	}

	if((ret = devctl(fd, DCMD_PROC_INFO, &info, sizeof info, 0)) == EOK) {
		uid = geteuid();
		if ( uid != 0 && uid != info.uid ) {
			vprintf(("Permission Denied\n"));
			close(fd);
			return EPERM;
		}
		uid = info.euid;
		
		if(uid != info.uid) /* suid binary */
			gid=0;
		else
			gid = info.egid;
	}

	path[0] = '\0';
	if(nd != -1) {
		if(dump_dir) {
			strcpy(path, dump_dir);
		} else {
	  		struct passwd				*pwp;

			if((ret = devctl(fd, DCMD_PROC_INFO, &info, sizeof info, 0)) == EOK && (pwp = getpwuid(info.uid))) {
				strcpy(path, pwp->pw_dir);
			} else {
				strcpy(path, "/tmp");
			}

		}

		strcat(path, "/");
	}
	strcat(path, basename(map->path));
	dump_path = gen_dump_path(path);

	if (gzlevel == -1) {
		fp = fopen(dump_path, "w");
	} else {
		fp = (FILE *)gzopen(dump_path, "w");
		if (fp)
		  gzsetparams((gzFile)fp, gzlevel, 0);
	}
	
	if(!fp) {
		perror(dump_path);
		close(fd);
		return errno;
	}
	chown( dump_path, uid, gid );
	chmod( dump_path, world_readable ? 0644 : S_IRUSR|S_IWUSR );
	ret = elfcore(fd, fp, map->path, size);
	
	if (gzlevel == -1) {
		fclose(fp);
	} else {
		gzclose((gzFile)fp);
	}
	close(fd);



	return ret;
}
예제 #6
0
int procmgr_wait(resmgr_context_t *ctp, proc_wait_t *msg) {
	PROCESS						*prp, *child;
	struct wait_entry			*wap, **pwap, waitl;
	int							alive;

	if(ctp->info.flags & _NTO_MI_ENDIAN_DIFF) {
		ENDIAN_SWAP16(&msg->i.idtype);
		ENDIAN_SWAP32(&msg->i.options);
		ENDIAN_SWAP32(&msg->i.id);
	}
	if(msg->i.options & ~WOPTMASK) {
		return EINVAL;
	}
	waitl.rcvid = ctp->rcvid;
	waitl.idtype = msg->i.idtype;
	waitl.options = msg->i.options;
	waitl.id = msg->i.id;

	alive = 0;
	if(ND_NODE_CMP(ctp->info.nd, ND_LOCAL_NODE) != 0) {
		struct _client_info info;
		struct _cred_info *src, *dst;
		pid_t	nm_pid;

		if(ConnectClientInfo(ctp->info.scoid, &info, 0) == -1) {
			return errno;
		}

		nm_pid = pathmgr_netmgr_pid();
		if(nm_pid == 0) {
			/* netmgr is gone */
			return EL2HLT;
		}
		if(!(prp = proc_lock_pid(nm_pid))) {
			return EL2HLT;
		}

		src = &info.cred;

		for(child = prp->child; child; child = child->sibling) {
			if(child->pid != waitl.id) {
				continue;
			}
			/* security check */
			dst = &child->cred->info;
			if(!(src->euid == 0  ||
			   src->ruid == dst->ruid  ||
			   src->ruid == dst->suid  ||
			   src->euid == dst->ruid  ||
			   src->euid == dst->suid)) {
				return proc_error(EPERM, prp);
			}
			switch(procmgr_wait_check(child, prp, &waitl, 0)) {
			case 0:
				alive++;
				break;
			case -1:
				break;
			default:	
				return proc_error(_RESMGR_NOREPLY, prp);
			}
			if(alive) {
				break;
			}
		}
		if(alive == 0) {
			return proc_error(ECHILD, prp);
		}
	} else {
		if(!(prp = proc_lock_pid(ctp->info.pid))) {
			return EL2HLT;
		}

		for(child = prp->child; child; child = child->sibling) {
			switch(procmgr_wait_check(child, prp, &waitl, 0)) {
			case 0:
				alive++;
				break;
			case -1:
				break;
			default:	
				return proc_error(_RESMGR_NOREPLY, prp);
			}
		}

		//
		// If we're the guardian process for our parent, we'll pick up his
		// children when he dies so we need to see if there are any children
		// of our parent which might satisfy the wait condition in the
		// future and, if so, pretend like they're our children for the
		// purposes of the wait request.
		//
		if(prp->parent && prp->parent->guardian == prp) {
			if(procmgr_wait_check(prp->parent, prp, &waitl, 0) == 0) {
				alive++;
			}
		}

		if(alive == 0) {
			if(!prp->parent || prp->parent->guardian != prp || procmgr_wait_check(prp->parent, prp, &waitl, 0) != 0) {
				return proc_error(ECHILD, prp);
			}
		}
	}

	if(waitl.options & WNOHANG) {
		memset(&msg->o, 0x00, sizeof msg->o);
		return proc_error(_RESMGR_PTR(ctp, &msg->o, sizeof msg->o), prp);
	}
			
	// nothing waiting, so add to queue sorted so pid match has higher priority
	if(!(wap = proc_object_alloc(&wait_souls))) {
		return proc_error(ENOMEM, prp);
	}
	for(pwap = &prp->wap; (waitl.next = *pwap); pwap = &waitl.next->next) {
		if(waitl.next->idtype < waitl.idtype) {
			break;
		}
	}
	*wap = waitl;
	*pwap = wap;

	ctp->id = root_id;
	(void)resmgr_open_bind(ctp, wap, &proc_wait_funcs);
	return proc_error(_RESMGR_NOREPLY, prp);
}