Example #1
0
static int
do_epoll_create1(int flags)
{
    int rval = libc.epoll_create1(flags);
    if( rval >= 0 )
    {
        fdinfo_t* info = alloc_info(EPOLL);
        fd_save(rval, info);
    }
    return rval;
}
Example #2
0
static Retcode
make_reg_prop(Environ *e, Allocator *a, Byte *propname)
{
	Package *savepkg = e->currpkg;
	Cell saveinst = e->currinst;
	Retcode ret;
	Byte *prop;
	Int plen = 0;
	Int i;
	Allocator_block *b = NULL;
	uInt addr[1];
	uInt size[1];

	e->currpkg = e->mmu;
	e->currinst = (uPtr)NULL;

	alloc_info(a, &b, addr, size);
	
	for (i = 1; b; alloc_info(a, &b, addr, size), i++)
		;

	prop = prop_alloc(e, i * 2 * sizeof (Int));

	b = NULL;
	alloc_info(a, &b, addr, size);
	
	for (i = 1; b; alloc_info(a, &b, addr, size), i++)
	{
		/* first encode the single-cell virtual address */
		prop_encode_int(prop + plen, &plen, addr[0]);
		/* next encode the single-cell block size */
		prop_encode_int(prop + plen, &plen, size[0]);
	}
	
	ret = add_property(e->mmu->props, propname, CSTR, prop, plen);
	e->currpkg = savepkg;
	e->currinst = saveinst;
	return ret;
}
Example #3
0
File: inode.c Project: taysom/tau
info_s *new_info (info_s *parent, char *name, unint mode)
{
    info_s	*info;
    u64	ino;
    FN;
    ino = alloc_ino(parent->in_tree.t_dev);

    info = alloc_info(strlen(name) + 1, get_species(mode),
                      parent->in_tree.t_dev);

    init_inode( &info->in_inode, ino, mode, name);

    add_info(ino, info);

    return info;
}
Example #4
0
bool yay::test()
{
  vk::ApplicationInfo app_info = vk::ApplicationInfo()
    .sType(vk::StructureType::eApplicationInfo)
    .pApplicationName("vulkan test")
    .applicationVersion(1)
    .pEngineName("faze")
    .engineVersion(1)
    .apiVersion(VK_API_VERSION);

  vk::InstanceCreateInfo inst_info = vk::InstanceCreateInfo()
    .sType(vk::StructureType::eInstanceCreateInfo)
    .pApplicationInfo(&app_info);

  /*
  inst_info.enabledExtensionCount = 0;
  inst_info.ppEnabledExtensionNames = NULL;
  inst_info.enabledLayerCount = 0;
  inst_info.ppEnabledLayerNames = NULL;
  */

  vk::AllocationCallbacks alloc_info(nullptr, allocs::pfnAllocation, allocs::pfnReallocation, allocs::pfnFree, allocs::pfnInternalAllocation, allocs::pfnInternalFree);

  FazPtr<vk::Instance> instance([=](vk::Instance ist)
  {
    ist.destroy(&alloc_info);
  });

  vk::Result res = vk::createInstance(&inst_info, &alloc_info, instance.Get());

  if (res != vk::Result::eSuccess)
  {
    // quite hot shit baby yeah!
    std::cout << vk::getString(res) << std::endl;
	  return false;
  }
	return true;
}
Example #5
0
File: inode.c Project: taysom/tau
static int find_search (
    void	*data,
    u64	rec_key,
    void	*rec,
    unint	len)
{
    find_search_s	*s = data;
    inode_s		*inode = rec;
    info_s		*info;
    FN;
    if (s->ino != rec_key) {
        return qERR_NOT_FOUND;
    }
    /*
     * Found the inode, allocate a structure and fill it in
     */
    info = alloc_info(len - sizeof(inode_s), get_species(inode->i_mode),
                      Inode_tree.t_dev);
    memcpy( &info->in_inode, inode, len);

    s->info = info;
    return 0;
}
Example #6
0
int
main(
	int	argc, 
	char	*argv[])
{
	int		 c;
	int	 	 error;
	int		 mr_flag, alloc_flag, handle_flag, event_flag;
	void		*hanp;
	size_t	 	 hlen;
	char		*filename;
	dm_sessid_t	 sid;


	Progname = argv[0];
	mr_flag  = alloc_flag =  handle_flag = event_flag = 0;
	
	while ((c = getopt(argc, argv, "maeh")) != EOF) {
		switch (c) {
		case 'm':
			mr_flag = 1;
			break;
		case 'a':
			alloc_flag = 1;
			break;
		case 'e':
			event_flag = 1;
			break;
		case 'h':
			handle_flag = 1;
			break;
		case '?':
		default:
			usage(Progname);
			exit(1);
		}
	}
	if (optind >= argc) {
		usage(Progname);
		exit(1);
	}
	filename = argv[optind];
	if (filename == NULL) {
		usage(Progname);
		exit(1);
	}
	

	/*
	 * Set up our link to the DMAPI, and get a handle for
	 * the file we want to query
	 */
	error = setup_dmapi(&sid);
	if (error)
		exit(1);

	if (dm_path_to_handle(filename, &hanp, &hlen) == -1) {
		printf("Can't get handle for path %s", filename);
		error = 1;
		goto out;
	}

	printf("File %s:\n", filename);
	if (mr_flag) {
		error = mr_info(sid, hanp, hlen);
		if (error) {
			error = 1;
			goto out;
		}
	}
	if (alloc_flag) {
		error = alloc_info(sid, hanp, hlen);
		if (error) {
			error = 1;
			goto out;
		}
	}
	if (event_flag) {
		error = event_info(sid, hanp, hlen);
		if (error) {
			error = 1;
			goto out;
		}
	}
	if (handle_flag) {
		error = handle_info(sid, hanp, hlen);
		if (error) {
			error = 1;
			goto out;
		}
	}

out:
	if (dm_destroy_session(sid)) {
		errno_msg("Can't shut down session");
		error = 1;
	}

	return(error);
}
Example #7
0
static int
impl_dummy_server(void)
{
    int dummy_server = -1;

    /* Create our dummy sock. */
    struct sockaddr_un dummy_addr;
    char *socket_path = tempnam("/tmp", ".huptime");

    memset(&dummy_addr, 0, sizeof(struct sockaddr_un));
    dummy_addr.sun_family = AF_UNIX;
    strncpy(dummy_addr.sun_path, socket_path, sizeof(dummy_addr.sun_path)-1);

    /* Create a dummy server. */
    dummy_server = socket(AF_UNIX, SOCK_STREAM, 0);
    if( dummy_server < 0 )
    {
        fprintf(stderr, "Unable to create unix socket?");
        return -1;
    }
    if( fcntl(dummy_server, F_SETFD, FD_CLOEXEC) < 0 )
    {
        close(dummy_server);
        fprintf(stderr, "Unable to set cloexec?");
        return -1;
    }
    if( libc.bind(
            dummy_server,
            (struct sockaddr*)&dummy_addr,
            sizeof(struct sockaddr_un)) < 0 )
    {
        close(dummy_server);
        fprintf(stderr, "Unable to bind unix socket?");
        return -1;
    }
    if( libc.listen(dummy_server, 1) < 0 )
    {
        close(dummy_server);
        fprintf(stderr, "Unable to listen on unix socket?");
        return -1;
    }

    /* Connect a dummy client. */
    int dummy_client = socket(AF_UNIX, SOCK_STREAM, 0);
    if( dummy_client < 0 )
    {
        close(dummy_server);
        fprintf(stderr, "Unable to create unix socket?");
        return -1;
    }
    if( fcntl(dummy_client, F_SETFD, FD_CLOEXEC) < 0 )
    {
        close(dummy_server);
        close(dummy_client);
        fprintf(stderr, "Unable to set cloexec?");
        return -1;
    }
    if( connect(
            dummy_client,
            (struct sockaddr*)&dummy_addr,
            sizeof(struct sockaddr_un)) < 0 )
    {
        close(dummy_server);
        close(dummy_client);
        fprintf(stderr, "Unable to connect dummy client?");
        return -1;
    }

    /* Put the client into an error state. */
    int dummy_fd = libc.accept(dummy_server, NULL, 0);
    if( dummy_fd < 0 )
    {
        fprintf(stderr, "Unable to accept internal client?");
        close(dummy_server);
        close(dummy_client);
        return -1;
    }
    close(dummy_fd);

    /* Save the dummy info. */
    fdinfo_t* dummy_info = alloc_info(DUMMY);
    if( dummy_info == NULL )
    {
        fprintf(stderr, "Unable to allocate dummy info?");
        return -1;
    }
    dummy_info->dummy.client = dummy_client;
    fd_save(dummy_server, dummy_info);
    inc_ref(dummy_info);
    fd_save(dummy_client, dummy_info);

    /* Ensure that it's unlinked. */
    unlink(socket_path);
    free(socket_path);

    return dummy_server;
}
Example #8
0
void
impl_init(void)
{
    const char* mode_env = getenv("HUPTIME_MODE");
    const char* multi_env = getenv("HUPTIME_MULTI");
    const char* revive_env = getenv("HUPTIME_REVIVE");
    const char* debug_env = getenv("HUPTIME_DEBUG");
    const char* pipe_env = getenv("HUPTIME_PIPE");
    const char* wait_env = getenv("HUPTIME_WAIT");

    if( debug_env != NULL && strlen(debug_env) > 0 )
    {
        debug_enabled = !strcasecmp(debug_env, "true") ? TRUE: FALSE;
    }

    DEBUG("Initializing...");

    /* Initialize our lock. */
    impl_init_lock();

    /* Save this pid as our master pid.
     * This is done to handle processes that use
     * process pools. We remember the master pid and
     * will do the full fork()/exec() only when we are
     * the master. Otherwise, we will simply shutdown
     * gracefully, and all the master to restart. */
    master_pid = getpid();

    /* Grab our exit strategy. */
    if( mode_env != NULL && strlen(mode_env) > 0 )
    {
        if( !strcasecmp(mode_env, "fork") )
        {
            exit_strategy = FORK;
            DEBUG("Exit strategy is fork.");
        }
        else if( !strcasecmp(mode_env, "exec") )
        {
            exit_strategy = EXEC;
            DEBUG("Exit strategy is exec.");
        }
        else
        {
            fprintf(stderr, "Unknown exit strategy.");
            libc.exit(1);
        }
    }

    /* Check if we have something to unlink. */
    to_unlink = getenv("HUPTIME_UNLINK");
    if( to_unlink != NULL && strlen(to_unlink) > 0 )
    {
        DEBUG("Unlink is '%s'.", to_unlink);
    }

    /* Clear up any outstanding child processes.
     * Because we may have exited before the process
     * could do appropriate waitpid()'s, we try to
     * clean up children here. Note that we may have
     * some zombies that hang around during the life
     * of the program, but at every restart they will
     * be cleaned up (so at least they won't grow
     * without bound). */
    int status = 0;
    while( waitpid((pid_t)-1, &status, WNOHANG) > 0 );

    /* Check if we're in multi mode. */
    if( multi_env != NULL && strlen(multi_env) > 0 )
    {
        multi_mode = !strcasecmp(multi_env, "true") ? TRUE: FALSE;
    }
#ifndef SO_REUSEPORT
    if( multi_mode == TRUE )
    {
        fprintf(stderr, "WARNING: Multi mode not supported.\n");
        fprintf(stderr, "(Requires at least Linux 3.9 and recent headers).\n");
    } 
#endif

    /* Check if we're in revive mode. */
    if( revive_env != NULL && strlen(revive_env) > 0 )
    {
        revive_mode = !strcasecmp(revive_env, "true") ? TRUE : FALSE;
    }

    /* Check if we are in wait mode. */
    if( wait_env != NULL && strlen(wait_env) > 0 )
    {
        wait_mode = !strcasecmp(wait_env, "true") ? TRUE : FALSE;
    }

    /* Check if we're a respawn. */
    if( pipe_env != NULL && strlen(pipe_env) > 0 )
    {
        int fd = -1;
        fdinfo_t *info = NULL;
        int pipefd = strtol(pipe_env, NULL, 10);

        DEBUG("Loading all file descriptors.");

        /* Decode all passed information. */
        while( !info_decode(pipefd, &fd, &info) )
        {
            fd_save(fd, info);
            DEBUG("Decoded fd %d (type %d).", fd, info->type);
            info = NULL;
        }
        if( info != NULL )
        {
            dec_ref(info);
        }

        /* Finished with the pipe. */
        libc.close(pipefd);
        unsetenv("HUPTIME_PIPE");
        DEBUG("Finished decoding.");

        /* Close all non-encoded descriptors. */
        for( fd = 0; fd < fd_max(); fd += 1 )
        {
            info = fd_lookup(fd);
            if( info == NULL )
            {
                DEBUG("Closing fd %d.", fd);
                libc.close(fd);
            }
        }

        /* Restore all given file descriptors. */
        for( fd = 0; fd < fd_limit(); fd += 1 )
        {
            info = fd_lookup(fd);
            if( info != NULL && info->type == SAVED )
            {
                fdinfo_t *orig_info = fd_lookup(info->saved.fd);
                if( orig_info != NULL )
                {
                    /* Uh-oh, conflict. Move the original (best effort). */
                    do_dup(info->saved.fd);
                    do_close(info->saved.fd);
                }

                /* Return the offset (ignore failure). */
                if( info->saved.offset != (off_t)-1 )
                {
                    lseek(fd, info->saved.offset, SEEK_SET);
                }

                /* Move the SAVED fd back. */
                libc.dup2(fd, info->saved.fd);
                DEBUG("Restored fd %d.", info->saved.fd);
            }
        }
    }
    else
    {
        DEBUG("Saving all initial file descriptors.");

        /* Save all of our initial files. These are used
         * for re-execing the process. These are persisted
         * effectively forever, and on restarts we close
         * everything that is not a BOUND socket or a SAVED
         * file descriptor. */
        for( int fd = 0; fd < fd_max(); fd += 1 )
        {
            fdinfo_t *info = fd_lookup(fd);
            if( info != NULL )
            {
                /* Encoded earlier. */
                continue;
            }

            /* Make a new SAVED FD. */
            int newfd = libc.dup(fd);
            if( newfd >= 0 )
            {
                fdinfo_t *saved_info = alloc_info(SAVED);

                if( saved_info != NULL )
                {
                    saved_info->saved.fd = fd;
                    saved_info->saved.offset = lseek(fd, 0, SEEK_CUR);
                    fd_save(newfd, saved_info);
                    DEBUG("Saved fd %d (offset %lld).",
                        fd, (long long int)saved_info->saved.offset);
                }
            }
        }
    }

    /* Save the environment.
     *
     * NOTE: We reserve extra space in the environment
     * for our special start-up parameters, which will be added
     * in impl_exec() below. (The encoded BOUND/SAVED sockets).
     *
     * We also filter out the special variables above that were
     * used to pass in information about sockets that were bound. */
    free(environ_copy);
    environ_copy = (char**)read_nul_sep("/proc/self/environ");
    DEBUG("Saved environment.");

    /* Save the arguments. */
    free(args_copy);
    args_copy = (char**)read_nul_sep("/proc/self/cmdline");
    DEBUG("Saved args.");
    for( int i = 0; args_copy[i] != NULL; i += 1 )
    {
        DEBUG(" arg%d=%s", i, args_copy[i]);
    }

    /* Save the cwd & exe. */
    free(cwd_copy);
    cwd_copy = (char*)read_link("/proc/self/cwd");
    DEBUG("Saved cwd.");
    free(exe_copy);
    exe_copy = (char*)read_link("/proc/self/exe");
    DEBUG("Saved exe.");

    /* Install our signal handlers. */
    impl_install_sighandlers();

    /* Initialize our thread. */
    impl_init_thread();

    /* Unblock our signals.
     * Note that we have specifically masked the
     * signals prior to the exec() below, to cover
     * the race between program start and having
     * installed the appropriate handlers. */
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGHUP);
    sigprocmask(SIG_UNBLOCK, &set, NULL);

    /* Done. */
    DEBUG("Initialization complete.");
}
Example #9
0
static int
do_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
{
    int rval = -1;
    fdinfo_t *info = NULL;

    if( sockfd < 0 )
    {
        errno = EINVAL;
        return -1;
    }

    DEBUG("do_accept4(%d, ...) ...", sockfd);
    L();
    info = fd_lookup(sockfd);
    if( info == NULL || (info->type != BOUND && info->type != DUMMY) )
    {
        U();
        /* Should return an error. */
        rval = libc.accept4(sockfd, addr, addrlen, flags);
        DEBUG("do_accept4(%d, ...) => %d (no info)", sockfd, rval);
        return rval;
    }

    /* Check that they've called listen. */
    if( info->type == BOUND && !info->bound.stub_listened )
    {
        U();
        DEBUG("do_accept4(%d, ...) => -1 (not listened)", sockfd);
        errno = EINVAL;
        return -1;
    }

    /* Check if this is a dummy.
     * There's no way that they should be calling accept().
     * The dummy FD will never trigger a poll, select, epoll,
     * etc. So we just act as a socket with no clients does --
     * either return immediately or block forever. NOTE: We
     * still return in case of EINTR or other suitable errors. */
    if( info->type == DUMMY && info->dummy.client >= 0 )
    {
        rval = info->dummy.client;
        info->dummy.client = -1;
        U();
        DEBUG("do_accept4(%d, ...) => %d (dummy client)", sockfd, rval);
        return rval;
    }

    U();

    if( !(flags & SOCK_NONBLOCK) )
    {
        /* Wait for activity on the socket. */
        struct pollfd poll_info;
        poll_info.fd = sockfd;
        poll_info.events = POLLIN;
        poll_info.revents = 0;
        if( poll(&poll_info, 1, -1) < 0 )
        {
            return -1;
        }
    }

    L();

    /* Check our status. */
    if( is_exiting == TRUE )
    {
        /* We've transitioned from not exiting
         * to exiting in this period. This will
         * circle around a return a dummy descriptor. */
        U();
        DEBUG("do_accept4(%d, ...) => -1 (interrupted)", sockfd);
        errno = flags & SOCK_NONBLOCK ? EAGAIN : EINTR;
        return -1;
    }

    /* Do the accept for real. */
    fdinfo_t *new_info = alloc_info(TRACKED);
    if( new_info == NULL )
    {
        U();
        DEBUG("do_accept4(%d, ...) => -1 (alloc error?)", sockfd);
        return -1;
    }
    inc_ref(info);
    new_info->tracked.bound = info;
    rval = libc.accept4(sockfd, addr, addrlen, flags);

    if( rval >= 0 )
    {
        /* Save the reference to the socket. */
        fd_save(rval, new_info);
    }
    else
    {
        /* An error occured, nothing to track. */
        dec_ref(new_info);
    }

    U();
    DEBUG("do_accept4(%d, ...) => %d (tracked %d) %s",
        sockfd, rval, total_tracked,
        rval == -1 ? strerror(errno) : "");
    return rval;
}
Example #10
0
static int
do_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    fdinfo_t *info = NULL;
    int rval = -1;

    if( sockfd < 0 )
    {
        errno = EINVAL;
        return -1;
    }

    /* At this point, we can reasonably assume
     * the program has started up and has installed
     * whatever signal handlers it wants. We check
     * that our own signal handler is installed.
     * If the user doesn't want us to override the
     * built-in signal handlers, they shouldn't use
     * huptime. */
    impl_install_sighandlers();

    DEBUG("do_bind(%d, ...) ...", sockfd);
    L();

    /* See if this socket already exists. */
    for( int fd = 0; fd < fd_limit(); fd += 1 )
    {
        fdinfo_t *info = fd_lookup(fd);
        if( info != NULL && 
            info->type == BOUND &&
            info->bound.addrlen == addrlen &&
            !memcmp(addr, (void*)info->bound.addr, addrlen) )
        {
            DEBUG("Found ghost %d, cloning...", fd);

            /* Give back a duplicate of this one. */
            int rval = do_dup2(fd, sockfd);
            if( rval < 0 )
            {
                /* Dup2 failed? */
                DEBUG("Failed.");
                continue;
            }
            if( info->bound.is_ghost )
            {
                /* Close the original (not needed). */
                info->bound.is_ghost = 0;
                do_close(fd);
            }

            /* Success. */
            U();
            DEBUG("do_bind(%d, ...) => 0 (ghosted)", sockfd);
            return 0;
        }
    }

