Example #1
0
int
__get_authtoken_attr(char *name, pwu_repository_t *rep, attrlist *item)
{
	int repositories;
	int i;
	int res;

	repositories = get_ns(rep, PWU_READ);

	if (repositories == 0)
		return (PWU_SYSTEM_ERROR);

	if (repositories == REP_ERANGE) {
		/* Can't determine where to look. Fall back to NSS */
		repositories = REP_NSS;
	}

	i = REP_FILES;
	res = PWU_NOT_FOUND;

	/* Loop over repositories until the user is found */
	while ((i <= REP_LAST) && (res == PWU_NOT_FOUND)) {
		if (repositories & i)
			res = rops[i]->getattr(name, item, rep);
		i <<= 1;
	}
	return (res);
}
Example #2
0
/*
 *	__check_history - check if a user's new password is in the user's
 *		old password history.
 *
 *	Entry
 *		user = username.
 *		passwd = new clear text password.
 *		rep = repositories to check.
 *
 *	Exit
 *		PWU_SUCCESS, passwd found in user's old password history.
 *			The caller should only be interested and fail if
 *			PWU_SUCCESS is returned.
 *		PWU_NOT_FOUND, passwd not in user's old password history.
 *		PWU_errors, PWU_ errors from other routines.
 *
 */
