X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fcommon%2Futils.c;h=5ce597f5eaa59528e7df8fe38b47cf4159de1a7d;hb=bdafebb5195cfda710b32b019f9cac6c4d86f42a;hp=24c3b8ca146ff1fafe8de8da3dd059c7f947f415;hpb=b61e1dca934c1cda7632d154c243dcf56aabac60;p=deliverable%2Flttng-tools.git diff --git a/src/common/utils.c b/src/common/utils.c index 24c3b8ca1..5ce597f5e 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -712,7 +712,8 @@ int utils_mkdir_recursive(const char *path, mode_t mode, int uid, int gid) * * Return 0 on success or else a negative value. */ -static int utils_stream_file_name(char *path, +LTTNG_HIDDEN +int utils_stream_file_name(char *path, const char *path_name, const char *file_name, uint64_t size, uint64_t count, const char *suffix) @@ -831,6 +832,36 @@ error: return ret; } +LTTNG_HIDDEN +void utils_stream_file_rotation_get_new_count(uint64_t count, + uint64_t *new_count, bool *should_unlink) +{ + if (count > 0) { + /* + * In tracefile rotation, for the relay daemon we need + * to unlink the old file if present, because it may + * still be open in reading by the live thread, and we + * need to ensure that we do not overwrite the content + * between get_index and get_packet. Since we have no + * way to verify integrity of the data content compared + * to the associated index, we need to ensure the reader + * has exclusive access to the file content, and that + * the open of the data file is performed in get_index. + * Unlinking the old file rather than overwriting it + * achieves this. + */ + if (new_count) { + *new_count = (*new_count + 1) % count; + } + *should_unlink = true; + } else { + if (new_count) { + (*new_count)++; + } + *should_unlink = false; + } +} + /* * Change the output tracefile according to the given size and count The * new_count pointer is set during this operation. @@ -846,9 +877,13 @@ int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size, int *stream_fd) { int ret; + bool should_unlink; assert(stream_fd); + utils_stream_file_rotation_get_new_count(count, new_count, + &should_unlink); + ret = close(out_fd); if (ret < 0) { PERROR("Closing tracefile"); @@ -856,32 +891,12 @@ int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size, } *stream_fd = -1; - if (count > 0) { - /* - * In tracefile rotation, for the relay daemon we need - * to unlink the old file if present, because it may - * still be open in reading by the live thread, and we - * need to ensure that we do not overwrite the content - * between get_index and get_packet. Since we have no - * way to verify integrity of the data content compared - * to the associated index, we need to ensure the reader - * has exclusive access to the file content, and that - * the open of the data file is performed in get_index. - * Unlinking the old file rather than overwriting it - * achieves this. - */ - if (new_count) { - *new_count = (*new_count + 1) % count; - } + if (should_unlink) { ret = utils_unlink_stream_file(path_name, file_name, size, new_count ? *new_count : 0, uid, gid, 0); if (ret < 0 && errno != ENOENT) { goto error; } - } else { - if (new_count) { - (*new_count)++; - } } ret = utils_create_stream_file(path_name, file_name, size, @@ -1017,6 +1032,59 @@ static inline unsigned int fls_u32(uint32_t x) #define HAS_FLS_U32 #endif +#if defined(__x86_64) +static inline +unsigned int fls_u64(uint64_t x) +{ + long r; + + asm("bsrq %1,%0\n\t" + "jnz 1f\n\t" + "movq $-1,%0\n\t" + "1:\n\t" + : "=r" (r) : "rm" (x)); + return r + 1; +} +#define HAS_FLS_U64 +#endif + +#ifndef HAS_FLS_U64 +static __attribute__((unused)) +unsigned int fls_u64(uint64_t x) +{ + unsigned int r = 64; + + if (!x) + return 0; + + if (!(x & 0xFFFFFFFF00000000ULL)) { + x <<= 32; + r -= 32; + } + if (!(x & 0xFFFF000000000000ULL)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xFF00000000000000ULL)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xF000000000000000ULL)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xC000000000000000ULL)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x8000000000000000ULL)) { + x <<= 1; + r -= 1; + } + return r; +} +#endif + #ifndef HAS_FLS_U32 static __attribute__((unused)) unsigned int fls_u32(uint32_t x) { @@ -1063,6 +1131,20 @@ int utils_get_count_order_u32(uint32_t x) return fls_u32(x - 1); } +/* + * Return the minimum order for which x <= (1UL << order). + * Return -1 if x is 0. + */ +LTTNG_HIDDEN +int utils_get_count_order_u64(uint64_t x) +{ + if (!x) { + return -1; + } + + return fls_u64(x - 1); +} + /** * Obtain the value of LTTNG_HOME environment variable, if exists. * Otherwise returns the value of HOME. @@ -1385,3 +1467,33 @@ int utils_show_man_page(int section, const char *page_name) section_string, page_name, NULL); return ret; } + +LTTNG_HIDDEN +int utils_change_working_dir(const char *path) +{ + int ret; + + assert(path); + + ret = chdir(path); + if (ret) { + PERROR("Failed to change working directory: %s", path); + goto end; + } + + /* Check for write access */ + if (access(path, W_OK)) { + if (errno == EACCES) { + /* + * Do not treat this as an error since the permission + * might change in the lifetime of the process + */ + DBG("Working directory is not writable: %s", path); + } else { + PERROR("access"); + } + } + +end: + return ret; +}