lttng_ht_node_init_u64(&stream->node, stream->stream_handle);
pthread_mutex_init(&stream->lock, NULL);
- ret = utils_mkdir_recursive(stream->path_name, S_IRWXU | S_IRWXG);
+ ret = utils_mkdir_recursive(stream->path_name, S_IRWXU | S_IRWXG,
+ -1, -1);
if (ret < 0) {
ERR("relay creating output directory");
goto err_free_stream;
goto exit;
}
- ret = utils_mkdir_recursive(opt_output_path, S_IRWXU | S_IRWXG);
+ ret = utils_mkdir_recursive(opt_output_path, S_IRWXU | S_IRWXG,
+ -1, -1);
if (ret < 0) {
ERR("Unable to create %s", opt_output_path);
goto exit;
}
/*
- * Recursively create directory using the given path and mode.
+ * Create directory using the given path and mode.
*
* On success, return 0 else a negative error code.
*/
LTTNG_HIDDEN
-int utils_mkdir_recursive(const char *path, mode_t mode)
+int utils_mkdir(const char *path, mode_t mode, int uid, int gid)
+{
+ int ret;
+
+ if (uid < 0 || gid < 0) {
+ ret = mkdir(path, mode);
+ } else {
+ ret = run_as_mkdir(path, mode, uid, gid);
+ }
+ if (ret < 0) {
+ if (errno != EEXIST) {
+ PERROR("mkdir %s, uid %d, gid %d", path ? path : "NULL",
+ uid, gid);
+ } else {
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Internal version of mkdir_recursive. Runs as the current user.
+ * Don't call directly; use utils_mkdir_recursive().
+ *
+ * This function is ominously marked as "unsafe" since it should only
+ * be called by a caller that has transitioned to the uid and gid under which
+ * the directory creation should occur.
+ */
+LTTNG_HIDDEN
+int _utils_mkdir_recursive_unsafe(const char *path, mode_t mode)
{
char *p, tmp[PATH_MAX];
size_t len;
ret = mkdir(tmp, mode);
if (ret < 0) {
if (errno != EEXIST) {
- PERROR("mkdir recursive last piece");
+ PERROR("mkdir recursive last element");
ret = -errno;
} else {
ret = 0;
return ret;
}
+/*
+ * Recursively create directory using the given path and mode, under the
+ * provided uid and gid.
+ *
+ * On success, return 0 else a negative error code.
+ */
+LTTNG_HIDDEN
+int utils_mkdir_recursive(const char *path, mode_t mode, int uid, int gid)
+{
+ int ret;
+
+ if (uid < 0 || gid < 0) {
+ /* Run as current user. */
+ ret = _utils_mkdir_recursive_unsafe(path, mode);
+ } else {
+ ret = run_as_mkdir_recursive(path, mode, uid, gid);
+ }
+ if (ret < 0) {
+ PERROR("mkdir %s, uid %d, gid %d", path ? path : "NULL",
+ uid, gid);
+ }
+
+ return ret;
+}
+
/*
* Create the stream tracefile on disk.
+ * path is the output parameter. It needs to be PATH_MAX len.
*
* Return 0 on success or else a negative value.
*/
char *utils_strdupdelim(const char *begin, const char *end);
int utils_set_fd_cloexec(int fd);
int utils_create_pid_file(pid_t pid, const char *filepath);
-int utils_mkdir_recursive(const char *path, mode_t mode);
+int utils_mkdir(const char *path, mode_t mode, int uid, int gid);
+int utils_mkdir_recursive(const char *path, mode_t mode, int uid, int gid);
int utils_create_stream_file(const char *path_name, char *file_name, uint64_t size,
uint64_t count, int uid, int gid, char *suffix);
int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size,