shm-path: remove directory hierarchy on destroy
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 15 Dec 2014 03:29:53 +0000 (22:29 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 26 Mar 2015 22:07:29 +0000 (18:07 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
19 files changed:
src/bin/lttng-sessiond/buffer-registry.c
src/bin/lttng-sessiond/buffer-registry.h
src/bin/lttng-sessiond/consumer.c
src/bin/lttng-sessiond/consumer.h
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/session.c
src/bin/lttng-sessiond/trace-ust.h
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng-sessiond/ust-app.h
src/bin/lttng-sessiond/ust-consumer.c
src/bin/lttng-sessiond/ust-registry.c
src/bin/lttng-sessiond/ust-registry.h
src/common/consumer.c
src/common/consumer.h
src/common/kernel-consumer/kernel-consumer.c
src/common/sessiond-comm/sessiond-comm.h
src/common/ust-consumer/ust-consumer.c
src/common/utils.c
src/common/utils.h

index b96e585001c9bf7f420b0aac1ce274329550ce7c..b4667a41b84f6ae5e3ccf03d2215cfe86feeefd6 100644 (file)
@@ -107,7 +107,7 @@ void buffer_reg_init_uid_registry(void)
  */
 int buffer_reg_uid_create(uint64_t session_id, uint32_t bits_per_long, uid_t uid,
                enum lttng_domain_type domain, struct buffer_reg_uid **regp,
-               const char *shm_path)
+               const char *root_shm_path, const char *shm_path)
 {
        int ret = 0;
        struct buffer_reg_uid *reg = NULL;
@@ -133,6 +133,8 @@ int buffer_reg_uid_create(uint64_t session_id, uint32_t bits_per_long, uid_t uid
        reg->uid = uid;
        reg->domain = domain;
        if (shm_path[0]) {
+               strncpy(reg->root_shm_path, root_shm_path, sizeof(reg->root_shm_path));
+               reg->root_shm_path[sizeof(reg->root_shm_path) - 1] = '\0';
                strncpy(reg->shm_path, shm_path, sizeof(reg->shm_path));
                reg->shm_path[sizeof(reg->shm_path) - 1] = '\0';
                DBG3("shm path '%s' is assigned to uid buffer registry for session id %" PRIu64,
@@ -233,7 +235,7 @@ void buffer_reg_init_pid_registry(void)
  * Return 0 on success else a negative value and regp is untouched.
  */
 int buffer_reg_pid_create(uint64_t session_id, struct buffer_reg_pid **regp,
-               const char *shm_path)
+               const char *root_shm_path, const char *shm_path)
 {
        int ret = 0;
        struct buffer_reg_pid *reg = NULL;
@@ -257,6 +259,8 @@ int buffer_reg_pid_create(uint64_t session_id, struct buffer_reg_pid **regp,
        /* A cast is done here so we can use the session ID as a u64 ht node. */
        reg->session_id = session_id;
        if (shm_path[0]) {
+               strncpy(reg->root_shm_path, root_shm_path, sizeof(reg->root_shm_path));
+               reg->root_shm_path[sizeof(reg->root_shm_path) - 1] = '\0';
                strncpy(reg->shm_path, shm_path, sizeof(reg->shm_path));
                reg->shm_path[sizeof(reg->shm_path) - 1] = '\0';
                DBG3("shm path '%s' is assigned to pid buffer registry for session id %" PRIu64,
index d17bbab623d5ae34a707d46b9d6bbf871213a8c7..7a817ec70464786c44c6d12e5e663516c63cfce1 100644 (file)
@@ -89,6 +89,7 @@ struct buffer_reg_uid {
        /* Node of a linked list used to teardown object at a destroy session. */
        struct cds_list_head lnode;
 
+       char root_shm_path[PATH_MAX];
        char shm_path[PATH_MAX];
 };
 
@@ -103,6 +104,7 @@ struct buffer_reg_pid {
        /* Indexed by session id. */
        struct lttng_ht_node_u64 node;
 
+       char root_shm_path[PATH_MAX];
        char shm_path[PATH_MAX];
 };
 
@@ -110,7 +112,7 @@ struct buffer_reg_pid {
 void buffer_reg_init_uid_registry(void);
 int buffer_reg_uid_create(uint64_t session_id, uint32_t bits_per_long, uid_t uid,
                enum lttng_domain_type domain, struct buffer_reg_uid **regp,
-               const char *shm_path);
+               const char *root_shm_path, const char *shm_path);
 void buffer_reg_uid_add(struct buffer_reg_uid *reg);
 struct buffer_reg_uid *buffer_reg_uid_find(uint64_t session_id,
                uint32_t bits_per_long, uid_t uid);
@@ -121,7 +123,7 @@ void buffer_reg_uid_destroy(struct buffer_reg_uid *regp,
 /* Buffer registry per PID. */
 void buffer_reg_init_pid_registry(void);
 int buffer_reg_pid_create(uint64_t session_id, struct buffer_reg_pid **regp,
-               const char *shm_path);
+               const char *root_shm_path, const char *shm_path);
 void buffer_reg_pid_add(struct buffer_reg_pid *reg);
 struct buffer_reg_pid *buffer_reg_pid_find(uint64_t session_id);
 void buffer_reg_pid_remove(struct buffer_reg_pid *regp);
index 628201e07c0f4477eafb1079a5cd96cf0677ecee..87d5f34387befba860e31feefe0059a9c8c12f9b 100644 (file)
@@ -802,6 +802,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg,
                uint64_t session_id_per_pid,
                unsigned int monitor,
                uint32_t ust_app_uid,
+               const char *root_shm_path,
                const char *shm_path)
 {
        assert(msg);
@@ -841,6 +842,11 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg,
        strncpy(msg->u.ask_channel.name, name, sizeof(msg->u.ask_channel.name));
        msg->u.ask_channel.name[sizeof(msg->u.ask_channel.name) - 1] = '\0';
 
+       if (root_shm_path) {
+               strncpy(msg->u.ask_channel.root_shm_path, root_shm_path,
+                       sizeof(msg->u.ask_channel.root_shm_path));
+               msg->u.ask_channel.root_shm_path[sizeof(msg->u.ask_channel.root_shm_path) - 1] = '\0';
+       }
        if (shm_path) {
                strncpy(msg->u.ask_channel.shm_path, shm_path,
                        sizeof(msg->u.ask_channel.shm_path));
index 0b67c08287df7be67430e3c7c76465d22e94a80b..e4845f5272904dc85d52669ae26740beadb93e07 100644 (file)
@@ -241,6 +241,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg,
                uint64_t session_id_per_pid,
                unsigned int monitor,
                uint32_t ust_app_uid,
+               const char *root_shm_path,
                const char *shm_path);
 void consumer_init_stream_comm_msg(struct lttcomm_consumer_msg *msg,
                enum lttng_consumer_command cmd,
index c542179371327b951d71255902b949c789f265fd..f8f2a7ce3c1624923f8af606b620fe8f5f443fe3 100644 (file)
@@ -2766,6 +2766,9 @@ static int create_ust_session(struct ltt_session *session,
        lus->live_timer_interval = session->live_timer;
        session->ust_session = lus;
        if (session->shm_path[0]) {
+               strncpy(lus->root_shm_path, session->shm_path,
+                       sizeof(lus->root_shm_path));
+               lus->root_shm_path[sizeof(lus->root_shm_path) - 1] = '\0';
                strncpy(lus->shm_path, session->shm_path,
                        sizeof(lus->shm_path));
                lus->shm_path[sizeof(lus->shm_path) - 1] = '\0';
index 99b0165070ebc296c9f2bc9dc46a6d5967703741..b82a330e92da376aef158bddfd8448f925c7a603 100644 (file)
@@ -24,6 +24,8 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <urcu.h>
+#include <dirent.h>
+#include <sys/types.h>
 
 #include <common/common.h>
 #include <common/sessiond-comm/sessiond-comm.h>
index 63564ff71f296e3eed9c7ec7159c590db78cb076..8be813877410fb129a1b0ff3124693580c89161a 100644 (file)
@@ -117,6 +117,7 @@ struct ltt_ust_session {
        /*
         * Path where to keep the shared memory files.
         */
+       char root_shm_path[PATH_MAX];
        char shm_path[PATH_MAX];
 };
 
index 480971b8982287e980ca09836d72b2105b869b23..183d12559e06da24842faeba31a36a0802658bc8 100644 (file)
@@ -1637,6 +1637,9 @@ static void shadow_copy_session(struct ust_app_session *ua_sess,
                goto error;
        }
 
+       strncpy(ua_sess->root_shm_path, usess->root_shm_path,
+               sizeof(ua_sess->root_shm_path));
+       ua_sess->root_shm_path[sizeof(ua_sess->root_shm_path) - 1] = '\0';
        strncpy(ua_sess->shm_path, usess->shm_path,
                sizeof(ua_sess->shm_path));
        ua_sess->shm_path[sizeof(ua_sess->shm_path) - 1] = '\0';
@@ -1758,7 +1761,7 @@ static int setup_buffer_reg_pid(struct ust_app_session *ua_sess,
                 * registry available, we have to create one for this session.
                 */
                ret = buffer_reg_pid_create(ua_sess->id, &reg_pid,
-                       ua_sess->shm_path);
+                       ua_sess->root_shm_path, ua_sess->shm_path);
                if (ret < 0) {
                        goto error;
                }
@@ -1772,7 +1775,8 @@ static int setup_buffer_reg_pid(struct ust_app_session *ua_sess,
                        app->uint16_t_alignment, app->uint32_t_alignment,
                        app->uint64_t_alignment, app->long_alignment,
                        app->byte_order, app->version.major,
-                       app->version.minor, reg_pid->shm_path,
+                       app->version.minor, reg_pid->root_shm_path,
+                       reg_pid->shm_path,
                        ua_sess->euid, ua_sess->egid);
        if (ret < 0) {
                /*
@@ -1824,7 +1828,8 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess,
                 * registry available, we have to create one for this session.
                 */
                ret = buffer_reg_uid_create(usess->id, app->bits_per_long, app->uid,
-                               LTTNG_DOMAIN_UST, &reg_uid, ua_sess->shm_path);
+                               LTTNG_DOMAIN_UST, &reg_uid,
+                               ua_sess->root_shm_path, ua_sess->shm_path);
                if (ret < 0) {
                        goto error;
                }
@@ -1838,8 +1843,8 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess,
                        app->uint16_t_alignment, app->uint32_t_alignment,
                        app->uint64_t_alignment, app->long_alignment,
                        app->byte_order, app->version.major,
-                       app->version.minor, reg_uid->shm_path,
-                       usess->uid, usess->gid);
+                       app->version.minor, reg_uid->root_shm_path,
+                       reg_uid->shm_path, usess->uid, usess->gid);
        if (ret < 0) {
                /*
                 * reg_uid->registry->reg.ust is NULL upon error, so we need to
index 59ef85b78cf9c082eb00b407066a1e78a272acb7..d6b675bec36dcd357b05e027dcf7b7a98e0015b7 100644 (file)
@@ -216,6 +216,7 @@ struct ust_app_session {
        /* Metadata channel attributes. */
        struct ustctl_consumer_channel_attr metadata_attr;
 
+       char root_shm_path[PATH_MAX];
        char shm_path[PATH_MAX];
 };
 
index 8a3533ba10c360097a8fb2cb0099a4f3d986f324..78e50df43fab90dab22892095f85050e1b1d2e11 100644 (file)
@@ -110,6 +110,7 @@ static int ask_channel_creation(struct ust_app_session *ua_sess,
        struct lttcomm_consumer_msg msg;
        struct ust_registry_channel *chan_reg;
        char shm_path[PATH_MAX] = "";
+       char root_shm_path[PATH_MAX] = "";
 
        assert(ua_sess);
        assert(ua_chan);
@@ -156,6 +157,8 @@ static int ask_channel_creation(struct ust_app_session *ua_sess,
                                strncat(shm_path, "_",
                                        sizeof(shm_path) - strlen(shm_path) - 1);
                }
+               strncpy(root_shm_path, ua_sess->root_shm_path, sizeof(root_shm_path));
+               root_shm_path[sizeof(root_shm_path) - 1] = '\0';
        }
 
        switch (ua_chan->attr.output) {
@@ -188,7 +191,7 @@ static int ask_channel_creation(struct ust_app_session *ua_sess,
                        ua_sess->id,
                        ua_sess->output_traces,
                        ua_sess->uid,
-                       shm_path);
+                       root_shm_path, shm_path);
 
        health_code_update();
 
index 26f306d52d516ac6091e74a1cb26ef73821dbbbd..f9ddd25a5928e197d15834446fa9710ec665a44b 100644 (file)
@@ -547,6 +547,7 @@ int ust_registry_session_init(struct ust_registry_session **sessionp,
                int byte_order,
                uint32_t major,
                uint32_t minor,
+               const char *root_shm_path,
                const char *shm_path,
                uid_t euid,
                gid_t egid)
@@ -571,6 +572,9 @@ int ust_registry_session_init(struct ust_registry_session **sessionp,
        session->long_alignment = long_alignment;
        session->byte_order = byte_order;
        session->metadata_fd = -1;
+       strncpy(session->root_shm_path, root_shm_path,
+               sizeof(session->root_shm_path));
+       session->root_shm_path[sizeof(session->root_shm_path) - 1] = '\0';
        if (shm_path[0]) {
                strncpy(session->shm_path, shm_path,
                        sizeof(session->shm_path));
@@ -676,4 +680,10 @@ void ust_registry_session_destroy(struct ust_registry_session *reg)
                        PERROR("unlink");
                }
        }
+       if (reg->root_shm_path[0]) {
+               /*
+                * Try deleting the directory hierarchy.
+                */
+               (void) utils_recursive_rmdir(reg->root_shm_path);
+       }
 }
index a22009efa996263cf9a17b2fe08941b5a088f92a..91a0534e9a8cbde5084878d45125da310589644a 100644 (file)
@@ -67,6 +67,7 @@ struct ust_registry_session {
        /* Length of bytes sent to the consumer. */
        size_t metadata_len_sent;
 
+       char root_shm_path[PATH_MAX];
        char shm_path[PATH_MAX];
        char metadata_path[PATH_MAX];
        int metadata_fd;        /* file-backed metadata FD */
@@ -231,6 +232,7 @@ int ust_registry_session_init(struct ust_registry_session **sessionp,
                int byte_order,
                uint32_t major,
                uint32_t minor,
+               const char *root_shm_path,
                const char *shm_path,
                uid_t euid,
                gid_t egid);
index 1cb1c47431303e6ed3c516948a78b5807855c48c..effa5f86f38cfa67247fdbd17a214c34f42c5703 100644 (file)
@@ -937,6 +937,7 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key,
                uint64_t session_id_per_pid,
                unsigned int monitor,
                unsigned int live_timer_interval,
+               const char *root_shm_path,
                const char *shm_path)
 {
        struct lttng_consumer_channel *channel;
@@ -994,6 +995,10 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key,
        strncpy(channel->name, name, sizeof(channel->name));
        channel->name[sizeof(channel->name) - 1] = '\0';
 
+       if (root_shm_path) {
+               strncpy(channel->root_shm_path, root_shm_path, sizeof(channel->root_shm_path));
+               channel->root_shm_path[sizeof(channel->root_shm_path) - 1] = '\0';
+       }
        if (shm_path) {
                strncpy(channel->shm_path, shm_path, sizeof(channel->shm_path));
                channel->shm_path[sizeof(channel->shm_path) - 1] = '\0';
index a80bc40ab9128e8ae3c5987bd4c8870736cc35bb..7f885370e33127448edcc3cf623346d3ce1642f9 100644 (file)
@@ -207,6 +207,7 @@ struct lttng_consumer_channel {
        /* Timer value in usec for live streaming. */
        unsigned int live_timer_interval;
 
+       char root_shm_path[PATH_MAX];
        char shm_path[PATH_MAX];
 };
 
@@ -602,6 +603,7 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key,
                uint64_t session_id_per_pid,
                unsigned int monitor,
                unsigned int live_timer_interval,
+               const char *root_shm_path,
                const char *shm_path);
 void consumer_del_stream(struct lttng_consumer_stream *stream,
                struct lttng_ht *ht);
index 0af417b9cdb701f657bb34ddcf0d65a1487bb455..e30d21b1ac59e77437ed983e39b5a8ada2e17dff 100644 (file)
@@ -481,7 +481,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.channel.tracefile_count, 0,
                                msg.u.channel.monitor,
                                msg.u.channel.live_timer_interval,
-                               NULL);
+                               NULL, NULL);
                if (new_channel == NULL) {
                        lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
                        goto end_nosignal;
index baf608ffd748fd3036e52547d850ccb84c66be98..5078b522b08280baea722578cb712f0bc0d26e9f 100644 (file)
@@ -430,6 +430,7 @@ struct lttcomm_consumer_msg {
                         * because the application can be in the tracing for instance.
                         */
                        uint32_t ust_app_uid;
+                       char root_shm_path[PATH_MAX];
                        char shm_path[PATH_MAX];
                } LTTNG_PACKED ask_channel;
                struct {
index 81f6859124c1353d89dbb36b38f8549761f33d53..6898bb115f0a41cfd783d42df6c4270a397d0369 100644 (file)
@@ -81,6 +81,10 @@ static void destroy_channel(struct lttng_consumer_channel *channel)
        if (channel->uchan) {
                lttng_ustconsumer_del_channel(channel);
        }
+       /* Try to rmdir all directories under shm_path root. */
+       if (channel->root_shm_path[0]) {
+               (void) utils_recursive_rmdir(channel->root_shm_path);
+       }
        free(channel);
 }
 
@@ -125,7 +129,7 @@ static struct lttng_consumer_channel *allocate_channel(uint64_t session_id,
                uint64_t tracefile_size, uint64_t tracefile_count,
                uint64_t session_id_per_pid, unsigned int monitor,
                unsigned int live_timer_interval,
-               const char *shm_path)
+               const char *root_shm_path, const char *shm_path)
 {
        assert(pathname);
        assert(name);
@@ -133,7 +137,7 @@ static struct lttng_consumer_channel *allocate_channel(uint64_t session_id,
        return consumer_allocate_channel(key, session_id, pathname, name, uid,
                        gid, relayd_id, output, tracefile_size,
                        tracefile_count, session_id_per_pid, monitor,
-                       live_timer_interval, shm_path);
+                       live_timer_interval, root_shm_path, shm_path);
 }
 
 /*
@@ -1213,6 +1217,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                msg.u.ask_channel.session_id_per_pid,
                                msg.u.ask_channel.monitor,
                                msg.u.ask_channel.live_timer_interval,
+                               msg.u.ask_channel.root_shm_path,
                                msg.u.ask_channel.shm_path);
                if (!channel) {
                        goto end_channel_error;
@@ -1678,6 +1683,10 @@ void lttng_ustconsumer_del_channel(struct lttng_consumer_channel *chan)
        }
        consumer_metadata_cache_destroy(chan);
        ustctl_destroy_channel(chan->uchan);
+       /* Try to rmdir all directories under shm_path root. */
+       if (chan->root_shm_path[0]) {
+               (void) utils_recursive_rmdir(chan->root_shm_path);
+       }
 }
 
 void lttng_ustconsumer_del_stream(struct lttng_consumer_stream *stream)
index 9a53330004931408df017fb4b2ebbd87ad31a61e..f9e6a99eafeec26afa4c7640f8a8d5a2c64178b1 100644 (file)
@@ -32,6 +32,7 @@
 #include <grp.h>
 #include <pwd.h>
 #include <sys/file.h>
+#include <dirent.h>
 
 #include <common/common.h>
 #include <common/runas.h>
@@ -1058,3 +1059,67 @@ char *utils_generate_optstring(const struct option *long_options,
 end:
        return optstring;
 }
+
+/*
+ * Try to remove a hierarchy of empty directories, recursively. Don't unlink
+ * any file.
+ */
+LTTNG_HIDDEN
+int utils_recursive_rmdir(const char *path)
+{
+       DIR *dir;
+       int dir_fd, ret = 0, closeret;
+       struct dirent *entry;
+
+       /* Open directory */
+       dir = opendir(path);
+       if (!dir) {
+               PERROR("Cannot open '%s' path", path);
+               return -1;
+       }
+       dir_fd = dirfd(dir);
+       if (dir_fd < 0) {
+               PERROR("dirfd");
+               return -1;
+       }
+
+       while ((entry = readdir(dir))) {
+               if (!strcmp(entry->d_name, ".")
+                               || !strcmp(entry->d_name, ".."))
+                       continue;
+               switch (entry->d_type) {
+               case DT_DIR:
+               {
+                       char subpath[PATH_MAX];
+
+                       strncpy(subpath, path, PATH_MAX);
+                       subpath[PATH_MAX - 1] = '\0';
+                       strncat(subpath, "/",
+                               PATH_MAX - strlen(subpath) - 1);
+                       strncat(subpath, entry->d_name,
+                               PATH_MAX - strlen(subpath) - 1);
+                       ret = utils_recursive_rmdir(subpath);
+                       if (ret) {
+                               goto end;
+                       }
+                       break;
+               }
+               case DT_REG:
+                       ret = -EBUSY;
+                       goto end;
+               default:
+                       ret = -EINVAL;
+                       goto end;
+               }
+       }
+end:
+       closeret = closedir(dir);
+       if (closeret) {
+               PERROR("closedir");
+       }
+       if (!ret) {
+               DBG3("Attempting rmdir %s", path);
+               ret = rmdir(path);
+       }
+       return ret;
+}
index 537fe0f9e6cf1017cafbe7cbd43fa5f054291a3e..05914cc37d694b28e8846adba3587df9526e1623 100644 (file)
@@ -54,5 +54,6 @@ gid_t utils_get_group_id(const char *name);
 char *utils_generate_optstring(const struct option *long_options,
                size_t opt_count);
 int utils_create_lock_file(const char *filepath);
+int utils_recursive_rmdir(const char *path);
 
 #endif /* _COMMON_UTILS_H */
This page took 0.035467 seconds and 4 git commands to generate.