int
__check_history(char *user, char *passwd, pwu_repository_t *rep)
{
    int repositories;
    int i;
    int res;

    repositories = get_ns(rep, PWU_READ);

    if (repositories == 0)
        return (PWU_SYSTEM_ERROR);

    if (repositories == REP_ERANGE)
        return (PWU_REPOSITORY_ERROR);

    i = REP_FILES;
    res = PWU_NOT_FOUND;

    /* Loop over repositories until the user is found */
    while ((i <= REP_LAST) && (res == PWU_NOT_FOUND)) {
        if (repositories & i)
            if (rops[i]->checkhistory != NULL)
                res = rops[i]->checkhistory(user, passwd, rep);
        i <<= 1;
    }
    return (res);
}
Example #3
0
void run_test(int64_t delay_ns)
{
    for (int i = 0; i <= 25; i++) {
        int64_t start, finish;
        start = get_ns();
        do_get(key, 0);
        finish = get_ns();

        int64_t elapsed = finish - start;
        if (i > 0) {
            printf("%f\n", elapsed / 1e9);
            fflush(stdout);
        }

        do_sleep(delay_ns);
    }
}
Example #4
0
//------------------------------------------------
// Do one large block read operation and report.
//
static void
read_and_report_large_block(device* dev, uint8_t* buf)
{
	uint64_t offset = random_large_block_offset(dev);
	uint64_t start_time = get_ns();
	uint64_t stop_time = read_from_device(dev, offset,
			g_scfg.large_block_ops_bytes, buf);

	if (stop_time != -1) {
		histogram_insert_data_point(g_large_block_read_hist,
				safe_delta_ns(start_time, stop_time));
	}
}
Example #5
0
//------------------------------------------------
// Do one transaction read operation and report.
//
static void
read_and_report(trans_req* read_req, uint8_t* buf)
{
	uint64_t raw_start_time = get_ns();
	uint64_t stop_time = read_from_device(read_req->dev, read_req->offset,
			read_req->size, buf);

	if (stop_time != -1) {
		histogram_insert_data_point(g_raw_read_hist,
				safe_delta_ns(raw_start_time, stop_time));
		histogram_insert_data_point(g_read_hist,
				safe_delta_ns(read_req->start_time, stop_time));
		histogram_insert_data_point(read_req->dev->raw_read_hist,
				safe_delta_ns(raw_start_time, stop_time));
	}
}
Example #6
0
//------------------------------------------------
// Do one large block write operation and report.
//
static void
write_and_report_large_block(device* dev, uint8_t* buf, uint64_t count)
{
	// Salt the block each time.
	rand_fill(buf, g_scfg.large_block_ops_bytes);

	uint64_t offset = random_large_block_offset(dev);
	uint64_t start_time = get_ns();
	uint64_t stop_time = write_to_device(dev, offset,
			g_scfg.large_block_ops_bytes, buf);

	if (stop_time != -1) {
		histogram_insert_data_point(g_large_block_write_hist,
				safe_delta_ns(start_time, stop_time));
	}
}
Example #7
0
//------------------------------------------------
// Do one transaction write operation and report.
//
static void
write_and_report(trans_req* write_req, uint8_t* buf)
{
	// Salt each record.
	rand_fill(buf, write_req->size);

	uint64_t raw_start_time = get_ns();
	uint64_t stop_time = write_to_device(write_req->dev, write_req->offset,
			write_req->size, buf);

	if (stop_time != -1) {
		histogram_insert_data_point(g_raw_write_hist,
				safe_delta_ns(raw_start_time, stop_time));
		histogram_insert_data_point(g_write_hist,
				safe_delta_ns(write_req->start_time, stop_time));
		histogram_insert_data_point(write_req->dev->raw_write_hist,
				safe_delta_ns(raw_start_time, stop_time));
	}
}
Example #8
0
//------------------------------------------------
// Do one device write operation.
//
static uint64_t
write_to_device(device* dev, uint64_t offset, uint32_t size, const uint8_t* buf)
{
	int fd = fd_get(dev);

	if (fd == -1) {
		return -1;
	}

	if (! pwrite_all(fd, buf, size, offset)) {
		close(fd);
		fprintf(stdout, "ERROR: writing %s: %d '%s'\n", dev->name, errno,
				act_strerror(errno));
		return -1;
	}

	uint64_t stop_ns = get_ns();

	fd_put(dev, fd);

	return stop_ns;
}
Example #9
0
static void *__ns_get_path(struct path *path, struct ns_common *ns)
{
	struct vfsmount *mnt = nsfs_mnt;
	struct qstr qname = { .name = "", };
	struct dentry *dentry;
	struct inode *inode;
	unsigned long d;

	rcu_read_lock();
	d = atomic_long_read(&ns->stashed);
	if (!d)
		goto slow;
	dentry = (struct dentry *)d;
	if (!lockref_get_not_dead(&dentry->d_lockref))
		goto slow;
	rcu_read_unlock();
	ns->ops->put(ns);
got_it:
	path->mnt = mntget(mnt);
	path->dentry = dentry;
	return NULL;
slow:
	rcu_read_unlock();
	inode = new_inode_pseudo(mnt->mnt_sb);
	if (!inode) {
		ns->ops->put(ns);
		return ERR_PTR(-ENOMEM);
	}
	inode->i_ino = ns->inum;
	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
	inode->i_flags |= S_IMMUTABLE;
	inode->i_mode = S_IFREG | S_IRUGO;
	inode->i_fop = &ns_file_operations;
	inode->i_private = ns;

	dentry = d_alloc_pseudo(mnt->mnt_sb, &qname);
	if (!dentry) {
		iput(inode);
		return ERR_PTR(-ENOMEM);
	}
	d_instantiate(dentry, inode);
	dentry->d_flags |= DCACHE_RCUACCESS;
	dentry->d_fsdata = (void *)ns->ops;
	d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry);
	if (d) {
		d_delete(dentry);	/* make sure ->d_prune() does nothing */
		dput(dentry);
		cpu_relax();
		return ERR_PTR(-EAGAIN);
	}
	goto got_it;
}

void *ns_get_path(struct path *path, struct task_struct *task,
			const struct proc_ns_operations *ns_ops)
{
	struct ns_common *ns;
	void *ret;

again:
	ns = ns_ops->get(task);
	if (!ns)
		return ERR_PTR(-ENOENT);

	ret = __ns_get_path(path, ns);
	if (IS_ERR(ret) && PTR_ERR(ret) == -EAGAIN)
		goto again;
	return ret;
}

int open_related_ns(struct ns_common *ns,
		   struct ns_common *(*get_ns)(struct ns_common *ns))
{
	struct path path = {};
	struct file *f;
	void *err;
	int fd;