#ifdef SO_REUSEPORT
    /* Multi mode? Set socket options. */
    if( multi_mode == TRUE )
    {
        int optval = 1;
        if( setsockopt(sockfd,
                       SOL_SOCKET,
                       SO_REUSEPORT,
                       &optval,
                       sizeof(optval)) < 0 )
        {
            U();
            DEBUG("do_bind(%d, ...) => -1 (no multi?)", sockfd);
            return -1;
        }

        DEBUG("Multi mode enabled.");
    }
#endif

    /* Try a real bind. */
    info = alloc_info(BOUND);
    if( info == NULL )
    {
        U();
        DEBUG("do_bind(%d, ...) => -1 (alloc error?)", sockfd);
        return -1;
    }
    rval = libc.bind(sockfd, addr, addrlen);
    if( rval < 0 )
    {
        dec_ref(info);
        U();
        DEBUG("do_bind(%d, ...) => %d (error)", sockfd, rval);
        return rval;
    }

    /* Ensure that this socket is non-blocking,
     * this is because we override the behavior
     * for accept() and we require non-blocking
     * behavior. We deal with the consequences. */
    rval = fcntl(sockfd, F_SETFL, O_NONBLOCK);
    if( rval < 0 )
    {
        dec_ref(info);
        U();
        DEBUG("do_bind(%d, ...) => %d (fcntl error)", sockfd, rval);
        return -1;
    }

    /* Save a refresh bound socket info. */
    info->bound.stub_listened = 0;
    info->bound.real_listened = 0;
    info->bound.addr = (struct sockaddr*)malloc(addrlen);
    info->bound.addrlen = addrlen;
    memcpy((void*)info->bound.addr, (void*)addr, addrlen);
    fd_save(sockfd, info);

    /* Success. */
    U();
    DEBUG("do_bind(%d, ...) => %d", sockfd, rval);
    return rval;
}
Example #11
0
void MemoryHeap::mark_allocated(void* addr, size_t size, bool largeAlloc)
	{
	lassert(size > 0);
	mPages.insert(std::make_pair(addr, alloc_info(size, largeAlloc)));
	mHeapSize += size;
	}