Пример #1
0
func (gpio *GPIO) AddEdgeDetect(edge GPIOEdge) (chan bool, error) {
	gpio.RemoveEdgeDetect()

	err := gpio.SetDirection(GPIO_INPUT)
	if err != nil {
		return nil, err
	}
	err = gpio.SetEdge(edge)
	if err != nil {
		return nil, err
	}
	err = gpio.openValueFile()
	if err != nil {
		return nil, err
	}

	epfd, err := syscall.EpollCreate(1)
	if err != nil {
		return nil, err
	}

	event := &syscall.EpollEvent{
		Events: syscall.EPOLLIN | _EPOLLET | syscall.EPOLLPRI,
		Fd:     int32(gpio.value.Fd()),
	}
	err = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, int(gpio.value.Fd()), event)
	if err != nil {
		syscall.Close(epfd)
		return nil, err
	}

	// / first time triggers with current state, so ignore
	_, err = syscall.EpollWait(epfd, make([]syscall.EpollEvent, 1), -1)
	if err != nil {
		syscall.Close(epfd)
		return nil, err
	}

	gpio.epfd.Set(epfd)

	valueChan := make(chan bool)
	go func() {
		for gpio.epfd.Get() != 0 {
			n, _ := syscall.EpollWait(epfd, make([]syscall.EpollEvent, 1), -1)
			if n > 0 {
				value, err := gpio.Value()
				if err == nil {
					valueChan <- value
				}
			}
		}
	}()
	return valueChan, nil
}
Пример #2
0
func newpollster() (p *pollster, err os.Error) {
	p = new(pollster)
	var e int

	// The arg to epoll_create is a hint to the kernel
	// about the number of FDs we will care about.
	// We don't know.
	if p.epfd, e = syscall.EpollCreate(16); e != 0 {
		return nil, os.NewSyscallError("epoll_create", e)
	}
	p.events = make(map[int]uint32)
	return p, nil
}
Пример #3
0
// epollinit opens an epoll file descriptor and creates a pipe which will be
// used to wake up the epoll_wait(2) function. Then, file descriptor associated
// with inotify event queue and the read end of the pipe are added to epoll set.
// Note that `fd` member must be set before this function is called.
func (i *inotify) epollinit() (err error) {
	if i.epfd, err = syscall.EpollCreate(2); err != nil {
		return
	}
	if err = syscall.Pipe(i.pipefd); err != nil {
		return
	}
	i.epes = []syscall.EpollEvent{
		{Events: syscall.EPOLLIN, Fd: i.fd},
		{Events: syscall.EPOLLIN, Fd: int32(i.pipefd[0])},
	}
	if err = syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, int(i.fd), &i.epes[0]); err != nil {
		return
	}
	return syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, i.pipefd[0], &i.epes[1])
}
Пример #4
0
func newpollster() (p *pollster, err error) {
	p = new(pollster)
	if p.epfd, err = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC); err != nil {
		if err != syscall.ENOSYS {
			return nil, os.NewSyscallError("epoll_create1", err)
		}
		// The arg to epoll_create is a hint to the kernel
		// about the number of FDs we will care about.
		// We don't know, and since 2.6.8 the kernel ignores it anyhow.
		if p.epfd, err = syscall.EpollCreate(16); err != nil {
			return nil, os.NewSyscallError("epoll_create", err)
		}
		syscall.CloseOnExec(p.epfd)
	}
	p.events = make(map[int]uint32)
	return p, nil
}
Пример #5
0
func Run(t *Tunnel) {
	var err error
	epollFd, err = syscall.EpollCreate(1024)
	if err != nil {
		logger.Log(logger.ERR, "Create epoll fd error [%s]", err)
		os.Exit(-2)
	}

	for _, step := range initStep {
		err = step.Action(t)
		if err != nil {
			fmt.Fprintf(os.Stderr, step.ErrFmt, err)
			os.Exit(-2)
		}
	}
	runTunnel = t

	events := make([]syscall.EpollEvent, 10, 10)
	for {
		en, err := syscall.EpollWait(epollFd, events, 1000)
		if err != nil {
			logger.Log(logger.ERR, "Wail epoll fd error [%s]", err)
			os.Exit(-2)
		}
		for i := 0; i < en; i++ {
			ee := events[i]
			if runTunnel.LFd == int(ee.Fd) {
				runTunnel.newConn()
				continue
			}
			tc, ok := fdTunnelConn[int(ee.Fd)]
			if !ok {
				continue
			}
			if ee.Events&syscall.EPOLLIN != 0 {
				tc.handleIn(int(ee.Fd))
			}
			if ee.Events&syscall.EPOLLOUT != 0 {
				tc.handleOut(int(ee.Fd))
			}
			if ee.Events&syscall.EPOLLHUP != 0 {
				tc.shutdown()
			}
		}
	}
}
Пример #6
0
// Create a new inotify poller.
// This creates an inotify handler, and an epoll handler.
func newFdPoller(fd int) (*fdPoller, error) {
	var errno error
	poller := emptyPoller(fd)
	defer func() {
		if errno != nil {
			poller.close()
		}
	}()
	poller.fd = fd

	// Create epoll fd
	poller.epfd, errno = syscall.EpollCreate(1)
	if poller.epfd == -1 {
		return nil, errno
	}
	// Create pipe; pipe[0] is the read end, pipe[1] the write end.
	errno = syscall.Pipe2(poller.pipe[:], syscall.O_NONBLOCK)
	if errno != nil {
		return nil, errno
	}

	// Register inotify fd with epoll
	event := syscall.EpollEvent{
		Fd:     int32(poller.fd),
		Events: syscall.EPOLLIN,
	}
	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event)
	if errno != nil {
		return nil, errno
	}

	// Register pipe fd with epoll
	event = syscall.EpollEvent{
		Fd:     int32(poller.pipe[0]),
		Events: syscall.EPOLLIN,
	}
	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event)
	if errno != nil {
		return nil, errno
	}

	return poller, nil
}
Пример #7
0
func (gpio *GPIO) WaitForEdge(edge Edge) (value Value, err error) {
	if err = gpio.setEdge(edge); err != nil {
		return 0, err
	}
	if err = gpio.ensureValueFileIsOpen(); err != nil {
		return 0, err
	}

	epollFd := gpio.epollFd.Get()

	if epollFd == 0 {
		epollFd, err = syscall.EpollCreate(1)
		if err != nil {
			return 0, err
		}

		event := &syscall.EpollEvent{
			Events: syscall.EPOLLIN | syscall.EPOLLPRI | _EPOLLET,
			Fd:     int32(gpio.valueFile.Fd()),
		}
		err = syscall.EpollCtl(epollFd, syscall.EPOLL_CTL_ADD, int(gpio.valueFile.Fd()), event)
		if err != nil {
			syscall.Close(epollFd)
			return 0, err
		}

		// first time triggers with current state, so ignore
		_, err = syscall.EpollWait(epollFd, dummyEpollEvents, -1)
		if err != nil {
			syscall.Close(epollFd)
			return 0, err
		}

		gpio.epollFd.Set(epollFd)
	}

	_, err = syscall.EpollWait(epollFd, dummyEpollEvents, -1)
	if err != nil {
		return 0, err
	}
	return gpio.Value()
}
Пример #8
0
func init_inotify() {
	var err error

	name_by_wd = make(map[int32]string)
	wd_by_name = make(map[string]int32)
	var event syscall.InotifyEvent
	event_size = int(unsafe.Sizeof(event))
	inotify_fd, _ = syscall.InotifyInit()
	if -1 == inotify_fd {
		bump_message("InotifyInit failed, file changes outside of tabby " +
			"will remain unnoticed")
		return
	}
	epoll_fd, err = syscall.EpollCreate(1)
	if -1 == epoll_fd {
		tabby_log("init_inotify: " + err.Error())
	}
	var epoll_event syscall.EpollEvent
	epoll_event.Events = syscall.EPOLLIN
	syscall.EpollCtl(epoll_fd, syscall.EPOLL_CTL_ADD, inotify_fd, &epoll_event)
	go inotify_observe()
}
Пример #9
0
func StartProxyServer(conf *ProxyConfig, proxy_log l4g.Logger) (err error) {
	logger = proxy_log

	var filter *IOFilterProtocol
	var netio *NetIOManager

	proxy := &ProxyServer{
		max_listen_fds: 1024,
		timeout:        1000,
		quit:           false,
		epoll_fd:       -1,
		events:         make([]syscall.EpollEvent, 100),
		sighnd:         make(chan os.Signal, 1),
	}

	if !parse_config(proxy, conf) {
		logger.Error("Failed to initialize proxy server.")
		goto Error
	}

	filter = NewIOFilterProtocol(conf)
	if filter == nil {
		logger.Error("Failed to initialize filter protocol.")
		goto Error
	} else {
		if filter.FilterEnabled() {
			go filter.MonitQuotaFiles()
			go filter.MonitQuotaDataSize()
		}
	}

	netio = NewNetIOManager()
	netio.SetFilter(filter)

	proxy.epoll_fd, err = syscall.EpollCreate(proxy.max_listen_fds)
	if err != nil {
		logger.Critical("Failed to initialize epoll listener [%s].", err)
		goto Cleanup
	}
	netio.SetEpollFd(proxy.epoll_fd)

	err = netio.ProxyNetListen(&proxy.proxy_endpoint)
	if err != nil {
		logger.Critical("Failed to initialize server listener [%s].", err)
		goto Cleanup
	}

	setup_sighnd(proxy)

	logger.Info("Mongodb proxy server start.")

	for {
		wait_signal(proxy, syscall.SIGTERM)

		if proxy.quit {
			break
		}

		nfds, err := syscall.EpollWait(proxy.epoll_fd, proxy.events,
			proxy.timeout)
		if err != nil {
			logger.Critical("Failed to do epoll wait [%s].", err)
			break
		}

		for i := 0; i < nfds; i++ {
			fd := int(proxy.events[i].Fd)

			if netio.ProxyNetIsProxyServer(fd) {
				clientinfo, err := netio.ProxyNetAccept(&proxy.mongo_endpoint)
				if err != nil {
					logger.Critical("Failed to establish bridge between mongo client and server [%s].", err)
				} else {
					addr, port := parse_sockaddr(clientinfo)
					logger.Debug("Succeed to establish bridge for client [%s:%d].", addr, port)
				}
			} else {
				event := proxy.events[i].Events

				if event&syscall.EPOLLIN != 0 {
					errno := netio.ProxyNetRecv(fd)

					if errno != NO_ERROR {
						var addr string
						var port int

						sa := netio.ProxyNetConnInfo(fd)
						if sa != nil {
							addr, port = parse_sockaddr(sa)
						}

						switch errno {
						case READ_ERROR:
							if sa != nil {
								logger.Error("Failed to read data from [%s:%d].", addr, port)
							}
						case SESSION_EOF:
							/* normal close */
							netio.ProxyNetFlush(fd)
							if sa != nil {
								logger.Debug("One side [%s:%d] close the session.", addr, port)
							}
						case UNKNOWN_ERROR:
							if sa != nil {
								logger.Debug("Unknown error during read happened at [%s:%d].", addr, port)
							}
						}

						netio.ProxyNetClosePeers(fd)
					}
				}

				if event&syscall.EPOLLOUT != 0 {
					errno := netio.ProxyNetSend(fd)

					if errno != NO_ERROR && errno != PARTIAL_SKB {
						var addr string
						var port int

						sa := netio.ProxyNetConnInfo(fd)
						if sa != nil {
							addr, port = parse_sockaddr(sa)
						}

						switch errno {
						case WRITE_ERROR:
							if sa != nil {
								logger.Error("Failed to write data to [%s:%d]", addr, port)
							}
						case FILTER_BLOCK:
							/*
							 * 'block' handler only happens on 'proxy->server' io write, here
							 * we need to log the 'client->proxy' connection information, if
							 * we call 'ConnInfo' method we get the 'proxy->server' connection,
							 * so we shall call 'OtherSideConnInfo' method here.
							 */
							sa = netio.ProxyNetOtherSideConnInfo(fd)
							if sa != nil {
								addr, port = parse_sockaddr(sa)
								logger.Error("Filter block request from client [%s:%d].", addr, port)
							}
						case UNKNOWN_ERROR:
							if sa != nil {
								logger.Debug("Unknown error during write happened at [%s:%d].", addr, port)
							}
						}

						netio.ProxyNetClosePeers(fd)
					}
				}

				if event&syscall.EPOLLRDHUP != 0 {
					netio.ProxyNetFlush(fd)
					sa := netio.ProxyNetConnInfo(fd)
					if sa != nil {
						ipaddr, port := parse_sockaddr(sa)
						logger.Debug("shutdown connection with [%s:%d].", ipaddr, port)
						netio.ProxyNetClosePeers(fd)
					}
				}

				if event&syscall.EPOLLHUP != 0 {
					netio.ProxyNetFlush(fd)
					sa := netio.ProxyNetConnInfo(fd)
					if sa != nil {
						ipaddr, port := parse_sockaddr(sa)
						logger.Debug("shutdown connection with [%s:%d].", ipaddr, port)
						netio.ProxyNetClosePeers(fd)
					}
				}
			}
		}
	}

Cleanup:
	netio.DestroyNetIO()
Error:
	logger.Info("Mongodb proxy server quit.")
	logger.Close()
	return err
}
Пример #10
0
func StartProxyServer(conf *ProxyConfig, proxy_log l4g.Logger) (err error) {
	logger = proxy_log

	var filter *IOFilterProtocol
	var netio *NetIOManager

	proxy := &ProxyServer{
		max_listen_fds: 1024,
		timeout:        1000,
		quit:           false,
		epoll_fd:       -1,
		events:         make([]syscall.EpollEvent, 100),
		sighnd:         make(chan os.Signal, 1),
	}

	if !parse_config(proxy, conf) {
		logger.Error("Failed to initialize proxy server.")
		goto Error
	}

	filter = NewIOFilterProtocol(conf)
	if filter == nil {
		logger.Error("Failed to initialize filter protocol.")
		goto Error
	} else {
		if filter.FilterEnabled() {
			go filter.MonitDiskUsage()
		}
	}

	netio = NewNetIOManager()
	netio.SetFilter(filter)

	proxy.epoll_fd, err = syscall.EpollCreate(proxy.max_listen_fds)
	if err != nil {
		logger.Critical("Failed to initialize epoll listener [%s].", err)
		goto Cleanup
	}
	netio.SetEpollFd(proxy.epoll_fd)

	err = netio.ProxyNetListen(&proxy.proxy_endpoint)
	if err != nil {
		logger.Critical("Failed to initialize server listener [%s].", err)
		goto Cleanup
	}

	setup_sighnd(proxy)

	logger.Info("Mongodb proxy server start.")

	for {
		wait_signal(proxy, syscall.SIGTERM)

		if proxy.quit {
			break
		}

		nfds, err := syscall.EpollWait(proxy.epoll_fd, proxy.events,
			proxy.timeout)
		if err != nil {
			logger.Critical("Failed to do epoll wait [%s].", err)
			break
		}

		for i := 0; i < nfds; i++ {
			fd := int(proxy.events[i].Fd)

			if netio.ProxyNetIsProxyServer(fd) {
				clientinfo, err := netio.ProxyNetAccept(&proxy.mongo_endpoint)
				if err != nil {
					logger.Critical("Failed to establish bridge between mongo client and server [%s].", err)
				} else {
					ipaddr, port := parse_sockaddr(clientinfo)
					logger.Debug("Succeed to establish bridge for client [%s:%d].", ipaddr, port)
				}
			} else {
				event := proxy.events[i].Events

				if event&syscall.EPOLLIN != 0 {
					errno := netio.ProxyNetRecv(fd)

					switch errno {
					case READ_ERROR:
						sa := netio.ProxyNetConnInfo(fd)
						if sa != nil {
							ipaddr, port := parse_sockaddr(sa)
							logger.Error("Failed to read data from [%s:%d].", ipaddr, port)
						}
					case SESSION_EOF:
						sa := netio.ProxyNetConnInfo(fd)
						if sa != nil {
							ipaddr, port := parse_sockaddr(sa)
							logger.Debug("One side [%s:%d] close the session.", ipaddr, port)
						}
					}

					if errno != NO_ERROR {
						netio.ProxyNetClosePeers(fd)
					}
				}

				if event&syscall.EPOLLOUT != 0 {
					errno := netio.ProxyNetSend(fd)

					switch errno {
					case WRITE_ERROR:
						sa := netio.ProxyNetConnInfo(fd)
						if sa != nil {
							ipaddr, port := parse_sockaddr(sa)
							logger.Error("Failed to write data to [%s:%d]", ipaddr, port)
						}
					case FILTER_BLOCK:
						sa := netio.ProxyNetConnInfo(fd)
						if sa != nil {
							ipaddr, port := parse_sockaddr(sa)
							logger.Error("Filter block request from client [%s:%d].", ipaddr, port)
						}
					}

					if errno != NO_ERROR {
						netio.ProxyNetClosePeers(fd)
					}
				}

				if event&syscall.EPOLLRDHUP != 0 {
					sa := netio.ProxyNetConnInfo(fd)
					if sa != nil {
						ipaddr, port := parse_sockaddr(sa)
						logger.Debug("shutdown connection with [%s:%d].", ipaddr, port)
						netio.ProxyNetClosePeers(fd)
					}
				}

				if event&syscall.EPOLLHUP != 0 {
					sa := netio.ProxyNetConnInfo(fd)
					if sa != nil {
						ipaddr, port := parse_sockaddr(sa)
						logger.Debug("shutdown connection with [%s:%d].", ipaddr, port)
						netio.ProxyNetClosePeers(fd)
					}
				}
			}
		}
	}

Cleanup:
	netio.DestroyNetIO()
Error:
	logger.Info("Mongodb proxy server quit.")
	logger.Close()
	return err
}