	fd = get_unused_fd_flags(O_CLOEXEC);
	if (fd < 0)
		return fd;

	while (1) {
		struct ns_common *relative;

		relative = get_ns(ns);
		if (IS_ERR(relative)) {
			put_unused_fd(fd);
			return PTR_ERR(relative);
		}

		err = __ns_get_path(&path, relative);
		if (IS_ERR(err) && PTR_ERR(err) == -EAGAIN)
			continue;
		break;
	}
	if (IS_ERR(err)) {
		put_unused_fd(fd);
		return PTR_ERR(err);
	}

	f = dentry_open(&path, O_RDONLY, current_cred());
	path_put(&path);
	if (IS_ERR(f)) {
		put_unused_fd(fd);
		fd = PTR_ERR(f);
	} else
		fd_install(fd, f);

	return fd;
}

static long ns_ioctl(struct file *filp, unsigned int ioctl,
			unsigned long arg)
{
	struct user_namespace *user_ns;
	struct ns_common *ns = get_proc_ns(file_inode(filp));
	uid_t __user *argp;
	uid_t uid;

	switch (ioctl) {
	case NS_GET_USERNS:
		return open_related_ns(ns, ns_get_owner);
	case NS_GET_PARENT:
		if (!ns->ops->get_parent)
			return -EINVAL;
		return open_related_ns(ns, ns->ops->get_parent);
	case NS_GET_NSTYPE:
		return ns->ops->type;
	case NS_GET_OWNER_UID:
		if (ns->ops->type != CLONE_NEWUSER)
			return -EINVAL;
		user_ns = container_of(ns, struct user_namespace, ns);
		argp = (uid_t __user *) arg;
		uid = from_kuid_munged(current_user_ns(), user_ns->owner);
		return put_user(uid, argp);
	default:
		return -ENOTTY;
	}
}

int ns_get_name(char *buf, size_t size, struct task_struct *task,
			const struct proc_ns_operations *ns_ops)
{
	struct ns_common *ns;
	int res = -ENOENT;
	ns = ns_ops->get(task);
	if (ns) {
		res = snprintf(buf, size, "%s:[%u]", ns_ops->name, ns->inum);
		ns_ops->put(ns);
	}
	return res;
}

struct file *proc_ns_fget(int fd)
{
	struct file *file;

	file = fget(fd);
	if (!file)
		return ERR_PTR(-EBADF);

	if (file->f_op != &ns_file_operations)
		goto out_invalid;

	return file;

out_invalid:
	fput(file);
	return ERR_PTR(-EINVAL);
}

static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry)
{
	struct inode *inode = d_inode(dentry);
	const struct proc_ns_operations *ns_ops = dentry->d_fsdata;

	seq_printf(seq, "%s:[%lu]", ns_ops->name, inode->i_ino);
	return 0;
}

static const struct super_operations nsfs_ops = {
	.statfs = simple_statfs,
	.evict_inode = nsfs_evict,
	.show_path = nsfs_show_path,
};
static struct dentry *nsfs_mount(struct file_system_type *fs_type,
			int flags, const char *dev_name, void *data)
{
	return mount_pseudo(fs_type, "nsfs:", &nsfs_ops,
			&ns_dentry_operations, NSFS_MAGIC);
}
static struct file_system_type nsfs = {
	.name = "nsfs",
	.mount = nsfs_mount,
	.kill_sb = kill_anon_super,
};

