Exemplo n.º 1
0
static bool cgm_bind_dir(const char *root, const char *dirname)
{
    nih_local char *cgpath = NULL;

    /* /sys should have been mounted by now */
    cgpath = NIH_MUST( nih_strdup(NULL, root) );
    NIH_MUST( nih_strcat(&cgpath, NULL, "/sys/fs/cgroup") );

    if (!dir_exists(cgpath)) {
        ERROR("%s does not exist", cgpath);
        return false;
    }

    /* mount a tmpfs there so we can create subdirs */
    if (mount("cgroup", cgpath, "tmpfs", 0, "size=10000,mode=755")) {
        SYSERROR("Failed to mount tmpfs at %s", cgpath);
        return false;
    }
    NIH_MUST( nih_strcat(&cgpath, NULL, "/cgmanager") );

    if (mkdir(cgpath, 0755) < 0) {
        SYSERROR("Failed to create %s", cgpath);
        return false;
    }

    if (mount(dirname, cgpath, "none", MS_BIND, 0)) {
        SYSERROR("Failed to bind mount %s to %s", dirname, cgpath);
        return false;
    }

    return true;
}
Exemplo n.º 2
0
int remove_on_empty_main(const char *controller, const char *cgroup,
		struct ucred p, struct ucred r)
{
	char rcgpath[MAXPATHLEN];
	size_t cgroup_len;
	nih_local char *working = NULL, *wcgroup = NULL;

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	// Get r's current cgroup in rcgpath
	if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
		nih_error("%s: Could not determine the requested cgroup", __func__);
		return -1;
	}

	cgroup_len = strlen(cgroup);

	if (strlen(rcgpath) + cgroup_len > MAXPATHLEN) {
		nih_error("%s: Path name too long", __func__);
		return -1;
	}

	wcgroup = NIH_MUST( nih_strdup(NULL, cgroup) );
	if (!normalize_path(wcgroup))
		return -1;

	working = NIH_MUST( nih_strdup(NULL, rcgpath) );
	NIH_MUST( nih_strcat(&working, NULL, "/") );
	NIH_MUST( nih_strcat(&working, NULL, wcgroup) );

	if (!dir_exists(working)) {
		return -1;
	}
	// must have write access
	if (!may_access(r.pid, r.uid, r.gid, working, O_WRONLY)) {
		nih_error("%s: pid %d (%u:%u) may not remove %s", __func__,
			r.pid, r.uid, r.gid, working);
		return -1;
	}

	NIH_MUST( nih_strcat(&working, NULL, "/notify_on_release") );

	if (!set_value_trusted(working, "1\n")) {
		nih_error("Failed to set remove_on_empty for %s:%s", controller, working);
		return -1;
	}

	return 0;
}
Exemplo n.º 3
0
/**
 * type_var_to_string:
 * @parent: parent object for new string,
 * @var: variable to convert.
 *
 * Returns a string for the given variable @var, consisting of the type
 * and variable name separated by a space if appropriate.
 *
 * If @parent is not NULL, it should be a pointer to another object which
 * will be used as a parent for the returned string.  When all parents
 * of the returned string are freed, the returned string will also be
 * freed.
 *
 * Returns: the newly allocated string or NULL if insufficient memory.
 **/
char *
type_var_to_string (const void *parent,
		    TypeVar *   var)
{
	char *str;

	nih_assert (var != NULL);

	if (strchr (var->type, '*')) {
		str = nih_sprintf (parent, "%s%s", var->type, var->name);
	} else {
		str = nih_sprintf (parent, "%s %s", var->type, var->name);
	}

	if (! str)
		return NULL;

	if (var->array) {
		if (! nih_strcat (&str, parent, "[]")) {
			nih_free (str);
			return NULL;
		}
	}

	return str;
}
Exemplo n.º 4
0
int remove_main(const char *controller, const char *cgroup, struct ucred p,
		struct ucred r, int recursive, int32_t *existed)
{
	char rcgpath[MAXPATHLEN];
	size_t cgroup_len;
	nih_local char *working = NULL, *copy = NULL, *wcgroup = NULL;
	char *p1;

	*existed = 1;

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	// Get r's current cgroup in rcgpath
	if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
		nih_error("%s: Could not determine the requested cgroup", __func__);
		return -1;
	}

	cgroup_len = strlen(cgroup);

	if (strlen(rcgpath) + cgroup_len > MAXPATHLEN) {
		nih_error("%s: Path name too long", __func__);
		return -1;
	}

	wcgroup = NIH_MUST( nih_strdup(NULL, cgroup) );
	if (!normalize_path(wcgroup))
		return -1;

	working = NIH_MUST( nih_strdup(NULL, rcgpath) );
	NIH_MUST( nih_strcat(&working, NULL, "/") );
	NIH_MUST( nih_strcat(&working, NULL, wcgroup) );

	if (!dir_exists(working)) {
		*existed = -1;
		return 0;
	}
	// must have write access to the parent dir
	copy = NIH_MUST( nih_strdup(NULL, working) );
	if (!(p1 = strrchr(copy, '/')))
		return -1;
	*p1 = '\0';
	if (!may_access(r.pid, r.uid, r.gid, copy, O_WRONLY)) {
		nih_error("%s: pid %d (%u:%u) may not remove %s", __func__,
			r.pid, r.uid, r.gid, copy);
		return -1;
	}

	if (!recursive) {
		if (rmdir(working) < 0) {
			nih_error("%s: Failed to remove %s: %s", __func__, working, strerror(errno));
			return -1;
		}
	} else if (recursive_rmdir(working) < 0)
			return -1;

	nih_info(_("Removed %s for %d (%u:%u)"), working, r.pid,
		 r.uid, r.gid);
	return 0;
}
Exemplo n.º 5
0
void
test_strcat (void)
{
    char *str, *ret;

    TEST_FUNCTION ("nih_strcat");

    /* Check that we can extend a string with another, resulting in the
     * original string being modified and the new pointer stored in the
     * argument and returned.
     */
    TEST_FEATURE ("with string");
    TEST_ALLOC_FAIL {
        char *tmp;

        TEST_ALLOC_SAFE {
            str = nih_strdup (NULL, "this is a test");
        }

        tmp = str;
        ret = nih_strcat (&str, NULL, " of strdup");

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, tmp);
            TEST_EQ_STR (str, "this is a test");

            nih_free (str);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 25);
        TEST_EQ_STR (str, "this is a test of strdup");

        nih_free (str);
    }


    /* Check that when no string is passed, this behaves as strdup.
     */
    TEST_FEATURE ("with NULL");
    TEST_ALLOC_FAIL {
        str = NULL;
        ret = nih_strcat (&str, NULL, "test of strdup");

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, NULL);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 15);
        TEST_EQ_STR (str, "test of strdup");

        nih_free (str);
    }
}