if (dir_ptr->lsdo_depth == 0) {
*total_size += dir_ptr->lsdo_size;
- *total_alloc_size += dir_ptr->lsdo_alloc_size_in_512blocks * 512;
+ *total_alloc_size += dir_ptr->lsdo_alloc_size_in_sectors * 512;
}
/* dir_stats->lsdg_min_size_value_for_print is initialized
if (dir_ptr->lsdo_depth >= 0 &&
dir_ptr->lsdo_size >= dir_stats->lsdg_min_size_value_for_print &&
!top_rating_only && out_fd) {
- allocate_dir_size = dir_ptr->lsdo_alloc_size_in_512blocks * 512;
+ allocate_dir_size = dir_ptr->lsdo_alloc_size_in_sectors * 512;
tabulation = ls3_stats_get_dots(dir_ptr->lsdo_depth);
snprintf(fmt_str_for_fid, sizeof(fmt_str_for_fid),
continue; /* skip first dir */
allocate_dir_size =
- heap->lsdr_array[i]->lsdo_alloc_size_in_512blocks * 512;
+ heap->lsdr_array[i]->lsdo_alloc_size_in_sectors * 512;
/* prepare FID */
snprintf(fid_str, sizeof(fid_str), DFID_NOBRACE,
PFID(&heap->lsdr_array[i]->lsdo_fid));
}
}
+/* ls3_stats_fprintf_dir_json_recursive - Recursively traverse a directory tree
+ * in memory and prints statistics for each directory to a
+ * file if all conditions are met.
+ */
+static struct json_object *ls3_stats_fprintf_dir_json_recursive(
+ struct ls3_stats_dir_obj *dir_ptr,
+ bool top_rating_only,
+ uint64_t *total_size,
+ uint64_t *total_alloc_size)
+{
+ struct json_object *jobj_dir_obj;
+ struct json_object *jobj_dir_child;
+ struct ls3_stats_dir_obj *child_ptr;
+ int i;
+
+ jobj_dir_obj = json_object_new_object();
+ jobj_dir_child = json_object_new_array();
+
+ if (dir_ptr == NULL)
+ return jobj_dir_obj;
+
+ if (dir_ptr->lsdo_depth == 0) {
+ *total_size += dir_ptr->lsdo_size;
+ *total_alloc_size += dir_ptr->lsdo_alloc_size_in_sectors * 512;
+ }
+
+ if (dir_ptr->lsdo_depth >= 0 &&
+ dir_ptr->lsdo_size >= dir_stats->lsdg_min_size_value_for_print &&
+ !top_rating_only) {
+ uint64_t allocate_dir_size;
+ char fid_str[60];
+ char path[PATH_MAX] = "";
+
+ allocate_dir_size = dir_ptr->lsdo_alloc_size_in_sectors * 512;
+ snprintf(fid_str, sizeof(fid_str),
+ DFID_NOBRACE, PFID(&dir_ptr->lsdo_fid));
+
+ if (dir_ptr->lsdo_fid.f_seq != 0) {
+ int rc;
+
+ rc = llapi_fid2path(reports_with_stats->client_mount_path,
+ fid_str, path, PATH_MAX, NULL, NULL);
+ if (rc != 0)
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "cannot get path of fid %s", fid_str);
+ }
+
+ json_object_object_add(jobj_dir_obj, "SizeBytes",
+ json_object_new_int64(dir_ptr->lsdo_size));
+
+ json_object_object_add(jobj_dir_obj, "AllocatedSizeBytes",
+ json_object_new_int64(allocate_dir_size));
+
+ json_object_object_add(jobj_dir_obj, "Depth",
+ json_object_new_int64(dir_ptr->lsdo_depth));
+
+ json_object_object_add(jobj_dir_obj, "FilesCount",
+ json_object_new_int64(dir_ptr->lsdo_files_count));
+
+ json_object_object_add(jobj_dir_obj, "DirsCount",
+ json_object_new_int64(dir_ptr->lsdo_dirs_count));
+
+ json_object_object_add(jobj_dir_obj, "UserID",
+ json_object_new_int64(dir_ptr->lsdo_uid));
+
+ json_object_object_add(jobj_dir_obj, "GroupID",
+ json_object_new_int64(dir_ptr->lsdo_gid));
+
+ json_object_object_add(jobj_dir_obj, "ProjID",
+ json_object_new_int64(dir_ptr->lsdo_projid));
+
+ json_object_object_add(jobj_dir_obj, "Atime",
+ json_object_new_int64(dir_ptr->lsdo_atime));
+
+ json_object_object_add(jobj_dir_obj, "Mtime",
+ json_object_new_int64(dir_ptr->lsdo_mtime));
+
+ json_object_object_add(jobj_dir_obj, "Ctime",
+ json_object_new_int64(dir_ptr->lsdo_ctime));
+
+ json_object_object_add(jobj_dir_obj, "Crtime",
+ json_object_new_int64(dir_ptr->lsdo_crtime));
+
+ json_object_object_add(jobj_dir_obj, "FID",
+ json_object_new_string(fid_str));
+
+ json_object_object_add(jobj_dir_obj, "DirectoryName",
+ json_object_new_string(dir_ptr->lsdo_name));
+
+ json_object_object_add(jobj_dir_obj, "Path",
+ json_object_new_string(path));
+ }
+
+ /* Trying to add a directory to the rating table */
+ if (dir_stats->lsdg_top_size &&
+ !(reports_with_stats->report_extension &
+ LS3_STATS_FILE_EXTENSION_OUT)) {
+ ls3_stats_insert_heap(dir_stats->lsdg_top_size, dir_ptr);
+ }
+
+ /* We always have at least 10 pointers in stock dir_ptr->lsdo_child[] */
+ for (i = 0; i < dir_ptr->lsdo_last_child + 1; i++) {
+ struct json_object *tmp_jobj_dir_obj;
+
+ child_ptr = dir_ptr->lsdo_child[i];
+ if (child_ptr == NULL)
+ continue;
+
+ tmp_jobj_dir_obj =
+ ls3_stats_fprintf_dir_json_recursive(child_ptr,
+ top_rating_only,
+ total_size,
+ total_alloc_size);
+
+ json_object_array_add(jobj_dir_child, tmp_jobj_dir_obj);
+ }
+
+ json_object_object_add(jobj_dir_obj,
+ "ChildDirectories", jobj_dir_child);
+ return jobj_dir_obj;
+}
+
+struct json_object *ls3_stats_fprintf_dirs_json(void)
+{
+ struct json_object *jobj_dirs_rating;
+ struct json_object *jobj_objects; /* Rating */
+ struct json_object *jobj_tree;
+ struct ls3_stats_dir_rating *heap;
+ uint64_t total_size;
+ uint64_t total_alloc_size;
+ int extension = reports_with_stats->report_extension;
+ int i;
+
+ if (!dir_stats)
+ return NULL;
+
+ if (!dir_stats->lsdg_start_dir)
+ return NULL;
+
+ ls3_stats_init_heap();
+ if (!dir_stats->lsdg_top_size)
+ return NULL;
+
+ jobj_dirs_rating = json_object_new_object();
+ jobj_tree = ls3_stats_fprintf_dir_json_recursive(
+ dir_stats->lsdg_start_dir,
+ false, &total_size,
+ &total_alloc_size);
+
+ if (!(extension & LS3_STATS_FILE_EXTENSION_OUT))
+ ls3_stats_heap_sort(dir_stats->lsdg_top_size);
+
+ heap = dir_stats->lsdg_top_size;
+ jobj_objects = json_object_new_array();
+ if (!jobj_objects) {
+ json_object_put(jobj_dirs_rating);
+ LS3_WARNING("failed to initialize array for json. "
+ "Directories ranking report will not be "
+ "generated in *.json format.\n");
+ return NULL;
+ }
+
+ for (i = 0; i < heap->lsdr_current_size_heap; i++) {
+ struct ls3_stats_dir_obj *tmp_obj;
+ struct json_object *jobj_obj;
+ uint64_t alloc_dir_size;
+ char fid_str[60];
+ char path[PATH_MAX] = "";
+ int rc;
+
+ tmp_obj = heap->lsdr_array[i];
+ if (!tmp_obj)
+ continue;
+
+ if (tmp_obj->lsdo_depth < 0)
+ continue; /* skip first dir */
+
+ /* prepare FID */
+ snprintf(fid_str, sizeof(fid_str), DFID_NOBRACE,
+ PFID(&tmp_obj->lsdo_fid));
+
+ if (tmp_obj->lsdo_fid.f_seq != 0) {
+ rc = llapi_fid2path(reports_with_stats->client_mount_path,
+ fid_str, path, PATH_MAX,
+ NULL, NULL);
+ if (rc != 0)
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "cannot get path of fid %s",
+ fid_str);
+ }
+
+ jobj_obj = json_object_new_object();
+
+ json_object_object_add(jobj_obj, "RatingPosition",
+ json_object_new_int64(i));
+
+ json_object_object_add(jobj_obj, "SizeBytes",
+ json_object_new_int64(tmp_obj->lsdo_size));
+
+ alloc_dir_size = tmp_obj->lsdo_alloc_size_in_sectors * 512;
+ json_object_object_add(jobj_obj, "AllocatedSizeBytes",
+ json_object_new_int64(alloc_dir_size));
+
+ json_object_object_add(jobj_obj, "Depth",
+ json_object_new_int64(tmp_obj->lsdo_depth));
+
+ json_object_object_add(jobj_obj, "FilesCount",
+ json_object_new_int64(tmp_obj->lsdo_files_count));
+
+ json_object_object_add(jobj_obj, "DirsCount",
+ json_object_new_int64(tmp_obj->lsdo_dirs_count));
+
+ json_object_object_add(jobj_obj, "UserID",
+ json_object_new_int64(tmp_obj->lsdo_uid));
+
+ json_object_object_add(jobj_obj, "FID",
+ json_object_new_string(fid_str));
+
+ json_object_object_add(jobj_obj, "DirectoryName",
+ json_object_new_string(tmp_obj->lsdo_name));
+
+ json_object_object_add(jobj_obj, "Path",
+ json_object_new_string(path));
+
+ json_object_array_add(jobj_objects, jobj_obj);
+ }
+
+ json_object_object_add(jobj_dirs_rating, "SourceDirectory",
+ json_object_new_string(dir_stats->lsdg_start_path));
+
+ json_object_object_add(jobj_dirs_rating, "MaxDepth",
+ json_object_new_int64(dir_stats->lsdg_max_depth));
+
+ json_object_object_add(jobj_dirs_rating, "TotalSizeBytes",
+ json_object_new_int64(total_size));
+
+ json_object_object_add(jobj_dirs_rating, "TotalAllocatedSizeBytes",
+ json_object_new_int64(total_alloc_size));
+
+ json_object_object_add(jobj_dirs_rating, "RatingMinSizeBytes",
+ json_object_new_int64(heap->lsdr_min_size));
+
+ json_object_object_add(jobj_dirs_rating, "RatingMaxSizeBytes",
+ json_object_new_int64(heap->lsdr_max_size));
+
+ json_object_object_add(jobj_dirs_rating, "Rating", jobj_objects);
+ json_object_object_add(jobj_dirs_rating, "MainTree", jobj_tree);
+
+ return jobj_dirs_rating;
+}
+
/* ls3_stats_dir_incr_counters - Increases directory size */
static void ls3_stats_dir_incr_counters(struct ls3_object_attrs *loa_all,
struct ls3_stats_dir_obj *dir_ptr)
* function we get the value from inode->i_blocks which is equal
* to the number of blocks with a size of 512B
*/
- dir_ptr->lsdo_alloc_size_in_512blocks += loa_all->loa_blocks;
+ dir_ptr->lsdo_alloc_size_in_sectors += loa_all->loa_blocks;
/* It is likely that loa_all->loa_size is also aligned to a
* block of 512 bytes somewhere in EXT2_I_SIZE(inode)...
* For this reason, we do not align the size in future.
dir_ptr->lsdo_fid.f_oid = loa_all->loa_file_fid.f_oid;
dir_ptr->lsdo_fid.f_seq = loa_all->loa_file_fid.f_seq;
dir_ptr->lsdo_fid.f_ver = loa_all->loa_file_fid.f_ver;
- /* Also update UID */
+ /* Also update UID/GID/PID/Time.
+ * This is necessary so that when gluing reports together,
+ * it is possible to create new statistics tables for
+ * the user, group, projectID, ctime, atime, mtime, crtime.
+ */
dir_ptr->lsdo_uid = loa_all->loa_uid;
+ dir_ptr->lsdo_gid = loa_all->loa_gid;
+ dir_ptr->lsdo_projid = loa_all->loa_projid;
+ dir_ptr->lsdo_atime = loa_all->loa_atime;
+ dir_ptr->lsdo_crtime = loa_all->loa_crtime;
+ dir_ptr->lsdo_mtime = loa_all->loa_mtime;
+ dir_ptr->lsdo_ctime = loa_all->loa_ctime;
}
/* ls3_stats_allocate_new_dir allocates memory for a new
json_object_object_add(jobj_main, "ProcessingTimeSecs",
json_object_new_double(e_time));
- json_object_object_add(jobj_main, "DevicePath",
- json_object_new_string(reports_with_stats->device_path));
+ if (reports_with_stats->device_path)
+ json_object_object_add(jobj_main, "DevicePath",
+ json_object_new_string(reports_with_stats->device_path));
- json_object_object_add(jobj_main, "DeviceName",
- json_object_new_string(reports_with_stats->device_name));
+ if (reports_with_stats->device_name)
+ json_object_object_add(jobj_main, "DeviceName",
+ json_object_new_string(reports_with_stats->device_name));
json_object_object_add(jobj_main, "DeviceType",
json_object_new_string(reports_with_stats->device_is_mdt ?
jobj_general = json_object_new_object();
jobj_ranges = json_object_new_array();
+ json_object_object_add(jobj_general, "TableId",
+ json_object_new_int(i));
+
json_object_object_add(jobj_general, "Title",
json_object_new_string(text_tmpl->som_table_title));
ls3_stats_get_range_str(range_ptr, range_t,
sizeof(range_t), i);
- json_object_object_add(jobj_range, "RangeInStr",
- json_object_new_string(range_t));
+ json_object_object_add(jobj_range, "RangePosition",
+ json_object_new_int(j));
json_object_object_add(jobj_range, "RangeStart",
json_object_new_double(range_ptr->range_start));
json_object_object_add(jobj_range, "RangeEnd",
json_object_new_double(range_ptr->range_end));
+ /* For UID/GID/Stripe/Mirror */
json_object_object_add(jobj_range, "RangeID",
json_object_new_int64(range_ptr->rrt_id));
json_object_object_add(jobj_range, "PercentageInRange",
json_object_new_double(range_ptr->percentage));
- json_object_object_add(jobj_range, "CumulativePercentageInRange",
- json_object_new_double(range_ptr->cumulative_percentage));
+ json_object_object_add(jobj_range,
+ "CumulativePercentageInRange",
+ json_object_new_double(
+ range_ptr->cumulative_percentage));
json_object_object_add(jobj_range, "TotalInRange",
json_object_new_int64(range_ptr->total_in_range));
- json_object_object_add(jobj_general, "TotalInRangeType",
+ json_object_object_add(jobj_range, "TotalInRangeType",
json_object_new_string((second_value_ts[0] != '\0') ?
second_value_ts : value_ts));
json_object_object_add(jobj_range, "PercentTotalInRange",
- json_object_new_double(range_ptr->percent_in_range));
+ json_object_new_double(
+ range_ptr->percent_in_range));
- json_object_object_add(jobj_range, "PercentCumulativeTotalInRange",
- json_object_new_double(range_ptr->percent_cumulative_in_range));
+ json_object_object_add(jobj_range,
+ "PercentCumulativeTotalInRange",
+ json_object_new_double(
+ range_ptr->percent_cumulative_in_range));
json_object_object_add(jobj_range, "MinValueInRange",
json_object_new_double(range_ptr->rrt_min));
json_object_object_add(jobj_range, "MaxValueInRange",
json_object_new_double(range_ptr->rrt_max));
- json_object_object_add(jobj_general, "MinMaxType",
- json_object_new_string(value_ts));
+ json_object_object_add(jobj_range, "MinMaxType",
+ json_object_new_string(value_ts));
json_object_array_add(jobj_ranges, jobj_range);
}
json_object_object_add(jobj_table, "Title",
json_object_new_string(title_text));
+ json_object_object_add(jobj_table, "UsersReportsTableId",
+ json_object_new_int(j));
+
for (k = 0; k < report_ptr->count_ranges; k++) {
struct json_object *jobj_range =
json_object_new_object();
range_ptr->total_in_range));
json_object_object_add(jobj_range,
"LastTimeAccess",
+ json_object_new_int64(
+ range_ptr->last_time_access));
+ json_object_object_add(jobj_range,
+ "LastTimeAccessStr",
json_object_new_string(buffer));
json_object_array_add(jobj_ranges, jobj_range);
}
json_object_object_add(jobj_main, "UserTimeReports", jobj_users_reports);
+
+ /* Try add dirs stats (TOP N rating table + tree) */
+ if (reports_with_stats->client_mount_path) {
+ struct json_object *jobj_dirs_rating;
+
+ jobj_dirs_rating = ls3_stats_fprintf_dirs_json();
+ if (jobj_dirs_rating)
+ json_object_object_add(jobj_main,
+ "DirectoriesStats",
+ jobj_dirs_rating);
+ }
+
json_str = json_object_to_json_string_ext(jobj_main,
JSON_C_TO_STRING_PRETTY);
}
/* Size statistics for directories */
- ls3_stats_dir_distributor(loa_all);
+ if (reports_with_stats->client_mount_path)
+ ls3_stats_dir_distributor(loa_all);
/* Reports only for regular file's */
if (!(loa_all->loa_mode & S_IFREG))