void __init nsfs_init(void)
{
	nsfs_mnt = kern_mount(&nsfs);
	if (IS_ERR(nsfs_mnt))
		panic("can't set nsfs up\n");
	nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
}
Example #10
0
int main(int argc, char *argv[])
{
    int64_t time_start, time_end;

    g_thread_init(NULL);
    queue = g_async_queue_new();
    lock = g_mutex_new();
    cond_empty = g_cond_new();
    cond_full = g_cond_new();

    int opt;
    int backend = 0;
    while ((opt = getopt(argc, argv, "at:s:b:n:BFD")) != -1) {
        switch (opt) {
        case 'a':
            // Make BDB log writes more asynchronous
            opt_bdb_async = TRUE;
            break;
        case 't':
            // Set number of log worker threads
            opt_threads = atoi(optarg);
            break;
        case 's':
            // Set item size (in bytes)
            item_size = atoi(optarg);
            break;
        case 'b':
            // Set batch size
            opt_batchsize = atoi(optarg);
            break;
        case 'n':
            // Set object count
            opt_writes = atoi(optarg);
            break;
        case 'B':
            // Select BDB backend
            backend = 'b';
            break;
        case 'F':
            // Select flat file backend
            backend = 'f';
            break;
        case 'D':
            // Select file system directory backend
            backend = 'd';
            break;
        default: /* '?' */
            fprintf(stderr, "Usage: %s [-t threads] {-B|-F|-D}\n",
                    argv[0]);
            return EXIT_FAILURE;
        }
    }

    switch (backend) {
    case 'b':
        launch_bdb();
        break;
    case 'f':
        launch_flatlog();
        break;
    case 'd':
        launch_fslog();
        break;
    default:
        fprintf(stderr, "Backend not selected!\n");
        return EXIT_FAILURE;
    }

    time_start = get_ns();
    for (int i = 0; i < opt_writes; i++) {
        struct item *item = g_new(struct item, 1);
        item->key = g_strdup_printf("item-%06d", i);
        item->data = g_malloc(item_size);
        item->len = item_size;

        g_mutex_lock(lock);
        g_async_queue_push(queue, item);
        outstanding++;
        if (outstanding == opt_batchsize)
            g_cond_wait(cond_empty, lock);
        g_mutex_unlock(lock);
    }

    g_mutex_lock(lock);
    while (outstanding > 0)
        g_cond_wait(cond_empty, lock);
    g_mutex_unlock(lock);
    time_end = get_ns();

    double elapsed = (time_end - time_start) / 1e9;
    printf("Elapsed: %f s\nThroughput: %f txn/s, %f MiB/s\n",
           elapsed, opt_writes / elapsed,
           opt_writes / elapsed * item_size / (1 << 20));

    if (backend == 'b' && opt_bdb_async)
        backend = 'B';

    FILE *f = fopen("../logbench.data", "a");
    g_assert(f != NULL);
    fprintf(f, "%c\t%d\t%d\t%d\t%f\t%f\t%f\n",
            backend, item_size, opt_writes, opt_batchsize,
            elapsed, opt_writes / elapsed,
            opt_writes / elapsed * item_size / (1 << 20));
    fclose(f);

    return 0;
}
Example #11
0
//------------------------------------------------
// Runs in service threads, adds read trans_req
// objects to transaction queues in round-robin
// fashion.
//
static void*
run_generate_read_reqs(void* pv_unused)
{
	rand_seed_thread();

	uint64_t count = 0;
	uint64_t internal_read_reqs_per_sec =
			g_scfg.internal_read_reqs_per_sec / g_scfg.read_req_threads;

	while (g_running) {
		if (atomic32_incr(&g_reqs_queued) > g_scfg.max_reqs_queued) {
			fprintf(stdout, "ERROR: too many requests queued\n");
			fprintf(stdout, "drive(s) can't keep up - test stopped\n");
			g_running = false;
			break;
		}

		uint32_t q_index = count % g_scfg.num_queues;
		uint32_t random_dev_index = rand_32() % g_scfg.num_devices;
		device* random_dev = &g_devices[random_dev_index];

		trans_req read_req = {
				.dev = random_dev,
				.offset = random_read_offset(random_dev),
				.size = random_read_size(random_dev),
				.is_write = false,
				.start_time = get_ns()
		};

		queue_push(g_trans_qs[q_index], &read_req);

		count++;

		int64_t sleep_us = (int64_t)
				(((count * 1000000) / internal_read_reqs_per_sec) -
						(get_us() - g_run_start_us));

		if (sleep_us > 0) {
			usleep((uint32_t)sleep_us);
		}
		else if (sleep_us < -(int64_t)g_scfg.max_lag_usec) {
			fprintf(stdout, "ERROR: read request generator can't keep up\n");
			fprintf(stdout, "ACT can't do requested load - test stopped\n");
			g_running = false;
		}
	}

	return NULL;
}

