]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
libcephfs_proxy: add option to specify the working directory
authorXavi Hernandez <xhernandez@gmail.com>
Tue, 13 Jan 2026 12:23:28 +0000 (13:23 +0100)
committerXavi Hernandez <xhernandez@gmail.com>
Tue, 10 Feb 2026 07:20:27 +0000 (08:20 +0100)
Signed-off-by: Xavi Hernandez <xhernandez@gmail.com>
src/libcephfs_proxy/libcephfsd.c
src/libcephfs_proxy/proxy.h
src/libcephfs_proxy/proxy_mount.c

index bbb5700d21fffd30f400f8ea48e818cc3e1d7a90..cb424fea65f0deb4439177e211169f1acc5e3403 100644 (file)
@@ -2232,15 +2232,48 @@ static bool check_stop(proxy_link_t *link)
 static int32_t server_start(proxy_manager_t *manager)
 {
        proxy_server_t server;
+       struct stat st;
        proxy_t *proxy;
+       const char *path;
+       char *wd;
+       int32_t err;
 
        proxy = container_of(manager, proxy_t, manager);
 
        server.manager = manager;
        server.settings = &proxy->settings;
 
-       return proxy_link_server(&server.link, &proxy->settings,
-                                accept_connection, check_stop);
+       path = proxy->settings.work_dir;
+       wd = realpath(path, NULL);
+       if (wd == NULL) {
+               return proxy_log(LOG_ERR, errno,
+                                "Failed to resolve the working directory");
+       }
+
+       if (stat(wd, &st) < 0) {
+               err = proxy_log(LOG_ERR, errno,
+                               "Failed to check the working directory");
+               goto done;
+       }
+
+       if (!S_ISDIR(st.st_mode)) {
+               err = proxy_log(LOG_ERR, EINVAL,
+                               "The provided path for the working directory "
+                               "is not a directory");
+               goto done;
+       }
+
+       proxy->settings.work_dir = wd;
+
+       err = proxy_link_server(&server.link, &proxy->settings,
+                               accept_connection, check_stop);
+
+       proxy->settings.work_dir = path;
+
+done:
+       free(wd);
+
+       return err;
 }
 
 static void log_format(struct iovec *iov, char *buffer, size_t size,
@@ -2294,10 +2327,13 @@ static void log_print(proxy_log_handler_t *handler, int32_t level, int32_t err,
 }
 
 static struct option main_opts[] = {
-       {"socket", required_argument, NULL, 's'},
+       {"socket",   required_argument, NULL, 's'},
+       {"work-dir", required_argument, NULL, 'w'},
        {}
 };
 
+static const char short_opts[] = ":s:w:";
+
 int32_t main(int32_t argc, char *argv[])
 {
        struct timespec now;
@@ -2313,15 +2349,18 @@ int32_t main(int32_t argc, char *argv[])
        proxy_log_register(&proxy.log_handler, log_print);
 
        proxy.settings.socket_path = PROXY_SOCKET;
+       proxy.settings.work_dir = ".";
 
        env = getenv(PROXY_SOCKET_ENV);
        if (env != NULL) {
                proxy.settings.socket_path = env;
        }
 
-       while ((val = getopt_long(argc, argv, ":s:", main_opts, NULL)) >= 0) {
+       while ((val = getopt_long(argc, argv, short_opts, main_opts, NULL)) >= 0) {
                if (val == 's') {
                        proxy.settings.socket_path = optarg;
+               } else if (val == 'w') {
+                       proxy.settings.work_dir = optarg;
                } else if (val == ':') {
                        proxy_log(LOG_ERR, ENODATA,
                                  "Argument missing for '%s'\n", optopt);
index f5a409625f2233d868b95013c9471832ee50a1b4..e0295e4ecf3d109fa830f1ffee46d99ac5d69308 100644 (file)
@@ -97,6 +97,7 @@ struct _list {
 
 struct _proxy_settings {
        const char *socket_path;
+       const char *work_dir;
 };
 
 #endif
index 33cc0e62c318024e3ef658b5a11cc1ee52db76ee..1c404f64e26b2e529d871ab65d962176f107486a 100644 (file)
@@ -554,11 +554,11 @@ static int32_t proxy_config_source_validate(int32_t fd, struct stat *before,
        return 1;
 }
 
-static int32_t proxy_config_destination_prepare(void)
+static int32_t proxy_config_destination_prepare(proxy_settings_t *settings)
 {
        int32_t fd;
 
-       fd = openat(AT_FDCWD, ".", O_TMPFILE | O_WRONLY, 0600);
+       fd = open(settings->work_dir, O_TMPFILE | O_WRONLY, 0600);
        if (fd < 0) {
                return proxy_log(LOG_ERR, errno, "openat() failed");
        }
@@ -587,16 +587,17 @@ static int32_t proxy_config_destination_write(int32_t fd, void *data,
        return size;
 }
 
-static int32_t proxy_config_destination_commit(int32_t fd, const char *name)
+static int32_t proxy_config_destination_commit(proxy_settings_t *settings,
+                                              int32_t fd, const char *path)
 {
-       char path[32];
+       char fd_path[32];
        int32_t len;
 
        if (fsync(fd) < 0) {
                return proxy_log(LOG_ERR, errno, "fsync() failed");
        }
 
-       if (linkat(fd, "", AT_FDCWD, name, AT_EMPTY_PATH) < 0) {
+       if (linkat(fd, "", AT_FDCWD, path, AT_EMPTY_PATH) < 0) {
                if (errno == EEXIST) {
                        return 0;
                }
@@ -606,12 +607,12 @@ static int32_t proxy_config_destination_commit(int32_t fd, const char *name)
                 * filesystem. */
        }
 
-       len = proxy_snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
+       len = proxy_snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d", fd);
        if (len < 0) {
                return len;
        }
 
-       if (linkat(AT_FDCWD, path, AT_FDCWD, name, AT_SYMLINK_FOLLOW) < 0) {
+       if (linkat(AT_FDCWD, fd_path, AT_FDCWD, path, AT_SYMLINK_FOLLOW) < 0) {
                if (errno != EEXIST) {
                        return proxy_log(LOG_ERR, errno, "linkat() failed");
                }
@@ -646,7 +647,8 @@ static int32_t proxy_config_transfer(void **ptr, void *data, int32_t idx)
 
 /* Copies and checksums a given configuration to a file and makes sure that it
  * has not been modified. */
-static int32_t proxy_config_prepare(const char *config, char *path,
+static int32_t proxy_config_prepare(proxy_settings_t *settings,
+                                   const char *config, char *path,
                                    int32_t size)
 {
        char hash[65];
@@ -667,7 +669,7 @@ static int32_t proxy_config_prepare(const char *config, char *path,
                goto done_mem;
        }
 
-       cfg.dst = proxy_config_destination_prepare();
+       cfg.dst = proxy_config_destination_prepare(settings);
        if (cfg.dst < 0) {
                err = cfg.dst;
                goto done_src;
@@ -683,12 +685,13 @@ static int32_t proxy_config_prepare(const char *config, char *path,
                goto done_dst;
        }
 
-       err = proxy_snprintf(path, size, "ceph-%s.conf", hash);
+       err = proxy_snprintf(path, size, "%s/ceph-%s.conf", settings->work_dir,
+                            hash);
        if (err < 0) {
                goto done_dst;
        }
 
-       err = proxy_config_destination_commit(cfg.dst, path);
+       err = proxy_config_destination_commit(settings, cfg.dst, path);
 
 done_dst:
        proxy_config_destination_close(cfg.dst);
@@ -826,7 +829,7 @@ static int32_t proxy_instance_release(proxy_instance_t *instance)
 static int32_t proxy_instance_config(proxy_instance_t *instance,
                                     const char *config)
 {
-       char path[128], *ppath;
+       char path[strlen(instance->settings->work_dir) + 128], *ppath;
        int32_t err;
 
        if (instance->mounted) {
@@ -836,7 +839,8 @@ static int32_t proxy_instance_config(proxy_instance_t *instance,
 
        ppath = NULL;
        if (config != NULL) {
-               err = proxy_config_prepare(config, path, sizeof(path));
+               err = proxy_config_prepare(instance->settings, config, path,
+                                          sizeof(path));
                if (err < 0) {
                        return err;
                }