//------------------------------------------------
// Runs in service threads, adds write trans_req
// objects to transaction queues in round-robin
// fashion.
//
static void*
run_generate_write_reqs(void* pv_unused)
{
	rand_seed_thread();

	uint64_t count = 0;
	uint64_t internal_write_reqs_per_sec =
			g_scfg.internal_write_reqs_per_sec / g_scfg.write_req_threads;

	while (g_running) {
		if (atomic32_incr(&g_reqs_queued) > g_scfg.max_reqs_queued) {
			fprintf(stdout, "ERROR: too many requests queued\n");
			fprintf(stdout, "drive(s) can't keep up - test stopped\n");
			g_running = false;
			break;
		}

		uint32_t q_index = count % g_scfg.num_queues;
		uint32_t random_dev_index = rand_32() % g_scfg.num_devices;
		device* random_dev = &g_devices[random_dev_index];

		trans_req write_req = {
				.dev = random_dev,
				.offset = random_write_offset(random_dev),
				.size = random_write_size(random_dev),
				.is_write = true,
				.start_time = get_ns()
		};

		queue_push(g_trans_qs[q_index], &write_req);

		count++;

		int64_t sleep_us = (int64_t)
				(((count * 1000000) / internal_write_reqs_per_sec) -
						(get_us() - g_run_start_us));

		if (sleep_us > 0) {
			usleep((uint32_t)sleep_us);
		}
		else if (sleep_us < -(int64_t)g_scfg.max_lag_usec) {
			fprintf(stdout, "ERROR: write request generator can't keep up\n");
			fprintf(stdout, "ACT can't do requested load - test stopped\n");
			g_running = false;
		}
	}

	return NULL;
}

//------------------------------------------------
// Runs in every device large-block read thread,
// executes large-block reads at a constant rate.
//
static void*
run_large_block_reads(void* pv_dev)
{
	rand_seed_thread();

	device* dev = (device*)pv_dev;

	uint8_t* buf = act_valloc(g_scfg.large_block_ops_bytes);

	if (! buf) {
		fprintf(stdout, "ERROR: large block read buffer act_valloc()\n");
		g_running = false;
		return NULL;
	}

	uint64_t count = 0;

	while (g_running) {
		read_and_report_large_block(dev, buf);

		count++;

		uint64_t target_us = (uint64_t)
				((double)(count * 1000000 * g_scfg.num_devices) /
						g_scfg.large_block_reads_per_sec);

		int64_t sleep_us = (int64_t)(target_us - (get_us() - g_run_start_us));

		if (sleep_us > 0) {
			usleep((uint32_t)sleep_us);
		}
		else if (sleep_us < -(int64_t)g_scfg.max_lag_usec) {
			fprintf(stdout, "ERROR: large block reads can't keep up\n");
			fprintf(stdout, "drive(s) can't keep up - test stopped\n");
			g_running = false;
		}
	}

	free(buf);

	return NULL;
}
Example #12
0
/*ARGSUSED*/
int
nss_getpwnam(char *name, attrlist *items, pwu_repository_t *rep, void **buf)
{
	attrlist *p;
	struct pwbuf *pwbuf;
	int repositories = REP_ERANGE;	/* changed if ATTR_REP_NAME is set */
	int err = PWU_SUCCESS;

	*buf = calloc(1, sizeof (struct pwbuf));
	pwbuf = (struct pwbuf *)*buf;

	/*
	 * determine which password structure (/etc/passwd or /etc/shadow)
	 * we need for the items we need to update
	 */
	for (p = items; p != NULL; p = p->next) {
		switch (p->type) {
		case ATTR_NAME:
		case ATTR_UID:
		case ATTR_GID:
		case ATTR_AGE:
		case ATTR_COMMENT:
		case ATTR_GECOS:
		case ATTR_HOMEDIR:
		case ATTR_SHELL:
			if (pwbuf->pwd == NULL)
				pwbuf->pwd = (struct passwd *)
				    malloc(sizeof (struct passwd));
			if (pwbuf->pwd == NULL) {
				errno = ENOMEM;
				if (pwbuf->spwd)
					free(pwbuf->spwd);
				return (PWU_NOMEM);
			}
			break;
		case ATTR_PASSWD:
		case ATTR_PASSWD_SERVER_POLICY:
		case ATTR_LSTCHG:
		case ATTR_MIN:
		case ATTR_MAX:
		case ATTR_WARN:
		case ATTR_INACT:
		case ATTR_EXPIRE:
		case ATTR_FLAG:
		case ATTR_LOCK_ACCOUNT:
		case ATTR_EXPIRE_PASSWORD:
		case ATTR_FAILED_LOGINS:
			if (pwbuf->spwd == NULL)
				pwbuf->spwd = (struct spwd *)
				    malloc(sizeof (struct spwd));
			if (pwbuf->spwd == NULL) {
				errno = ENOMEM;
				if (pwbuf->pwd)
					free(pwbuf->pwd);
				return (PWU_NOMEM);
			}
			break;
		case ATTR_REP_NAME:
			/* get the compat names (REP_COMPAT_*) */
			repositories = get_ns(rep, PWU_READ);
			break;
		default:
			/*
			 * Some other repository might have different values
			 * so we ignore those.
			 */
			break;
		}
	}

	if (pwbuf->pwd) {
		if ((pwbuf->pwd_scratch = malloc(PWD_SCRATCH_SIZE)) == NULL) {
			err = PWU_NOMEM;
			goto error;
		}
		if (getpwnam_r(name, pwbuf->pwd, pwbuf->pwd_scratch,
		    PWD_SCRATCH_SIZE) == NULL) {
			err = PWU_NOT_FOUND;
			goto error;
		}
	}

	if (pwbuf->spwd) {
		if ((pwbuf->spwd_scratch = malloc(SPW_SCRATCH_SIZE)) == NULL) {
			err = PWU_NOMEM;
			goto error;
		}
		if (getspnam_r(name, pwbuf->spwd, pwbuf->spwd_scratch,
		    SPW_SCRATCH_SIZE) == NULL) {
			err = PWU_NOT_FOUND;
			goto error;
		}
	}

	/* pwbuf->rep_name tells us where the user in fact comes from */
	if (repositories != REP_ERANGE) {
		struct passwd pwd;
		char pwd_scratch[PWD_SCRATCH_SIZE];

		/* can we find the user locally? */
		if (private_getpwnam_r(name, &pwd, pwd_scratch,
		    PWD_SCRATCH_SIZE) != NULL)
			pwbuf->rep_name = "files";
		else if (repositories & REP_COMPAT_NISPLUS)
			pwbuf->rep_name = "nisplus";
		else if (repositories & REP_COMPAT_LDAP)
			pwbuf->rep_name = "ldap";
		else if (repositories & REP_COMPAT_NIS)
			pwbuf->rep_name = "nis";
		else
			pwbuf->rep_name = "nss";
	} else
		pwbuf->rep_name = "nss";

	return (PWU_SUCCESS);
error:
	if (pwbuf->pwd) free(pwbuf->pwd);
	if (pwbuf->pwd_scratch) free(pwbuf->pwd_scratch);
	if (pwbuf->spwd) free(pwbuf->spwd);
	if (pwbuf->spwd_scratch) free(pwbuf->spwd_scratch);
	free(pwbuf);
	*buf = NULL;

	return (err);
}
Example #13
0
void print_duration(struct timespec *start, struct timespec *end, long size) {
  long diff = get_ns(end) - get_ns(start);
  double tput = ((double)size / (double)(1000*1000)) / ( (double)diff / (double)(1000*1000*1000));
  printf("Took %ld ns\n", diff);
  printf("Throughput (MB/s): %f\n", tput);
}