From patchwork Tue Feb 20 09:59:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Prutyanov X-Patchwork-Id: 875454 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="EvzOIy1q"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zlx1r6nmGz9s0r for ; Tue, 20 Feb 2018 21:00:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751552AbeBTKAO (ORCPT ); Tue, 20 Feb 2018 05:00:14 -0500 Received: from mail-he1eur01on0116.outbound.protection.outlook.com ([104.47.0.116]:10020 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751590AbeBTKAL (ORCPT ); Tue, 20 Feb 2018 05:00:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=Iqdnsb8WccVSkMQgItnMGAqOIL9FD6N0Lis/4Pzj7Tk=; b=EvzOIy1qUGqmwSTLphWj26Q5eVyzN6IVQ9zs9ld+jnJzG5HGGG8WYcQ2VeFqq+DaCxwO1MEaGk+UL1Yw/cBT1861DWaoJM5uTHkY871RC8/RxBQ9fwJUMwwkPYJFsvpM3ZVBsetQMaojERrtlujLOxfGvCzFe6yYb9Oz2cEvS4Q= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=viktor.prutyanov@virtuozzo.com; Received: from vprutyanov-pc.sw.ru (195.214.232.6) by AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.506.18; Tue, 20 Feb 2018 10:00:07 +0000 From: Viktor Prutyanov To: linux-ext4@vger.kernel.org Cc: Theodore Ts'o , Dmitry Monakhov , Viktor Prutyanov Subject: [PATCH v3 1/5] libsupport: add JSON output helpers Date: Tue, 20 Feb 2018 12:59:46 +0300 Message-Id: <20180220095950.23462-2-viktor.prutyanov@virtuozzo.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> References: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR0902CA0058.eurprd09.prod.outlook.com (2603:10a6:7:15::47) To AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 22ea2891-da61-4aba-4c87-08d57848b937 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:AM4PR08MB2849; X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 3:M2b7etnRGVLjBrikf4BRJ3xv19YSjFSCvQrMjHLx0Qt1DeSHNjEoWLiFNFl/WjbgdpVKb7WuFvvEYMxkDLwg6S0QqXrF883LhcMnL2neVianYi2clTkruAwEA4nU0GfO4itZ3E4oe0FUXcOvzht/Azsdiyblq1URVDSX2GViuzw7CNDbxVNFBgwmi2x1DQpZ/AsKJMRVfTFgquVpwr7oRowy5lvVGJzzm0LzpGHdhrsSY05UlZb9DduR/Yk7AiDH; 25:tIAbWo2DnZDVbDfNsqLhCMdQrFH/FDaZfGeKzP0venVYVps7TDzjVVcMNQPrMIkCVYT4wohmhlIJm9yB8ae24r+oH7wR4LxI1PnHv6DSxbrTZpeutmaSxQqaeSaMqkDBafWjxZ3lgruWiB3SaCG4huNDEMISTpy31gnbuzOYGzR6XSbHp8cmqH/E6mGB5ri1W16hii/q8vPUPREhRRBsXByjCwKnc/gzTvVxaZrD6dwJTErR5gX4Z8X8LufVkKMM3WBctG/gXn3lERhySx+IOjVIRuWRzTEf3jZOrQ2P3BPsKog3JgDdwh/UZ4g/yAcQx2faL1FdBfbgZ9Wkav+qQQ==; 31:fXmpV2YYtyeS2nSAElzf76nld7+6m4CfblnV2kPqM/1iVhGPINjDn03yJNUiKDOBu3pXy7tmqVXmtj3UQc1iRY8vq2HGvUUT7F7vN8BMiubaya9GndIQTrNjrJ/bK83yZdfB7nhstmUlIKxV1+xg4yi67wXhuDhiOeDV4o037MsXZDk5CcfGxTEseFl2122WID7r1oCT5fR8z8RqvACxIq8r9pvn2hZPODTZXSqvNlA= X-MS-TrafficTypeDiagnostic: AM4PR08MB2849: X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:aU5D8ok3OV+V3kCJpepgQEpKA/5mGPYgR2mgYQLcvsSSQ36RewJCIK7OKW2pIyRvrGUiYMzpe/NGVWdu6IJ/NYQ48Ww9VQ3y3xQdcpIzxIidd/hO6DWdxQIAiw+/4xOTv2IhJY1azyG003VMpC4I1m/tsSHPN/0x5tqV8yi6uXV3JDxkqJ73AZiD7ZOnPhUh2cgmCVHxDwCeVWRWVgxIq+YKAxa1O+/Hbvo1+s7RRw+A8rsrs6LsebZ+v7lDYyL5GaUToSPmr6EY988uttzdkJFpjnM11QMcjF8f696T1u5A5omeAlXUdS4CIYfOjvzgiiKAMsIBQeih6Hr2JKzEajCa84spg7xHpl36liZ7Sms4vEMT6AQEmF0OqFg/eim6CP0X8b18+o65NesDLPmFcZKvjfpgdgx6W5JKFhSbY4TNz0K0fYOZJ0aiNHivMx4rDCd+kmdCQr3Xlsqi5xIUJT+qAVuay1la114bA8PnudwcauioGwCpUE3QOLPLbdG9; 4:Mq9AF+HRNxuiQ9WscMH7G0pgMJdPYco+1q5Vt0gw7zEjEMP14i9IA1IDNlQU1T23UZxTQZlz8QD2Z7+Byu8dJnKR/F+TYcmwAXBX06Qik4vrwn/VEgaGA/hd10bmIoBoJ5Y/TpS1Jc0bUnrCar1F+2vRZ0V1PIZaKOUkIS0iQi17lOI+ojBj+cnHf1JEBVyG+8fNfHGGt70m2Wikd56DqfpJgLlXZFJKee240E5FXEYRMFZo4QEJSpYNSu1BBTjXPniIDvjEg2EXaXrEb383UA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(3231101)(944501161)(93006095)(93001095)(10201501046)(3002001)(6041288)(20161123560045)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM4PR08MB2849; BCL:0; PCL:0; RULEID:; SRVR:AM4PR08MB2849; X-Forefront-PRVS: 05891FB07F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(39850400004)(366004)(396003)(39380400002)(346002)(376002)(199004)(189003)(52116002)(16586007)(478600001)(54906003)(59450400001)(5660300001)(1076002)(68736007)(6666003)(51416003)(107886003)(69596002)(50466002)(86362001)(48376002)(8676002)(16526019)(186003)(76176011)(6116002)(55236004)(2950100002)(6916009)(26005)(3846002)(316002)(2906002)(386003)(81156014)(6506007)(81166006)(7736002)(97736004)(53416004)(8936002)(6486002)(305945005)(36756003)(50226002)(53936002)(66066001)(6512007)(47776003)(25786009)(2351001)(105586002)(4326008)(106356001)(2361001)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM4PR08MB2849; H:vprutyanov-pc.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 23:Ejsfs+gePPdjnSNuKlhldFP+YVlcJKEc7ime2odescG9LceY7YSM/bCHmtB0ZLgW0F+sxAqTPDIxYB3PU7IPBLHdNsNG8Yqw6ACiQnVLeodvK4uiXEPev0CBJHAoO0DJ8VUEhgjsbKnWNqT0In7gjO2TCWCC/EFSqVlYqgkdROs2telQLO6GMtu0UDZ2lz4S4USGu4B1LgHJEw7dXwrAXdjknyLI+HTC5D2dkO9OEt64PWRbTX+Qa56l0I26pZ6yGdicLvwmNvUFlkk88sS+dSdGsKdrVfPJf31A8F/h1LE1TU0Pu9Vv/vJ20TQjl7Q1gqS6J9LaRRlyc5YKv+2dcLlc4b01yYiueoNF21hKy6Wbmwq5qsSZDHMv/4WT4+dnBKdoycxxowSYOSNM/WMqSw7c8sCachb8zeBbaBUzFZUCgZrSmUqFrOJ6XZgNgtr4R0DYxz8pFcv/UrUmWMGXDxZKe4wK6ZZW30o3Rem4lHKYsrVXon3gu64WcUMUZ0A4U1gMl7pIqrZiJPN2/S4isXeSdL+Yk2DjP/IRAsNxNbiH72+05C/xwHlZMNH115Qpdt+sn112bJLeemQhIQY5WIsAqyWmwnxrReRIGggYHcwCdG4WsoJdVlZLiV07Br0aTq/u78/jat8GZ+6cppQcF0KOEfIzgOP2DhHMYrkzKMCZavY7+CdkTSKT2wGIZd5ysHV7KjUDE6JrA8TsRRo7Y8AlIA5TOKpEnVv3fMmEhchu+KQueX53/fxerMBw83A6NXwUFNLeuMPonEtfZ+Rthpgebiot/3xXfzuAev/fdFuQUbrcIhERN+j7MTyAGUXY3ipFeGz/mbra22xcBvx1TtTiMYlJDLY5NxD9gFH7/PRpKJX4ib/L0IvmpqHS6FVVFFVt75LkzyZDytkylM2XfAeI/6O0vT5e9w6pAxrdxMdyExAnge/Fnlfxg7WjFZFL4yQkZuB4WCQhOHxaW4KgnjO+ip084NReXSWYXaA7FutBlZrY2fqcL+rw03A+JUVOFglHnejpxO1Be+HSRXIPHZB3uA8h9Oqo7kQ/rpfx1EmNxhjeNfUCrLaDyv0PhJCYCZAiAyP7dUf7Gzn5CzozYgmVFO6/7oUzDQkI1LFNIqcQvogucsMoZny+RjwE0+s+dqktCrI4KIkjVmaG5eLAvw983OW25qtNkUcDyLCSzOPAtHQ/DpioIdlLZeozAfhNKPrGyAKEnrjLY1izqMp9XDfNLX/nQp+mk2GUxLp+vFUnqodXvP4KfiAGcndPkQ/AhTLYk/C9IeasLLvZ4iMgl15ybNRp2YGK9+FAQPnDWXA= X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 6:xvQLpKKo9gl7B5VGCF7bLFTXJeWlkRE09r/x8NGePIn1BTQOYDwwmZUrxUrjFiMwQKyd54ceNxkTuB1HvEWj1Pt9I+XkfVgIUimPhX4XudFaHdUq01GFWGG82VyyF5+ntmRDRAiQHjt990St7SYyE+QGZYnCFttVyOu722v3nq1v8bBbubXrNYoUKeXwXxSvq0Xexf5aV0qU42LB1CuH71T4Aa1XSZlLRJsf/eDcAzuskB5FKlchYc08ezhbGFRjp+fGZw7Yookly5CTnYUVspsHhH5CezKsjfrpwZeLmJUJjy2nvpOZX2c33bsAUYhj3l+/QMVqV0orRwQN+wYjQJpPaAAlOksgIO5CGsrYgxA=; 5:t5vlTiFEuVofVDzprvkiLI0Z+RUfwKetDng4YZKFWlX0e9OLWy5ZVEAFPTIBYq3lN7ASokIyP61pRL3k74TzeIcMyQUQB4oeBMRfF4j1VOh9HkVJ0qCknu3OIF4e7lFF7i6m98nOCVTH1MEWik9DzYJOna/dwBR7iZVeBQ6kRvU=; 24:KsyXFBoB+24CMg1SLJkD13u114y1XNwclfmmilNdmkdgZoKzTnc6eyem8SCVkhJshqLXQxaaJmzVzA9qLmjWZMfq6+6oJ+5U3HBz/qIDtXs=; 7:tUls1UaAdTBg9hp2i1Wz6tU8l3gt1GvKFJzjePZZJN3AUs4Aa4dYf4f7RiAA+0WDhOcKQT8S1jTAa/gkQ9cY4APxLduG2MNnhwTbgVuRUqyUkyKuGLxWlJj0A0TMgLCMn2El2eDL0/W+AFaGlJDkK+LbEKjQsNVu3iqsv3A2k0v2cuOfEctfz5jzwfFfORdk/QSdddHS5LNTHbMbD4ekU029s3oOduPIiGVSc0ZjQseEaFZfUHblVU1dNVPGavPy SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:9apryR8P+OcvedUWmpm09hYIKLOdyuFiSowoqXvLqQ/pTw2QIEQgn4sa4pFg5KPJtbsi9/P+NgW3cYazG+dur9cbHkmbhVX3lqvictDL6DEe5HEOx4+s+/Ff07clUWQcO4z2pnG73qm8xfon77GCvo6arRHLw2KyccFop/mZh0A= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Feb 2018 10:00:07.9586 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 22ea2891-da61-4aba-4c87-08d57848b937 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR08MB2849 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds JSON objects and lists and methods to print them Signed-off-by: Viktor Prutyanov --- lib/support/Makefile.in | 7 +- lib/support/json-out.c | 326 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/support/json-out.h | 69 ++++++++++ misc/dumpe2fs.c | 17 ++- 4 files changed, 416 insertions(+), 3 deletions(-) create mode 100644 lib/support/json-out.c create mode 100644 lib/support/json-out.h diff --git a/lib/support/Makefile.in b/lib/support/Makefile.in index 40206b74..42fa3324 100644 --- a/lib/support/Makefile.in +++ b/lib/support/Makefile.in @@ -22,7 +22,8 @@ OBJS= cstring.o \ quotaio.o \ quotaio_v2.o \ quotaio_tree.o \ - dict.o + dict.o \ + json-out.o SRCS= $(srcdir)/argv_parse.c \ $(srcdir)/cstring.c \ @@ -35,7 +36,8 @@ SRCS= $(srcdir)/argv_parse.c \ $(srcdir)/quotaio.c \ $(srcdir)/quotaio_tree.c \ $(srcdir)/quotaio_v2.c \ - $(srcdir)/dict.c + $(srcdir)/dict.c \ + $(srcdir)/json-out.c LIBRARY= libsupport LIBDIR= support @@ -165,3 +167,4 @@ quotaio_v2.o: $(srcdir)/quotaio_v2.c $(top_builddir)/lib/config.h \ $(srcdir)/dqblk_v2.h $(srcdir)/quotaio_tree.h dict.o: $(srcdir)/dict.c $(top_builddir)/lib/config.h \ $(top_builddir)/lib/dirpaths.h $(srcdir)/dict.h +json-out.o: $(srcdir)/json-out.c $(srcdir)/json-out.h diff --git a/lib/support/json-out.c b/lib/support/json-out.c new file mode 100644 index 00000000..8c822f35 --- /dev/null +++ b/lib/support/json-out.c @@ -0,0 +1,326 @@ +/* + * json-out.c -- JSON output + * + * Copyright (c) 2018 Virtuozzo International GmbH + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#include +#include + +#include "json-out.h" + +static void *xmalloc(size_t size) +{ + void *p = malloc(size); + + if (!p) + exit(1); + + return p; +} + +static void *xstrdup(const char *str) +{ + size_t size = strlen(str) + 1; + char *p = xmalloc(size); + + return strcpy(p, str); +} + +struct json_list *json_list_create(enum json_val_type type) +{ + struct json_list *list = xmalloc(sizeof(struct json_list)); + + list->node = NULL; + list->type = type; + + return list; +} + +struct json_list *json_list_create_in_obj(struct json_obj *parent_obj, char *key, enum json_val_type type) +{ + struct json_list *list = json_list_create(type); + + json_obj_add_list(parent_obj, key, list); + + return list; +} + +void json_list_delete(struct json_list *list) +{ + struct json_list_node *node = list->node, *next; + + while (node) { + switch (list->type) { + case JSON_VAL_STRING: + free(node->val.str); + break; + case JSON_VAL_LIST: + json_list_delete(node->val.list); + break; + case JSON_VAL_OBJECT: + json_obj_delete(node->val.obj); + break; + default: + break; + } + next = node->next; + free(node); + node = next; + } + free(list); +} + +struct json_obj *json_obj_create(void) +{ + struct json_obj *obj = xmalloc(sizeof(struct json_obj)); + + obj->pair = NULL; + + return obj; +} + +struct json_obj *json_obj_create_in_obj(struct json_obj *parent_obj, char *key) +{ + struct json_obj *obj = json_obj_create(); + + json_obj_add_obj(parent_obj, key, obj); + + return obj; +} + +static void json_pair_delete(struct json_pair *pair) +{ + switch (pair->type) + { + case JSON_VAL_STRING: + free(pair->val.str); + break; + case JSON_VAL_LIST: + json_list_delete(pair->val.list); + break; + case JSON_VAL_OBJECT: + json_obj_delete(pair->val.obj); + break; + default: + break; + } + free(pair->key); + free(pair); +} + +void json_obj_delete(struct json_obj *obj) +{ + struct json_pair *pair = obj->pair, *next; + + while (pair) { + next = pair->next; + json_pair_delete(pair); + pair = next; + } + free(obj); +} + +void json_obj_delete_pair(struct json_obj *obj, char *key) +{ + struct json_pair *pair = obj->pair, *next, *prev = NULL; + + while (pair) { + next = pair->next; + if (!strcmp(pair->key, key)) { + json_pair_delete(pair); + if (prev) + prev->next = next; + else + obj->pair = next; + break; + } + prev = pair; + pair = next; + } +} + +static struct json_list_node *json_list_add_node(struct json_list *list) +{ + struct json_list_node *new_node = xmalloc(sizeof(struct json_list_node)); + + new_node->next = NULL; + + if (list->node) { + struct json_list_node *node; + + for (node = list->node; node && node->next; node = node->next); + node->next = new_node; + } else + list->node = new_node; + + return new_node; +} + +void json_list_add_str(struct json_list *list, const char *str) +{ + struct json_list_node *new_node = json_list_add_node(list); + + new_node->val.str = xstrdup(str); +} + +void json_list_add_obj(struct json_list *list, struct json_obj *obj) +{ + struct json_list_node *new_node = json_list_add_node(list); + + new_node->val.obj = obj; +} + +static struct json_pair *json_obj_add_pair(struct json_obj *obj, const char *key, enum json_val_type type) +{ + struct json_pair *new_pair = xmalloc(sizeof(struct json_pair)); + new_pair->key = xstrdup(key); + new_pair->next = NULL; + new_pair->type = type; + + if (obj->pair) { + struct json_pair *pair; + + for (pair = obj->pair; pair && pair->next; pair = pair->next); + pair->next = new_pair; + } else + obj->pair = new_pair; + + return new_pair; +} + +void json_obj_add_str(struct json_obj *obj, const char *key, const char *str) +{ + struct json_pair *new_pair = json_obj_add_pair(obj, key, JSON_VAL_STRING); + + new_pair->val.str = xstrdup(str); +} + +void json_obj_add_fmt_buf_str(struct json_obj *obj, const char *key, char *buf, size_t size, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, size, fmt, ap); + va_end(ap); + + json_obj_add_str(obj, key, buf); +} + +void json_obj_add_fmt_str(struct json_obj *obj, const char *key, size_t size, const char *fmt, ...) +{ + va_list ap; + char *buf = malloc(size); + + va_start(ap, fmt); + vsnprintf(buf, size, fmt, ap); + va_end(ap); + + json_obj_add_str(obj, key, buf); + free(buf); +} + +void json_obj_add_list(struct json_obj *obj, const char *key, struct json_list *list) +{ + struct json_pair *new_pair = json_obj_add_pair(obj, key, JSON_VAL_LIST); + + new_pair->val.list = list; +} + +void json_obj_add_obj(struct json_obj *obj, const char *key, struct json_obj *new_obj) +{ + struct json_pair *new_pair = json_obj_add_pair(obj, key, JSON_VAL_OBJECT); + + new_pair->val.obj = new_obj; +} + +static void json_pair_print_json(struct json_pair *pair, int ind_lvl); +static void json_list_node_print_json(struct json_list_node *node, enum json_val_type type, int ind_lvl); + +static void +print_ind(int ind_lvl) +{ + int i; + + putchar('\n'); + for (i = 0; i < ind_lvl; i++) + fputs(" ", stdout); +} + +void json_obj_print_json(struct json_obj *obj, int ind_lvl) +{ + struct json_pair *pair; + + printf("{"); + for (pair = obj->pair; pair; pair = pair->next) { + json_pair_print_json(pair, ind_lvl+1); + if (pair->next) + printf(", "); + } + if (obj->pair) /* Do not indent if object was empty */ + print_ind(ind_lvl); + printf("}"); +} + +void json_list_print_json(struct json_list *list, int ind_lvl) +{ + struct json_list_node *node; + + printf("["); + for (node = list->node; node; node = node->next) { + json_list_node_print_json(node, list->type, ind_lvl+1); + if (node->next) + printf(", "); + } + if (list->node) /* Do not indent if list was empty */ + print_ind(ind_lvl); + printf("]"); +} + +static void +json_list_node_print_json(struct json_list_node *node, enum json_val_type type, int ind_lvl) +{ + print_ind(ind_lvl); + switch (type) { + case JSON_VAL_STRING: + printf("\"%s\"", node->val.str); + break; + case JSON_VAL_LIST: + json_list_print_json(node->val.list, ind_lvl); + break; + case JSON_VAL_OBJECT: + json_obj_print_json(node->val.obj, ind_lvl); + break; + case JSON_VAL_FLAG: + printf("%s", node->val.flag ? "true" : "false"); + break; + default: + break; + } +} + +static void json_pair_print_json(struct json_pair *pair, int ind_lvl) +{ + print_ind(ind_lvl); + printf("\"%s\": ", pair->key); + switch (pair->type) { + case JSON_VAL_STRING: + printf("\"%s\"", pair->val.str); + break; + case JSON_VAL_LIST: + json_list_print_json(pair->val.list, ind_lvl); + break; + case JSON_VAL_OBJECT: + json_obj_print_json(pair->val.obj, ind_lvl); + break; + default: + break; + } +} diff --git a/lib/support/json-out.h b/lib/support/json-out.h new file mode 100644 index 00000000..0132bd2c --- /dev/null +++ b/lib/support/json-out.h @@ -0,0 +1,69 @@ +/* + * json-out.h -- JSON output + * + * Copyright (c) 2018 Virtuozzo International GmbH + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#ifndef H_JSON_OUT +#define H_JSON_OUT + +enum json_val_type { + JSON_VAL_STRING, + JSON_VAL_OBJECT, + JSON_VAL_LIST, + JSON_VAL_FLAG +}; + +struct json_obj { + struct json_pair *pair; +}; + +union json_val { + char *str; + struct json_obj *obj; + struct json_list *list; + char flag; +}; + +struct json_pair { + char *key; + enum json_val_type type; + union json_val val; + struct json_pair *next; +}; + +struct json_list { + enum json_val_type type; + struct json_list_node *node; +}; + +struct json_list_node { + union json_val val; + struct json_list_node *next; +}; + +struct json_obj *json_obj_create(void); +struct json_obj *json_obj_create_in_obj(struct json_obj *parent_obj, char *key); +void json_obj_add_str(struct json_obj *obj, const char *key, const char *str); +void json_obj_add_list(struct json_obj *obj, const char *key, struct json_list *list); +void json_obj_add_obj(struct json_obj *obj, const char *key, struct json_obj *new_obj); +void json_obj_add_flag(struct json_obj *obj, const char *key, char flag); +void json_obj_add_fmt_str(struct json_obj *obj, const char *key, size_t size, const char *fmt, ...); +void json_obj_add_fmt_buf_str(struct json_obj *obj, const char *key, char *buf, size_t size, const char *fmt, ...); +void json_obj_print_json(struct json_obj *obj, int ind_lvl); +void json_obj_delete_pair(struct json_obj *obj, char *key); +void json_obj_delete(struct json_obj *obj); + +struct json_list *json_list_create(enum json_val_type type); +struct json_list *json_list_create_in_obj(struct json_obj *parent_obj, char *key, enum json_val_type type); +void json_list_add_str(struct json_list *list, const char *str); +void json_list_add_obj(struct json_list *list, struct json_obj *obj); +void json_list_print_json(struct json_list *list, int ind_lvl); +void json_list_delete(struct json_list *list); + +#endif diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 395ea9ee..ca9953a1 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -607,7 +607,12 @@ try_open_again: goto just_descriptors; list_super (fs->super); if (ext2fs_has_feature_journal_dev(fs->super)) { - print_journal_information(fs); + print_journal_information(fs, dump_obj); + if (json) { + json_obj_print_json(dump_obj, 0); + putchar('\n'); + json_obj_delete(dump_obj); + } ext2fs_close_free(&fs); exit(0); } @@ -616,6 +621,11 @@ try_open_again: print_inline_journal_information(fs); list_bad_blocks(fs, 0); if (header_only) { + if (json) { + json_obj_print_json(dump_obj, 0); + putchar('\n'); + json_obj_delete(dump_obj); + } ext2fs_close_free(&fs); exit (0); } @@ -636,6 +646,11 @@ just_descriptors: error_message(retval)); } } + if (json) { + json_obj_print_json(dump_obj, 0); + putchar('\n'); + json_obj_delete(dump_obj); + } ext2fs_close_free(&fs); remove_error_table(&et_ext2_error_table); exit (0); From patchwork Tue Feb 20 09:59:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Prutyanov X-Patchwork-Id: 875455 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="djLsroo6"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zlx1v45x2z9s0b for ; Tue, 20 Feb 2018 21:00:19 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751586AbeBTKAR (ORCPT ); Tue, 20 Feb 2018 05:00:17 -0500 Received: from mail-he1eur01on0116.outbound.protection.outlook.com ([104.47.0.116]:10020 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751510AbeBTKAP (ORCPT ); Tue, 20 Feb 2018 05:00:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=LAMFBhFraDzi6oY9/BBLFEWPrfu48VR9E3AH6k8ganU=; b=djLsroo6ZU9O4VPCZlsj38fk72vGwTPo2MKyOmY7Lfqpd8+gVAtrEPFV4buZyWcb0bLApRG482fpOJIkCJfK2TLVFnVTMU2oncyiCn9m1+Z+LWz2QVfl5vc90CY5JwRjgTZEUF/K/ijdZnmTj1wM1XiL0otf6zIkYGpOUh4w5FI= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=viktor.prutyanov@virtuozzo.com; Received: from vprutyanov-pc.sw.ru (195.214.232.6) by AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.506.18; Tue, 20 Feb 2018 10:00:08 +0000 From: Viktor Prutyanov To: linux-ext4@vger.kernel.org Cc: Theodore Ts'o , Dmitry Monakhov , Viktor Prutyanov Subject: [PATCH v3 2/5] dumpe2fs: add JSON output of block groups Date: Tue, 20 Feb 2018 12:59:47 +0300 Message-Id: <20180220095950.23462-3-viktor.prutyanov@virtuozzo.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> References: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR0902CA0058.eurprd09.prod.outlook.com (2603:10a6:7:15::47) To AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 033a38c6-a692-4972-3453-08d57848b9a0 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:AM4PR08MB2849; X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 3:IB6nhG0WQQEOMaU0MGhmb3vFQyFbekRpu98sGkTOnTskmtS42RdPQj8/ljfPqZZfBAAqrZcpjBIFQoXcJiMMFdrJW1g6b5h8EdawEQ7GE/Uolt8AgYuXyxMYxDz4LjS5l7KWzrp60xNdTtOjCSxZy9UJvIICNubCyBIEaV33UIvUPkCMhUppiur19NozGUNVcR3IirmyzIfdgyiCZm0TKyQDQ2rwG22HAfo5bZQj5W9jgnIKsC1qqXlm5aoI45nF; 25:uOhhsQ+aZqZ897g4aK1V0sK53nazeomWVjoBei4cK/hcr0h01EYapW8bOtyxME9QtmVa2/swURoMt+t7XmO4G5vUsDIfow25qnrEcTFhK3SR7GKueoZUifJjHQsYWjmI7tQd29vXA1w3lmMDAcRMoB1IB5DMpin40LiUu35BJAItfPAd9DyDgdr8R35SUITTFUtL4nyOIDYJ42SPbf/LowZ1xHwPFNhdU09s4VmX6ZnR6qc1Ww1BmKi4XKYDZQglZgDgAnoHqjwZQxWeqIxoBqgyCoEO7SQIkLOharGkFMwFrVkrKGo/bakmkQ4QJy9eJCAD/9gKElV/upDjAF3X+w==; 31:LX6jfXvVy1CCt+oTMka1Of9gGFCOr3hhKlOgL7cmMgMwf45RCvKNoYxBu6quprUpMgIGcOyA8vY/TgCDFVHs8PfB2I9/hkr1/GTvkTP/0nGTJz5UqSsog7lmzTV2V03irwvHGeM0LkarGmxdKmV0mzA2RrRivx9b/JDZxt4UWWc6ZDMMCAZ5G1+V+38KY7RkZgzixKMazjlcbzkdlIeNxuGrWgPp4VRe0g7DnzOglZI= X-MS-TrafficTypeDiagnostic: AM4PR08MB2849: X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:U/kSQ8GR0zhkKTdkyAWpIOHTpRX7lwIstlCwKLg46K/FP8ttsot4TAGUwQ8WqlnGSGdoGeJxIJ4W/MMNmfLU6airMKZ/s19qRu1JwP6PfEssgJ8tzngi51cwLCFWqc+jdSgfq5IFue89tNxJztEVDKIDY/ZbhRJMW0splWR0CSvorldX9tWdu9PDfcFxtBiDz7Oj6C9dmC7eQvXDSo+53vOBkRjAWJ0NF4mPpYSYNB28bcbNCe5RxCfm3Asg69tSrbZl1f7o18YsY0fKuJm9PZXfW0Vb+8mWhpQcqkl5LStEf4QnrM8GGC6NPTY64o8iP5rk93XjGMF1KwWm7vUchWHoMd5E7DMZ4th71+3uUCSNjPq60y4Aje5ot6WM/HfSCjvbGBtbDosc6kraqoSMqWc5IN9VD0SoGd7y+VJP0eYej7/Hdi3G7AkrJh6tya80HL0L2fuP5YrgSazFWda8z6uNnapPzEcdQMqOYOFs/DhtuKt7iLiOZGXhmicgKqDJ; 4:2kovMzrFb+zG1Ga4OMfXC/Ya0rH7bAi3QxMymUnEyZvy9xkAzPOw5aG6JYRdHbpX461lU6DXuzIbmqQTb3x0cZW4LQc4GrnIwjWUzNqGLHFONbdi2pJ1qv9Dpg/IajU5lpgCQJLohAdMJqbZQ4mgV5cPURDAvk5lXzavzdMeymwqTlVhzJp5fNIOyGIUbfVCpQj+ZbTMCGk+14T+oyfLjN+3/mPh9d2NLcHEJhGg087SaE9wzr0wCRK67mUj3sJYdF0GHD5bwaa6qJgwQGalkA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(3231101)(944501161)(93006095)(93001095)(10201501046)(3002001)(6041288)(20161123560045)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM4PR08MB2849; BCL:0; PCL:0; RULEID:; SRVR:AM4PR08MB2849; X-Forefront-PRVS: 05891FB07F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(39850400004)(366004)(396003)(39380400002)(346002)(376002)(199004)(189003)(52116002)(16586007)(478600001)(54906003)(59450400001)(5660300001)(1076002)(68736007)(6666003)(51416003)(107886003)(69596002)(50466002)(86362001)(48376002)(8676002)(16526019)(186003)(76176011)(6116002)(55236004)(2950100002)(6916009)(26005)(3846002)(316002)(2906002)(386003)(81156014)(6506007)(81166006)(7736002)(97736004)(53416004)(8936002)(6486002)(305945005)(36756003)(50226002)(53936002)(66066001)(6512007)(47776003)(25786009)(2351001)(105586002)(4326008)(106356001)(2361001)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM4PR08MB2849; H:vprutyanov-pc.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 23:gyguzLnCt9f/yJcbt0//xBLgshRHeRYGvpBy7GFa8k6WnqYUS90sV2nDWwyvB9U/yN9Sx0AuGbktEUtfLPbbaMl+mduN2ZzHQ81IF7CYulHbdIBZlcULd2pIUC8MAXYDWT/GyRsxHaUD6o73aCf5eswhQZUfb/dM2NLx7QdsPsGoL88F6IsK8Qr3XsqFVMyb9H4xAspNwO+AuJ+A2q02GUtDBJpkAqy4bG3A9q+aBuT5WSXOP7SU/hsKBxixr1cFNxV0x75yV9tumOpkq3ZffM62I9lGwOVVr5yG2nfJnUSx5bgA0Jo7bgvMs2+4ee++3AxSWuHBqVPokkWXkMuAJubWuAmzOPKjZHxs2vZZMka+MV8Iqsn5r3aGalBWrvEN2TUwi2CrlPATT8D1+UBoJ3FmScjHvLpVmbWEsiWTYNbmGLI63clKXQYuYxsTSVzUxKAZvJgrsp7/5R/wNZQ/wlUn1kv+rIdBjfwSswwj9Vt+cidkSJWFYiX4m27JK7yjxNys5rSmEH8JK/svHEDw48VB0IP5ucFoW6ieBdvqOGfdzSfStJaqG1zfMONVgldlfkPVvCxatw7PGVVGMCFXgqH1i+sf0vjpSGN6fHMyv6lb0TjM9zXCIKJw1nvp6OL66dOyT4lGL1lUbRwItEtmj5Q7leZzQYOODtBQUvBpibZk3VDANr31jkrx/3CDCJsfyTlRE5iKMDa2Kf1LKsKHpaycZDOcvftN9iqS0+mBrbZaAKB4XHHwdZt/aJg8cuRzU581ewaLkE5kXrJZgqY0Lx1TWsqk0PtXNgq9NVodydLeGjJjRvekey2o/RkFBRePm1wQGn8VLc+JQTFpR7PHwURMf2+wCVBjcnp8sjstCMNw4YfTHTQayaNqTxdBEx2d7F4IM6KMRQi/AM51/lMzFMhYf7WV/MHdl5rIdAQdL9f14UKMxLTIVr9GR4hjbH7f5CGj1Mg88JTZVRjgVPmtDZEuyVie5EU9ZXsE/s9hogGIWa0cuveRuHCGieubZ3NTmaFBUS9/TTG99R+d5rnfg4FwALYvs0Up8UMucT0GxaMcufJObAb3/BDWlEGsm3IYkN3tuFlcBuaFcr4Lwu1PfGR8j3JMBvHI/Wol7XF7ckLrpnfpZxQhtKjh7bIG0IY6be6MJw7g3sd1bh86lLqZM9aWS/B5noyf6D6p0hyPAKWzuOgG+W0H9ANywPAqwPq0DS5D9HZbYV4cucSdel7pkXhYWBPnOAXexVzvCemk0mpiPvCGDEeYoWJZEj8qtOB0G8VYd8VhKCzE4IrK9/qmhxQ+/yqWRAiWr5EU+KldZ8c= X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 6:ExqMC94gsK+BdeVnnL/OF7oWFt1PCSpKNqcdVWm00baqLU1gSfqv/RyC3SlNyHl24H2Baam3zRDcbaBSy4YBn6qrCXedCPErZa//gUiqul3QOWY08wEI7U8RqBV9BMD2qSvT/SQo5wEDck7sRfqHEMPn7spX/DFB8otsaQ6EbUkYS5sbom29RJrjpxeFwbWC4zlfcl6tcMlvOtReP4CdBvZmD0a/9LYXCsoV3ayW5yDgU/F/8o4O+RdRqNM0BNqZbZDGKPHVBOx0DNtrELAdVDKxPVI6SYq/ayG4hN5XwDl33hQ79gknfXjA4SDNKum6zqG73q9Fr2YTRIVz0xflA+pMwPdctBiJgL3PzAMaf1s=; 5:Ql4ORJRmsfxBvWywlIjpb9pUwBQgYuhiVjpS06F99B+ZSFl6yN/BSSPlZKNjO5PBbU7UZuolz2FAb+LBCEjfvo/FD06yXhVSskL6k4Bx9Y5IekvC0nKI5YREFRU4rLuFQUm/fRyo0amY5e22EtnNXdQOmKC2qzpZSH6CzZQKJm0=; 24:nIS60P5kgwp9PvEMys/DFrmDWqYlF5Sdn5CFISAo1RgkB7yakA3FXSB1DcviAuht5iChodFjqhmZySLvpicGEhQuGagRpCLM81wcXDtcvl0=; 7:lnfB9eM7rLA3hWYl6cpeRe4iw3BPzwknpju8eY1XNq2QJ7Oe1hVOqsgUzH3nDPmON1EY5HfdJua2SCC+SPJc67+UZUt1OeN8FWxoJXntCvQSAcn5KtenbI6gA9m4izXP5b7LnnbuU9lMdSTTwH+hroM7Jn2lwwwcPRvlEe47uI6ce/RH+sEQ5HUqjSx0Ev4FhDRuDiR8wkPMx0HPes+JcjnFsuLSG1YOETatfpobv7Hjia77HGbZMytE2h0KXISi SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:u8Tvn8+HplEM1YBt/ChO0TTCF8wgdXLmUU4O+hSlfMeRww4chRVSPYRmKpdEiRinJnOWSy/Zz6wHV0x/XAMDSa29lODnI+AsPQYKcHSYB1NqTBXYT8mli0cFXabyy61pgXdUjziQd59abm615mgAhj+ztWrPAlDHGKuMJaCpJ8c= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Feb 2018 10:00:08.6461 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 033a38c6-a692-4972-3453-08d57848b9a0 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR08MB2849 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds '-j' option for JSON output of block groups information Signed-off-by: Viktor Prutyanov --- misc/dumpe2fs.8.in | 3 + misc/dumpe2fs.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 270 insertions(+), 5 deletions(-) diff --git a/misc/dumpe2fs.8.in b/misc/dumpe2fs.8.in index da78d4fc..d03ee8be 100644 --- a/misc/dumpe2fs.8.in +++ b/misc/dumpe2fs.8.in @@ -72,6 +72,9 @@ as the pathname to the image file. .B \-x print the detailed group information block numbers in hexadecimal format .TP +.B \-j +use JSON ouput format +.TP .B \-V print the version number of .B dumpe2fs diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index ca9953a1..319c296b 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -42,6 +42,7 @@ extern int optind; #include "support/nls-enable.h" #include "support/plausible.h" +#include "support/json-out.h" #include "../version.h" #define in_use(m, x) (ext2fs_test_bit ((x), (m))) @@ -53,7 +54,7 @@ static int blocks64 = 0; static void usage(void) { - fprintf(stderr, _("Usage: %s [-bfghixV] [-o superblock=] " + fprintf(stderr, _("Usage: %s [-bfghixjV] [-o superblock=] " "[-o blocksize=] device\n"), program_name); exit(1); } @@ -69,6 +70,17 @@ static void print_number(unsigned long long num) printf("%llu", num); } +static void snprint_number(char *str, size_t size, unsigned long long num) +{ + if (hex_format) { + if (blocks64) + snprintf(str, size, "0x%08llx", num); + else + snprintf(str, size, "0x%04llx", num); + } else + snprintf(str, size, "%llu", num); +} + static void print_range(unsigned long long a, unsigned long long b) { if (hex_format) { @@ -80,6 +92,19 @@ static void print_range(unsigned long long a, unsigned long long b) printf("%llu-%llu", a, b); } +static struct json_obj *json_create_range_obj(unsigned long long a, + unsigned long long b) +{ + struct json_obj *obj = json_obj_create(); + char buf[32]; + const char *fmt = hex_format ? (blocks64 ? "0x%08llx" : "0x%04llx") : "%llu"; + + json_obj_add_fmt_buf_str(obj, "start", buf, sizeof(buf), fmt, a); + json_obj_add_fmt_buf_str(obj, "len", buf, sizeof(buf), fmt, b - a + 1); + + return obj; +} + static void print_free(unsigned long group, char * bitmap, unsigned long num, unsigned long offset, int ratio) { @@ -106,6 +131,31 @@ static void print_free(unsigned long group, char * bitmap, } } +static void fill_json_free(struct json_list *list, unsigned long group, + char *bitmap, unsigned long num, unsigned long offset, int ratio) +{ + unsigned long i; + unsigned long j; + unsigned long long a, b; + + offset /= ratio; + offset += group * num; + for (i = 0; i < num; i++) + if (!in_use (bitmap, i)) + { + for (j = i; j < num && !in_use (bitmap, j); j++) + ; + if (--j == i) + a = b = (i + offset) * ratio; + else { + a = (i + offset) * ratio; + b = (j + offset) * ratio; + i = j; + } + json_list_add_obj(list, json_create_range_obj(a, b)); + } +} + static void print_bg_opt(int bg_flags, int mask, const char *str, int *first) { @@ -136,6 +186,25 @@ static void print_bg_opts(ext2_filsys fs, dgrp_t i) fputc('\n', stdout); } +static void fill_json_bg_opts(struct json_obj *obj, ext2_filsys fs, dgrp_t i) +{ + int bg_flags = 0; + struct json_list *bg_opts_list = json_list_create_in_obj(obj, "bg-opts", + JSON_VAL_STRING); + + if (ext2fs_has_group_desc_csum(fs)) + bg_flags = ext2fs_bg_flags(fs, i); + else + return; + + if (bg_flags & EXT2_BG_INODE_UNINIT) + json_list_add_str(bg_opts_list, "INODE_UNINIT"); + if (bg_flags & EXT2_BG_BLOCK_UNINIT) + json_list_add_str(bg_opts_list, "BLOCK_UNINIT"); + if (bg_flags & EXT2_BG_INODE_ZEROED) + json_list_add_str(bg_opts_list, "ITABLE_ZEROED"); +} + static void print_bg_rel_offset(ext2_filsys fs, blk64_t block, int itable, blk64_t first_block, blk64_t last_block) { @@ -150,6 +219,29 @@ static void print_bg_rel_offset(ext2_filsys fs, blk64_t block, int itable, } } +static struct json_obj* json_create_bg_rel_offset_obj(ext2_filsys fs, + blk64_t block, int itable, blk64_t first_block, blk64_t last_block) +{ + struct json_obj *obj = json_obj_create(); + char buf[32]; + + if ((block >= first_block) && (block <= last_block)) { + if (itable && block == first_block) + return obj; + snprintf(buf, sizeof(buf), "%u", (unsigned)(block - first_block)); + json_obj_add_str(obj, "offset", buf); + } else if (ext2fs_has_feature_flex_bg(fs->super)) { + dgrp_t flex_grp = ext2fs_group_of_blk2(fs, block); + snprintf(buf, sizeof(buf), "%u", flex_grp); + json_obj_add_str(obj, "bg", buf); + snprintf(buf, sizeof(buf), "%u", + (unsigned)(block-ext2fs_group_first_block2(fs,flex_grp))); + json_obj_add_str(obj, "offset", buf); + } + + return obj; +} + static void list_desc(ext2_filsys fs, int grp_only) { unsigned long i; @@ -321,6 +413,165 @@ static void list_desc(ext2_filsys fs, int grp_only) free(inode_bitmap); } +static void fill_json_desc(struct json_obj *obj, ext2_filsys fs) +{ + unsigned long i; + blk64_t first_block, last_block; + blk64_t super_blk, old_desc_blk, new_desc_blk; + char *block_bitmap=NULL, *inode_bitmap=NULL; + const char *units = "blocks"; + int inode_blocks_per_group, old_desc_blocks, reserved_gdt; + int block_nbytes, inode_nbytes; + int has_super; + blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block); + ext2_ino_t ino_itr = 1; + errcode_t retval; + struct json_list *desc_list = json_list_create_in_obj(obj, "desc", JSON_VAL_OBJECT); + char buf[64]; + + if (ext2fs_has_feature_bigalloc(fs->super)) + units = "clusters"; + + block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8; + inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; + + if (fs->block_map) + block_bitmap = malloc(block_nbytes); + if (fs->inode_map) + inode_bitmap = malloc(inode_nbytes); + inode_blocks_per_group = ((fs->super->s_inodes_per_group * + EXT2_INODE_SIZE(fs->super)) + + EXT2_BLOCK_SIZE(fs->super) - 1) / + EXT2_BLOCK_SIZE(fs->super); + reserved_gdt = fs->super->s_reserved_gdt_blocks; + first_block = fs->super->s_first_data_block; + if (ext2fs_has_feature_meta_bg(fs->super)) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = fs->desc_blocks; + + for (i = 0; i < fs->group_desc_count; i++) { + struct json_obj *group_obj = json_obj_create(); + + json_list_add_obj(desc_list, group_obj); + + first_block = ext2fs_group_first_block2(fs, i); + last_block = ext2fs_group_last_block2(fs, i); + + ext2fs_super_and_bgd_loc2(fs, i, &super_blk, + &old_desc_blk, &new_desc_blk, 0); + + json_obj_add_fmt_buf_str(group_obj, "num", buf, sizeof(buf), "%lu", i); + json_obj_add_obj(group_obj, "blocks", + json_create_range_obj(first_block, last_block)); + if (ext2fs_has_group_desc_csum(fs)) { + unsigned csum = ext2fs_bg_checksum(fs, i); + unsigned exp_csum = ext2fs_group_desc_csum(fs, i); + + json_obj_add_fmt_buf_str(group_obj, "group-desc-csum", + buf, sizeof(buf), "0x%04x", csum); + if (csum != exp_csum) + json_obj_add_fmt_buf_str(group_obj, "group-desc-csum-exp", + buf, sizeof(buf), "0x%04x", exp_csum); + } + + fill_json_bg_opts(group_obj, fs, i); + has_super = ((i==0) || super_blk); + if (has_super) { + json_obj_add_str(group_obj, "superblock-type", + i == 0 ? "Primary" : "Backup"); + snprint_number(buf, sizeof(buf), super_blk); + json_obj_add_str(group_obj, "superblock-at", buf); + } + if (old_desc_blk) { + json_obj_add_obj(group_obj, "group-descriptors-at", + json_create_range_obj(old_desc_blk, + old_desc_blk + old_desc_blocks - 1)); + if (reserved_gdt) { + json_obj_add_obj(group_obj, "reserved-gdt-blocks-at", + json_create_range_obj(old_desc_blk + old_desc_blocks, + old_desc_blk + old_desc_blocks + reserved_gdt - 1)); + } + } else if (new_desc_blk) { + snprint_number(buf, sizeof(buf), new_desc_blk); + json_obj_add_str(group_obj, "group-desc-at", buf); + has_super++; + } + + snprint_number(buf, sizeof(buf), ext2fs_block_bitmap_loc(fs, i)); + json_obj_add_str(group_obj, "block-bitmap-at", buf); + json_obj_add_obj(group_obj, "block-bitmap-rel-offset", + json_create_bg_rel_offset_obj(fs, + ext2fs_block_bitmap_loc(fs, i), 0, + first_block, last_block)); + if (ext2fs_has_feature_metadata_csum(fs->super)) + json_obj_add_fmt_buf_str(group_obj, "block-bitmap-csum", buf, + sizeof(buf), "0x%08x", ext2fs_block_bitmap_checksum(fs, i)); + + snprint_number(buf, sizeof(buf), ext2fs_inode_bitmap_loc(fs, i)); + json_obj_add_str(group_obj, "inode-bitmap-at", buf); + json_obj_add_obj(group_obj, "inode-bitmap-rel-offset", + json_create_bg_rel_offset_obj(fs, + ext2fs_inode_bitmap_loc(fs, i), 0, + first_block, last_block)); + if (ext2fs_has_feature_metadata_csum(fs->super)) + json_obj_add_fmt_buf_str(group_obj, "inode-bitmap-csum", buf, + sizeof(buf), "0x%08x", ext2fs_inode_bitmap_checksum(fs, i)); + + json_obj_add_obj(group_obj, "inode-table-at", + json_create_range_obj(ext2fs_inode_table_loc(fs, i), + ext2fs_inode_table_loc(fs, i) + + inode_blocks_per_group - 1)); + + json_obj_add_obj(group_obj, "inode-table-rel-offset", + json_create_bg_rel_offset_obj(fs, + ext2fs_inode_table_loc(fs, i), 1, + first_block, last_block)); + + json_obj_add_fmt_buf_str(group_obj, "free-blocks-count", buf, + sizeof(buf), "%u %s", ext2fs_bg_free_blocks_count(fs, i), units); + json_obj_add_fmt_buf_str(group_obj, "free-inodes-count", buf, + sizeof(buf), "%u", ext2fs_bg_free_inodes_count(fs, i)); + json_obj_add_fmt_buf_str(group_obj, "used-dirs-count", buf, + sizeof(buf), "%u", ext2fs_bg_used_dirs_count(fs, i)); + json_obj_add_fmt_buf_str(group_obj, "unused-inodes", buf, + sizeof(buf), "%u", ext2fs_bg_itable_unused(fs, i)); + if (block_bitmap) { + struct json_list *free_blocks_list; + + free_blocks_list = json_list_create_in_obj(group_obj, + "free-blocks", JSON_VAL_OBJECT); + retval = ext2fs_get_block_bitmap_range2(fs->block_map, + blk_itr, block_nbytes << 3, block_bitmap); + if (!retval) + fill_json_free(free_blocks_list, i, + block_bitmap, + fs->super->s_clusters_per_group, + fs->super->s_first_data_block, + EXT2FS_CLUSTER_RATIO(fs)); + blk_itr += fs->super->s_clusters_per_group; + } + if (inode_bitmap) { + struct json_list *free_inodes_list; + + free_inodes_list = json_list_create_in_obj(group_obj, + "free-inodes", JSON_VAL_OBJECT); + retval = ext2fs_get_inode_bitmap_range2(fs->inode_map, + ino_itr, inode_nbytes << 3, inode_bitmap); + if (!retval) + fill_json_free(free_inodes_list, i, + inode_bitmap, + fs->super->s_inodes_per_group, + 1, 1); + ino_itr += fs->super->s_inodes_per_group; + } + } + if (block_bitmap) + free(block_bitmap); + if (inode_bitmap) + free(inode_bitmap); +} + static void list_bad_blocks(ext2_filsys fs, int dump) { badblocks_list bb_list = 0; @@ -510,6 +761,8 @@ int main (int argc, char ** argv) int header_only = 0; int c; int grp_only = 0; + int json = 0; + struct json_obj *dump_obj; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); @@ -524,7 +777,7 @@ int main (int argc, char ** argv) if (argc && *argv) program_name = *argv; - while ((c = getopt(argc, argv, "bfghixVo:")) != EOF) { + while ((c = getopt(argc, argv, "bfghixjVo:")) != EOF) { switch (c) { case 'b': print_badblocks++; @@ -553,6 +806,9 @@ int main (int argc, char ** argv) case 'x': hex_format++; break; + case 'j': + json++; + break; default: usage(); } @@ -597,6 +853,8 @@ try_open_again: check_plausibility(device_name, CHECK_FS_EXIST, NULL); exit (1); } + if (json) + dump_obj = json_obj_create(); fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE; if (ext2fs_has_feature_64bit(fs->super)) blocks64 = 1; @@ -616,10 +874,11 @@ try_open_again: ext2fs_close_free(&fs); exit(0); } - if (ext2fs_has_feature_journal(fs->super) && + if (!json && ext2fs_has_feature_journal(fs->super) && (fs->super->s_journal_inum != 0)) print_inline_journal_information(fs); - list_bad_blocks(fs, 0); + if (!json) + list_bad_blocks(fs, 0); if (header_only) { if (json) { json_obj_print_json(dump_obj, 0); @@ -639,7 +898,10 @@ try_bitmaps_again: if (!retval && (fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS)) printf("%s", _("\n*** Checksum errors detected in bitmaps! Run e2fsck now!\n\n")); just_descriptors: - list_desc(fs, grp_only); + if (json) + fill_json_desc(dump_obj, fs); + else + list_desc(fs, grp_only); if (retval) { printf(_("\n%s: %s: error reading bitmaps: %s\n"), program_name, device_name, From patchwork Tue Feb 20 09:59:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Prutyanov X-Patchwork-Id: 875456 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="OONt8EpZ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zlx215s0xz9ryy for ; Tue, 20 Feb 2018 21:00:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751563AbeBTKAV (ORCPT ); Tue, 20 Feb 2018 05:00:21 -0500 Received: from mail-he1eur01on0116.outbound.protection.outlook.com ([104.47.0.116]:10020 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751532AbeBTKAS (ORCPT ); Tue, 20 Feb 2018 05:00:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=a675s5+g7HEveU+NU1X0/HOB4J+QLf3a5vW2m3yGYec=; b=OONt8EpZpx9X97Vasfsm8sh0w504zoh3s0RMuyDoBtNsNeCHx5ZW85GhD/D6/fZU3Rj+2T1Z5/cdzHhBizQqIy+GSniWAva3Ba3PzCw/4zeOQVhz+3/G/EOYkLyFiPYdRZUn4nT3eque9/iftCV2sWCH3Z9PkOQGg3WrAOszpEw= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=viktor.prutyanov@virtuozzo.com; Received: from vprutyanov-pc.sw.ru (195.214.232.6) by AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.506.18; Tue, 20 Feb 2018 10:00:09 +0000 From: Viktor Prutyanov To: linux-ext4@vger.kernel.org Cc: Theodore Ts'o , Dmitry Monakhov , Viktor Prutyanov Subject: [PATCH v3 3/5] dumpe2fs: add JSON output of superblock Date: Tue, 20 Feb 2018 12:59:48 +0300 Message-Id: <20180220095950.23462-4-viktor.prutyanov@virtuozzo.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> References: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR0902CA0058.eurprd09.prod.outlook.com (2603:10a6:7:15::47) To AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 5f82558a-ed91-4773-b9c1-08d57848ba06 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:AM4PR08MB2849; X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 3:ei+AbmWCsbkQ0JFdila2Iy9ZMnXHp6mt656/O6vt+Tax2CoOu4kYaNM00Cp0df7k0GPXQJMPKL2zCxYGhfw66+hP6uz1t600UX1YaslR/dIl6W4WaQ4Lx9jd5cVSGO/1GV9Mz46S53MuIHO73RWR5eGhVrw5rwTs4fv09s1Y23WEWYiBq8HKwBrg+tJOEVF7OLe1VRY3oF8iqpcs481ujrWvG96l1Bi99OI+OFszH4F4cOfbtFSQEOy9Zq/ZvJAz; 25:cX2pY1CsBFnG0bqAeZdVeCkOtu//UZug//5wtZvoSdHobC4Qceletk+wM7eeQMerEU4EVKZHrLb3+PULyDfL+aHbYPE/SwPSgCE5u1qaKJj3k8pYhB0rQ3UST2xQYep6rpmEbV3veNCyDTkLVxIZvL7mp5jJSmO8D5Wciv3P7AeSgKXAr/bzRbr3aM2bDLwnm3pfRj1PhQx21FYP/du5HpWGsXP0yt4OKyr2nleOmpAkiAiY9PumyfTL/Bm9KGhJnSQVDjR4uJQRyol4gY5y0RVk+09NRc14jZ+pLGO00nn6BJ6TvjrMDZ0g9TAA1RE/pfPo073X8+D+OYqlM5BAlg==; 31:Cb2+wBzlz+IQugQB1BZq1uyvgbp90qff0PEv8e3pszSoz+7WSROeP6QZ6x4A7zAGvAPmbcJfWNDcWc3kWMMs7mRdfEaKktBXXbabInO+OyyFF8qvulZCccEzVgtxRZrtwcQuC4vDT0I0Y8BF8RBTVjVdYOVNXZG3Y+K/c6nOj76G16Cpo4LRJGEHEIDFxcaLKFsJT8kub1IVC9NQGrQyCGGo9Wv1908V/Z7lwynIpBc= X-MS-TrafficTypeDiagnostic: AM4PR08MB2849: X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:IOpWLftK0ZQczsalrlodXiFsbiPNsbpj7mLNLBMnBoC9o2rxg2ZoTHacMz9I+nlFyxpzrkikyJtfrUkA6Dg3OpMD4aSdptfWKX6CJCuALozZpnb+JUJ0PSp45xh4zclvxCqp/r0/myE5gc3yxHwMkAykoSGYsJKm958Akbv52vdHaQ87g7GRKBGPfK7MtsWKMFyRgi7gsSso6UJBQ8PfbI6sr0jD/3mjopuoCx1vXsYP7AnrRR0RKDFhBg2sLtdzUGvlzao0tmi5YUmvR5i32V6PWI3Vx5J6sutQ1a02BanUK8sUe0dL9fEjo4Y//6qIS9HobXvviBK6SYl/csqWRtnr8hdbV+wzivPtNmwFiCzeqCkqK/wCBOVkZFJm11d+DqVXc8TPoGzpBL2Grj5ALrMdR6ladnR9j1NsykFPQuu3nsrEgVaQP/MJ2wrAJy05wWDmKbBXbNHhyKKa6sMza9hr3ZpzZosQG+xPIDSrzMo355KR30TaO8tblrvxoIBV; 4:sP8RN4o0hwjyFXqLo0CbHyjR/ty4uBC1RIBp3NgoPmLAhEXl1FovRfR6y8Z/wjxFDcRgrt4ZlXON6OBwki1i1++R+L9tMx9aQBADIfej+bqi5O7yOqdLP6lFG0bK+aOlVxZLarXLGjxKzoKIUY46YrQk87qJ4o1aYGAovXKhEt+/0v/u8q7aFT8cfVEOgkJklsFMLn7320Xp1Z+QC4ivm/xyNUBXDRt9Z34irYD/0qPgyR3dXd5AJhIbvtgC3yODOua3X1GBgMSLb+ht9LGriQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(3231101)(944501161)(93006095)(93001095)(10201501046)(3002001)(6041288)(20161123560045)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM4PR08MB2849; BCL:0; PCL:0; RULEID:; SRVR:AM4PR08MB2849; X-Forefront-PRVS: 05891FB07F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(39850400004)(366004)(396003)(39380400002)(346002)(376002)(199004)(189003)(52116002)(16586007)(478600001)(54906003)(59450400001)(5660300001)(1076002)(68736007)(6666003)(51416003)(107886003)(69596002)(50466002)(86362001)(48376002)(8676002)(16526019)(186003)(76176011)(6116002)(55236004)(2950100002)(6916009)(26005)(3846002)(316002)(2906002)(386003)(81156014)(6506007)(81166006)(7736002)(97736004)(53416004)(8936002)(6486002)(305945005)(551544002)(36756003)(50226002)(53936002)(66066001)(6512007)(47776003)(25786009)(2351001)(105586002)(4326008)(106356001)(2361001)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM4PR08MB2849; H:vprutyanov-pc.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 23:iscRagWeUkmd0ue75SzOpg7t1TfKqqhWcWXy0XwBN9Umcvp7sBvLawNvBpb1qN0z+4f5ojcw9QR2DQnwWNBvSR4ouwMJYiitI37ap8mAok/1uQqmnkf7pTuqXHvBTlj+iItEfVdQ2ArUcOZvkFBTvfX2wNIujCXgtL2Z1f7QKhDAd/XQlIr5kAGQnuPDJCUPeD17H3p+QcPwABf0o+j+3dG+ZHNDCtFBGCGgAU+hURRsWjSQefJtlJmmOZpwjy0OvtG91Mbsj0wZZ3RjuRtBSsS4kLMzTM6FLgWbRbBEj33ipQRFB61TlEdiNJfTbcc8O+nTnfC2dxc/RG1fJF3PF20wJrJ2XprJgxwgnl6cZkCjooTW/Tmx8Lk7pU2B0TYiUUaF5sJTKYeOjhP8rMJhjb83FE+fud0thsE71ergitJKNQQWvWTrpIlJPyaITz29C1DVIFd9ByKnIIR+BO08So+AHCu+QhfOjxtc7wlvKpLOOWTSo450EUfduthq+13yT+DMBQdyR2lKKfqMgkeaeR/6E+dBSf7pk90yQu6I3cGFpugtBiBvaeVMLY3/fMAroEF1RoeN7xhyzPetZU3uU795zczkCBTqnUvHzzUNDZeXYhISEKdLvUpAwz0QUL7FaSp4LKHbjuqkYezSo+EogsHy+NswNAWMU9verHh0l5XHBMMoB9OsWKYspfsUedwcoJ/GX6ZGWn/8gPdLCp5S9FxSMqZ9rVmAbvhBSE99ON++UFEQ+VAIOsj3ad8kjeX52c7avGPdkYkXLbG0dKsz0kD3DWGriaRMIAdycVM/f7GpEHwuF2LEihRtN53s+kRtSr0k4Em/6hxmXCwoA33MQ43pKF5rPKlS70POz7lYusLbY19UQ3RR/3odlve0QB5SkHPJa7G8LtZ658O+F1zsS83Fr3oCzfqIz8nt75/0zjNZZdOT9kmZJvmDyDlX7mx3GaieV3L6HC/8nWnkhcVN5w2KelCFmwQZ8xzXWhE+0I955VbT02AQ4ey3ZTTJZc0CTWnKONCqryFECFHnXTelI/ypQiHzul2ulxctdmZgZOshg90UHdgLfzSkoYQlRsC5DHe5p1AeXPSqUwV9ob627n8Psn6yIvrqfUm1Ja/mN3/TiFt3KsCH8bL0/GA2vfh58IoWQDSErD+PNjkLh0VEXbozp4698RYza+to6EodFgeeAynDUNRiFcBgmw7yj12JnDgtbq/TJtM/dwjQ7CAhH58g2IW86CdDA0ZYj2J6Ndifpa/I9B8KjQf4EPemEJJ/+j1MLtFrXEVYJB8bLg0SWsO/V4sp7Sa7n1APpH6DlvWH8MrnHRzx0jugTqcvJhaG X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 6:pfo5p1iblokc+HNmpJ6xZz0nWJVA1aGwgUXqAXiNHpiwCAjgxvWgXhWA7xvqArS+D5mvmHwhc1wdqReDAAoCrGioAnW0b+bldnweyKsSwmdJuQSYmtsTQQ547OhvGKhhVkpiSt2cJaEHFDsxuG7PTBBZ3dfoaVb1GYpRxcZWUZb0LDL5PMdQxjgsqsYhmI9ChkLghfAKngGxjghlV9zLmlVjKrm+YOn3Rp/2igcxur5lzr+udfG9FaETX+bTkJuVpQnjip2pzFcjae9r4DphbNQjKD8BDkRzkkZQQpmsZwp4N4Y/DTNLAvj914CUYU1/+jKoY+1sCjXZFipxfgf80B+SrEdKQbMQsAAyHldM97o=; 5:2FVOCOKfFwN45gjjwKATc6DjODgqpbNJFK8OBiIdBKAL0l+Tq1ZVpvI7/4SdPmZiu74uYUbqDfTofhP6nOJgeZ8CTUXZW0U1rZva13Guaqbh9qoXNeH6mqkw2WjWKH36vC7BCc6Pqv9YVe9P/zmeFbGsYW8XPOqLsQ7x0OZGKXc=; 24:XxWz5uxTtMgfEgVw3CIscvrvxQHze+2rxL5A6hQSAVU4rAaP/DjR/aZDRrJxCtIlGq/IpzQWyWUj49vqnXoPT3Wg+aWZOMC8JLeSAcPjq80=; 7:22zloDR9zsHrmAPpaOOzp3jTC+TQo8Ogy3RVQrXJsOEmXqjkYAKNddKaNNJAyeUaspeaST7TBY9jlH9ihRBqTTvik26413hVuPgI96MqV/Wag0Ghfp2vuLnDzSaZLY6m0L6WqJOl4G2HDl6coYiGlkbYTBY7EVTCAHZcWS/gi5pmVJwIcTKL7ADxE/ogzIoUa6uxmTFW5YNDsutpGgjwkoCeTvqK1aRK2fS+I9sZVoN1sL2MSzPsAU+ddfvIEt4d SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:WlVY4sLmoU4bBkOBAU2xzIlkawQ6OhgoqhF5t1HQ/xj23F2J1C8uBwmUZWNA6jpa/OARXUxaXS/jFuD+LRLdNTDMVbABe9LnjTVn+2DZlr4wkh2omt7yQXIzfqXoqeb8LOsMe97eDDBbizdkS0vQZqzx0MEJrKMZ/wDYnsZOW2c= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Feb 2018 10:00:09.3024 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5f82558a-ed91-4773-b9c1-08d57848ba06 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR08MB2849 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds JSON output of superblock information Signed-off-by: Viktor Prutyanov --- debugfs/Makefile.in | 4 +- lib/e2p/e2p.h | 6 + lib/e2p/ls.c | 362 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/e2p/pe.c | 18 +++ lib/e2p/ps.c | 10 ++ misc/Makefile.in | 8 +- misc/dumpe2fs.c | 5 +- 7 files changed, 406 insertions(+), 7 deletions(-) diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in index 57940cde..92a3552a 100644 --- a/debugfs/Makefile.in +++ b/debugfs/Makefile.in @@ -34,9 +34,9 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \ $(srcdir)/journal.c $(srcdir)/../e2fsck/revoke.c \ $(srcdir)/../e2fsck/recovery.c $(srcdir)/do_journal.c -LIBS= $(LIBSUPPORT) $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \ +LIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSUPPORT) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \ $(LIBUUID) $(LIBMAGIC) $(SYSLIBS) -DEPLIBS= $(DEPLIBSUPPORT) $(LIBEXT2FS) $(LIBE2P) $(DEPLIBSS) $(DEPLIBCOM_ERR) \ +DEPLIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSUPPORT) $(DEPLIBSS) $(DEPLIBCOM_ERR) \ $(DEPLIBBLKID) $(DEPLIBUUID) STATIC_LIBS= $(STATIC_LIBSUPPORT) $(STATIC_LIBEXT2FS) $(STATIC_LIBSS) \ diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h index e96cdec8..88c08d73 100644 --- a/lib/e2p/e2p.h +++ b/lib/e2p/e2p.h @@ -13,6 +13,8 @@ #include +#include "support/json-out.h" + #define E2P_FEATURE_COMPAT 0 #define E2P_FEATURE_INCOMPAT 1 #define E2P_FEATURE_RO_INCOMPAT 2 @@ -42,8 +44,10 @@ int iterate_on_dir (const char * dir_name, void list_super(struct ext2_super_block * s); void list_super2(struct ext2_super_block * s, FILE *f); void print_fs_errors (FILE * f, unsigned short errors); +void snprint_fs_errors (char *str, size_t size, unsigned short errors); void print_flags (FILE * f, unsigned long flags, unsigned options); void print_fs_state (FILE * f, unsigned short state); +void snprint_fs_state (char *str, size_t size, unsigned short state); int setflags (int fd, unsigned long flags); int setversion (int fd, unsigned long version); @@ -77,3 +81,5 @@ char *e2p_os2string(int os_type); int e2p_string2os(char *str); unsigned int e2p_percent(int percent, unsigned int base); + +void fill_json_super(struct json_obj *obj, struct ext2_super_block * s); diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c index a7586e09..b690960b 100644 --- a/lib/e2p/ls.c +++ b/lib/e2p/ls.c @@ -37,6 +37,15 @@ static void print_user (unsigned short uid, FILE *f) fprintf(f, "(user %s)\n", pw->pw_name); } +static void fill_json_user(struct json_obj *obj, unsigned short uid) +{ + struct passwd *pw = getpwuid(uid); + + json_obj_add_fmt_str(obj, "uid", 32, "%u", uid); + if (pw) + json_obj_add_str(obj, "user", pw->pw_name); +} + static void print_group (unsigned short gid, FILE *f) { struct group *gr; @@ -49,6 +58,15 @@ static void print_group (unsigned short gid, FILE *f) fprintf(f, "(group %s)\n", gr->gr_name); } +static void fill_json_group(struct json_obj *obj, unsigned short gid) +{ + struct group *gr = getgrgid(gid); + + json_obj_add_fmt_str(obj, "gid", 32, "%u", gid); + if (gr) + json_obj_add_str(obj, "group", gr->gr_name); +} + #define MONTH_INT (86400 * 30) #define WEEK_INT (86400 * 7) #define DAY_INT (86400) @@ -117,6 +135,24 @@ static void print_features(struct ext2_super_block * s, FILE *f) #endif } +static void fill_json_features(struct json_obj *obj, + struct ext2_super_block *s) +{ +#ifdef EXT2_DYNAMIC_REV + int i, j; + __u32 *mask = &s->s_feature_compat, m; + struct json_list *list = json_list_create_in_obj(obj, + "filesystem-features", JSON_VAL_STRING); + + for (i=0; i <3; i++,mask++) { + for (j=0,m=1; j < 32; j++, m<<=1) { + if (*mask & m) + json_list_add_str(list, e2p_feature2string(i, m)); + } + } +#endif +} + static void print_mntopts(struct ext2_super_block * s, FILE *f) { #ifdef EXT2_DYNAMIC_REV @@ -142,6 +178,26 @@ static void print_mntopts(struct ext2_super_block * s, FILE *f) #endif } +static void fill_json_mntopts(struct json_obj *obj, + struct ext2_super_block *s) +{ +#ifdef EXT2_DYNAMIC_REV + int i; + __u32 mask = s->s_default_mount_opts, m; + struct json_list *list = json_list_create_in_obj(obj, + "default-mount-options", JSON_VAL_STRING); + + if (mask & EXT3_DEFM_JMODE) + json_list_add_str(list, e2p_mntopt2string(mask & EXT3_DEFM_JMODE)); + for (i=0,m=1; i < 32; i++, m<<=1) { + if (m & EXT3_DEFM_JMODE) + continue; + if (mask & m) + json_list_add_str(list, e2p_mntopt2string(m)); + } +#endif +} + static void print_super_flags(struct ext2_super_block * s, FILE *f) { int flags_found = 0; @@ -168,6 +224,25 @@ static void print_super_flags(struct ext2_super_block * s, FILE *f) fputs("(none)\n", f); } +static void fill_json_super_flags(struct json_obj *obj, + struct ext2_super_block *s) +{ + int flags_found = 0; + struct json_list *list = json_list_create_in_obj(obj, + "filesystem-flags", JSON_VAL_STRING); + + if (s->s_flags == 0) + return; + + if (s->s_flags & EXT2_FLAGS_SIGNED_HASH) + json_list_add_str(list, "signed_directory_hash"); + if (s->s_flags & EXT2_FLAGS_UNSIGNED_HASH) + json_list_add_str(list, "unsigned_directory_hash"); + if (s->s_flags & EXT2_FLAGS_TEST_FILESYS) + json_list_add_str(list, "test_filesystem"); +} + + static __u64 e2p_blocks_count(struct ext2_super_block *super) { return super->s_blocks_count | @@ -213,6 +288,12 @@ static const char *quota_prefix[MAXQUOTAS] = { [PRJQUOTA] = "Project quota inode:", }; +static const char *json_quota_prefix[MAXQUOTAS] = { + [USRQUOTA] = "user-quota-inode", + [GRPQUOTA] = "group-quota-inode", + [PRJQUOTA] = "project-quota-inode", +}; + /** * Convert type of quota to written representation */ @@ -477,3 +558,284 @@ void list_super (struct ext2_super_block * s) list_super2(s, stdout); } +static void fill_json_time(struct json_obj *obj, const char *key, char *buf, + time_t tm) +{ + char *str; + + if (tm && (ctime_r(&tm, buf))) { + if (str = strchr(buf, '\n')) + *str = '\0'; + json_obj_add_str(obj, key, buf); + } +} + +void fill_json_super(struct json_obj *obj, struct ext2_super_block * sb) +{ + int inode_blocks_per_group; + char buf[80], *str; + time_t tm; + enum quota_type qtype; + struct json_obj *super_obj = json_obj_create_in_obj(obj, "super"); + + inode_blocks_per_group = (((sb->s_inodes_per_group * + EXT2_INODE_SIZE(sb)) + + EXT2_BLOCK_SIZE(sb) - 1) / + EXT2_BLOCK_SIZE(sb)); + if (sb->s_volume_name[0]) { + memset(buf, 0, sizeof(buf)); + strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name)); + } else + strcpy(buf, ""); + json_obj_add_str(super_obj, "fs-volume-name", buf); + if (sb->s_last_mounted[0]) { + memset(buf, 0, sizeof(buf)); + strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted)); + } else + strcpy(buf, ""); + json_obj_add_str(super_obj, "last-mounted-on", buf); + json_obj_add_str(super_obj, "fs-uuid", e2p_uuid2str(sb->s_uuid)); + json_obj_add_fmt_buf_str(super_obj, "fs-magic-number", buf, sizeof(buf), + "0x%04X", sb->s_magic); + json_obj_add_fmt_buf_str(super_obj, "fs-revision-level", buf, sizeof(buf), + "%d", sb->s_rev_level); + fill_json_features(super_obj, sb); + fill_json_super_flags(super_obj, sb); + fill_json_mntopts(super_obj, sb); + if (sb->s_mount_opts[0]) + json_obj_add_str(super_obj, "mount-options", sb->s_mount_opts); + snprint_fs_state(buf, sizeof(buf), sb->s_state); + json_obj_add_str(super_obj, "fs-state", buf); + snprint_fs_errors(buf, sizeof(buf), sb->s_errors); + json_obj_add_str(super_obj, "errors-behaviour", buf); + str = e2p_os2string(sb->s_creator_os); + json_obj_add_str(super_obj, "fs-os-type", str); + free(str); + json_obj_add_fmt_buf_str(super_obj, "inode-count", buf, sizeof(buf), "%u", + sb->s_inodes_count); + json_obj_add_fmt_buf_str(super_obj, "block-count", buf, sizeof(buf), + "%llu", e2p_blocks_count(sb)); + json_obj_add_fmt_buf_str(super_obj, "reserved-block-count", buf, + sizeof(buf), "%llu", e2p_r_blocks_count(sb)); + if (sb->s_overhead_blocks) + json_obj_add_fmt_buf_str(super_obj, "overhead-blocks", buf, + sizeof(buf), "%u", sb->s_overhead_blocks); + json_obj_add_fmt_buf_str(super_obj, "free-blocks", buf, sizeof(buf), + "%llu", e2p_free_blocks_count(sb)); + json_obj_add_fmt_buf_str(super_obj, "free-inodes", buf, sizeof(buf), "%u", + sb->s_free_inodes_count); + json_obj_add_fmt_buf_str(super_obj, "first-block", buf, sizeof(buf), "%u", + sb->s_first_data_block); + json_obj_add_fmt_buf_str(super_obj, "block-size", buf, sizeof(buf), "%u", + EXT2_BLOCK_SIZE(sb)); + if (ext2fs_has_feature_bigalloc(sb)) + json_obj_add_fmt_buf_str(super_obj, "cluster-size", buf, sizeof(buf), + "%u", EXT2_CLUSTER_SIZE(sb)); + else + json_obj_add_fmt_buf_str(super_obj, "fragment-size", buf, sizeof(buf), + "%u", EXT2_CLUSTER_SIZE(sb)); + + if (ext2fs_has_feature_64bit(sb)) + json_obj_add_fmt_buf_str(super_obj, "group-descriptor-size", buf, + sizeof(buf), "%u", sb->s_desc_size); + if (sb->s_reserved_gdt_blocks) + json_obj_add_fmt_buf_str(super_obj, "reserved-gdt-blocks", buf, + sizeof(buf), "%u", sb->s_reserved_gdt_blocks); + json_obj_add_fmt_buf_str(super_obj, "blocks-per-group", buf, sizeof(buf), + "%u", sb->s_blocks_per_group); + if (ext2fs_has_feature_bigalloc(sb)) + json_obj_add_fmt_buf_str(super_obj, "clusters-per-group", buf, + sizeof(buf), "%u", sb->s_clusters_per_group); + else + json_obj_add_fmt_buf_str(super_obj, "fragments-per-group", buf, + sizeof(buf), "%u", sb->s_clusters_per_group); + json_obj_add_fmt_buf_str(super_obj, "inodes-per-group", buf, sizeof(buf), + "%u", sb->s_inodes_per_group); + json_obj_add_fmt_buf_str(super_obj, "inode-blocks-per-group", buf, + sizeof(buf), "%u", inode_blocks_per_group); + if (sb->s_raid_stride) + json_obj_add_fmt_buf_str(super_obj, "raid-stride", buf, sizeof(buf), + "%u", sb->s_raid_stride); + if (sb->s_raid_stripe_width) + json_obj_add_fmt_buf_str(super_obj, "raid-stripe-width", buf, + sizeof(buf), "%u", sb->s_raid_stripe_width); + if (sb->s_first_meta_bg) + json_obj_add_fmt_buf_str(super_obj, "first-meta-block-group", buf, + sizeof(buf), "%u", sb->s_first_meta_bg); + if (sb->s_log_groups_per_flex) + json_obj_add_fmt_buf_str(super_obj, "flex-block-group-size", buf, + sizeof(buf), "%u", 1 << sb->s_log_groups_per_flex); + + json_obj_add_fmt_buf_str(super_obj, "inodes-per-group", buf, sizeof(buf), + "%u", sb->s_inodes_per_group); + json_obj_add_fmt_buf_str(super_obj, "inode-blocks-per-group", buf, + sizeof(buf), "%u", inode_blocks_per_group); + if (sb->s_raid_stride) + json_obj_add_fmt_buf_str(super_obj, "raid-stride", buf, sizeof(buf), + "%u", sb->s_raid_stride); + if (sb->s_raid_stripe_width) + json_obj_add_fmt_buf_str(super_obj, "raid-stripe-width", buf, + sizeof(buf), "%u", sb->s_raid_stripe_width); + if (sb->s_first_meta_bg) + json_obj_add_fmt_buf_str(super_obj, "first-meta-block-group", buf, + sizeof(buf), "%u", sb->s_first_meta_bg); + if (sb->s_log_groups_per_flex) + json_obj_add_fmt_buf_str(super_obj, "flex-block-group-size", buf, + sizeof(buf), "%u", 1 << sb->s_log_groups_per_flex); + fill_json_time(super_obj, "filesystem-created", buf, sb->s_mkfs_time); + fill_json_time(super_obj, "last-mount-time", buf, sb->s_mtime); + fill_json_time(super_obj, "last-write-time", buf, sb->s_wtime); + json_obj_add_fmt_buf_str(super_obj, "mount-count", buf, sizeof(buf), + "%u", sb->s_mnt_count); + json_obj_add_fmt_buf_str(super_obj, "maximum-mount-count", buf, + sizeof(buf), "%d", sb->s_max_mnt_count); + fill_json_time(super_obj, "last-checked", buf, sb->s_lastcheck); + json_obj_add_fmt_buf_str(super_obj, "check-interval", buf, sizeof(buf), + "%u", sb->s_checkinterval); + json_obj_add_str(super_obj, "check-interval-str", + interval_string(sb->s_checkinterval)); + if (sb->s_checkinterval) + { + time_t next = sb->s_lastcheck + sb->s_checkinterval; + + fill_json_time(super_obj, "next-check-after", buf, + sb->s_lastcheck + sb->s_checkinterval); + } +#define POW2(x) ((__u64) 1 << (x)) + if (sb->s_kbytes_written) { + if (sb->s_kbytes_written < POW2(13)) + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, + sizeof(buf), "%llu kB", sb->s_kbytes_written); + else if (sb->s_kbytes_written < POW2(23)) + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, + sizeof(buf), "%llu MB", + (sb->s_kbytes_written + POW2(9)) >> 10); + else if (sb->s_kbytes_written < POW2(33)) + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, + sizeof(buf), "%llu GB", + (sb->s_kbytes_written + POW2(19)) >> 20); + else if (sb->s_kbytes_written < POW2(43)) + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, + sizeof(buf), "%llu TB", + (sb->s_kbytes_written + POW2(29)) >> 30); + else + json_obj_add_fmt_buf_str(super_obj, "lifetime-writes", buf, + sizeof(buf), "%llu PB", + (sb->s_kbytes_written + POW2(39)) >> 40); + } + fill_json_user(super_obj, sb->s_def_resuid); + fill_json_group(super_obj, sb->s_def_resgid); + if (sb->s_rev_level >= EXT2_DYNAMIC_REV) { + json_obj_add_fmt_buf_str(super_obj, "first-inode", buf, sizeof(buf), + "%d", sb->s_first_ino); + json_obj_add_fmt_buf_str(super_obj, "inode-size", buf, sizeof(buf), + "%d", sb->s_inode_size); + if (sb->s_min_extra_isize) + json_obj_add_fmt_buf_str(super_obj, "required-extra-isize", buf, + sizeof(buf), "%d", sb->s_min_extra_isize); + if (sb->s_want_extra_isize) + json_obj_add_fmt_buf_str(super_obj, "desired-extra-isize", buf, + sizeof(buf), "%d", sb->s_want_extra_isize); + } + if (!e2p_is_null_uuid(sb->s_journal_uuid)) + json_obj_add_str(super_obj, "journal-uuid", + e2p_uuid2str(sb->s_journal_uuid)); + if (sb->s_journal_inum) + json_obj_add_fmt_buf_str(super_obj, "journal-inode", buf, + sizeof(buf), "%u", sb->s_journal_inum); + if (sb->s_journal_dev) + json_obj_add_fmt_buf_str(super_obj, "journal-device", buf, + sizeof(buf), "0x%04x", sb->s_journal_dev); + if (sb->s_last_orphan) + json_obj_add_fmt_buf_str(super_obj, "first-orphan-inode", buf, + sizeof(buf), "%u", sb->s_last_orphan); + if (ext2fs_has_feature_dir_index(sb) || + sb->s_def_hash_version) + json_obj_add_str(super_obj, "default-directory-hash", + e2p_hash2string(sb->s_def_hash_version)); + if (!e2p_is_null_uuid(sb->s_hash_seed)) + json_obj_add_str(super_obj, "directory-hash-seed", + e2p_uuid2str(sb->s_hash_seed)); + if (sb->s_jnl_backup_type) { + switch (sb->s_jnl_backup_type) { + case 1: + json_obj_add_str(super_obj, "journal-backup", "inode blocks"); + break; + default: + json_obj_add_fmt_buf_str(super_obj, "journal-backup", buf, + sizeof(buf), "type %u", sb->s_jnl_backup_type); + } + } + if (sb->s_backup_bgs[0]) + json_obj_add_fmt_buf_str(super_obj, "backup-block-group-0", buf, + sizeof(buf), "%u", sb->s_backup_bgs[0]); + if (sb->s_backup_bgs[1]) + json_obj_add_fmt_buf_str(super_obj, "backup-block-group-1", buf, + sizeof(buf), "%u", sb->s_backup_bgs[1]); + if (sb->s_snapshot_inum) { + json_obj_add_fmt_buf_str(super_obj, "snapshot-inode", buf, sizeof(buf), + "%u", sb->s_snapshot_inum); + json_obj_add_fmt_buf_str(super_obj, "snapshot-id", buf, sizeof(buf), + "%u", sb->s_snapshot_id); + json_obj_add_fmt_buf_str(super_obj, "snapshot-reserved-blocks", buf, + sizeof(buf), "%llu", sb->s_snapshot_r_blocks_count); + } + if (sb->s_snapshot_list) + json_obj_add_fmt_buf_str(super_obj, "snapshot-list-head", buf, + sizeof(buf), "%u", sb->s_snapshot_list); + if (sb->s_error_count) + json_obj_add_fmt_buf_str(super_obj, "fs-error-count", buf, sizeof(buf), + "%u", sb->s_error_count); + if (sb->s_first_error_time) { + fill_json_time(super_obj, "first-error-time", buf, + sb->s_first_error_time); + memset(buf, 0, sizeof(buf)); + strncpy(buf, (char *)sb->s_first_error_func, + sizeof(sb->s_first_error_func)); + json_obj_add_str(super_obj, "first-error-function", buf); + json_obj_add_fmt_buf_str(super_obj, "first-error-line-num", buf, + sizeof(buf), "%u", sb->s_first_error_line); + json_obj_add_fmt_buf_str(super_obj, "first-error-inode-num", buf, + sizeof(buf), "%u", sb->s_first_error_ino); + json_obj_add_fmt_buf_str(super_obj, "first-error-block-num", buf, + sizeof(buf), "%llu", sb->s_first_error_block); + } + if (sb->s_last_error_time) { + fill_json_time(super_obj, "last-error-time", buf, + sb->s_last_error_time); + memset(buf, 0, sizeof(buf)); + strncpy(buf, (char *)sb->s_last_error_func, + sizeof(sb->s_last_error_func)); + json_obj_add_str(super_obj, "last-error-function", buf); + json_obj_add_fmt_buf_str(super_obj, "last-error-line-num", buf, + sizeof(buf), "%u", sb->s_last_error_line); + json_obj_add_fmt_buf_str(super_obj, "last-error-inode-num", buf, + sizeof(buf), "%u", sb->s_last_error_ino); + json_obj_add_fmt_buf_str(super_obj, "last-error-block-num", buf, + sizeof(buf), "%llu", sb->s_last_error_block); + } + if (ext2fs_has_feature_mmp(sb)) { + json_obj_add_fmt_buf_str(super_obj, "mmp-block-number", buf, + sizeof(buf), "%llu", (long long)sb->s_mmp_block); + json_obj_add_fmt_buf_str(super_obj, "mmp-update-interval", buf, + sizeof(buf), "%u", sb->s_mmp_update_interval); + } + for (qtype = 0; qtype < MAXQUOTAS; qtype++) { + if (*quota_sb_inump(sb, qtype) != 0) + json_obj_add_fmt_buf_str(super_obj, json_quota_prefix[qtype], buf, + sizeof(buf), "%u", *quota_sb_inump(sb, qtype)); + } + if (ext2fs_has_feature_metadata_csum(sb)) { + json_obj_add_str(super_obj, "checksum-type", + checksum_type(sb->s_checksum_type)); + json_obj_add_fmt_buf_str(super_obj, "checksum", buf, sizeof(buf), + "0x%08x", sb->s_checksum); + } + if (!e2p_is_null_uuid(sb->s_encrypt_pw_salt)) + json_obj_add_str(super_obj, "encryption-pw-salt", + e2p_uuid2str(sb->s_encrypt_pw_salt)); + + if (ext2fs_has_feature_csum_seed(sb)) + json_obj_add_fmt_buf_str(super_obj, "checksum-seed", buf, sizeof(buf), + "0x%08x", sb->s_checksum_seed); +} diff --git a/lib/e2p/pe.c b/lib/e2p/pe.c index 1f24545d..9426e743 100644 --- a/lib/e2p/pe.c +++ b/lib/e2p/pe.c @@ -38,3 +38,21 @@ void print_fs_errors (FILE * f, unsigned short errors) fprintf (f, "Unknown (continue)"); } } + +void snprint_fs_errors (char *buf, size_t size, unsigned short errors) +{ + switch (errors) + { + case EXT2_ERRORS_CONTINUE: + snprintf (buf, size, "Continue"); + break; + case EXT2_ERRORS_RO: + snprintf (buf, size, "Remount read-only"); + break; + case EXT2_ERRORS_PANIC: + snprintf (buf, size, "Panic"); + break; + default: + snprintf (buf, size, "Unknown"); + } +} diff --git a/lib/e2p/ps.c b/lib/e2p/ps.c index 757f8a66..19eb6559 100644 --- a/lib/e2p/ps.c +++ b/lib/e2p/ps.c @@ -30,3 +30,13 @@ void print_fs_state (FILE * f, unsigned short state) if (state & EXT2_ERROR_FS) fprintf (f, " with errors"); } + +void snprint_fs_state (char *str, size_t size, unsigned short state) +{ + if (state & EXT2_VALID_FS) + snprintf (str, size, "clean"); + else + snprintf (str, size, "not clean"); + if (state & EXT2_ERROR_FS) + snprintf (str, size, "with errors"); +} diff --git a/misc/Makefile.in b/misc/Makefile.in index 6f631eb1..a863ef62 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -170,15 +170,15 @@ e2initrd_helper: e2initrd_helper.o $(DEPLIBS) $(DEPLIBBLKID) $(LIBEXT2FS) tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS) $(DEPLIBS_E2P) $(DEPLIBBLKID) \ $(DEPLIBUUID) $(LIBEXT2FS) $(E) " LD $@" - $(Q) $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS) \ - $(LIBBLKID) $(LIBUUID) $(LIBEXT2FS) $(LIBS_E2P) \ + $(Q) $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) \ + $(LIBBLKID) $(LIBUUID) $(LIBEXT2FS) $(LIBS_E2P) $(LIBS) \ $(LIBINTL) $(SYSLIBS) $(LIBBLKID) $(LIBMAGIC) tune2fs.static: $(TUNE2FS_OBJS) $(STATIC_DEPLIBS) $(STATIC_LIBE2P) $(DEPSTATIC_LIBBLKID) $(E) " LD $@" $(Q) $(CC) $(LDFLAGS_STATIC) -o tune2fs.static $(TUNE2FS_OBJS) \ - $(STATIC_LIBS) $(STATIC_LIBBLKID) $(STATIC_LIBUUID) \ - $(STATIC_LIBE2P) $(LIBINTL) $(SYSLIBS) \ + $(STATIC_LIBBLKID) $(STATIC_LIBUUID) \ + $(STATIC_LIBE2P) $(STATIC_LIBS) $(LIBINTL) $(SYSLIBS) \ $(STATIC_LIBBLKID) $(LIBMAGIC) tune2fs.profiled: $(TUNE2FS_OBJS) $(PROFILED_DEPLIBS) \ diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 319c296b..93e4b2ff 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -863,7 +863,10 @@ try_open_again: } else { if (grp_only) goto just_descriptors; - list_super (fs->super); + if (json) + fill_json_super(dump_obj, fs->super); + else + list_super (fs->super); if (ext2fs_has_feature_journal_dev(fs->super)) { print_journal_information(fs, dump_obj); if (json) { From patchwork Tue Feb 20 09:59:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Prutyanov X-Patchwork-Id: 875458 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="OtZzzOtZ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zlx243hw3z9s0b for ; Tue, 20 Feb 2018 21:00:28 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751168AbeBTKAZ (ORCPT ); Tue, 20 Feb 2018 05:00:25 -0500 Received: from mail-he1eur01on0116.outbound.protection.outlook.com ([104.47.0.116]:10020 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751432AbeBTKAV (ORCPT ); Tue, 20 Feb 2018 05:00:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=OmcHomexrLK/J/WoUkv7hgYzDWXGIBJEjuSi3w3WtPY=; b=OtZzzOtZyx4JTr2MqTucwfUslvMvCgy1Mae4i/zlCH5Z2VTgHbZJlRRvpwmFLiLy0f9HiNrQ1ZWXtkREkBKStZl1kI8Gjm1o+N2G1tHT5RrzCdVt6zcKTTCCxdPkv4+zM4PXHaEVjCQ5fU7W1gW8XZ3qmpzqFtCa33OTb9a+8Tw= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=viktor.prutyanov@virtuozzo.com; Received: from vprutyanov-pc.sw.ru (195.214.232.6) by AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.506.18; Tue, 20 Feb 2018 10:00:09 +0000 From: Viktor Prutyanov To: linux-ext4@vger.kernel.org Cc: Theodore Ts'o , Dmitry Monakhov , Viktor Prutyanov Subject: [PATCH v3 4/5] dumpe2fs: add JSON output of journal Date: Tue, 20 Feb 2018 12:59:49 +0300 Message-Id: <20180220095950.23462-5-viktor.prutyanov@virtuozzo.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> References: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR0902CA0058.eurprd09.prod.outlook.com (2603:10a6:7:15::47) To AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c5530abc-c880-407b-3f2a-08d57848ba6d X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:AM4PR08MB2849; X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 3:BSX9kvBXPT73tXwquAOaUydyrhoV0Yf7AShRs82TT+4rlwjKOT9mkRrVzSuOFNeIcsv5smd+cnw7cO/s19wGHGI5jpqUSYvJ4+rB4+Lf6AwCkit7/+ZzBC3BomF7pmUeAP99IV9rNyXsM8UGakznLbYATr2DS1rR8SOK3fiX6gwTuxUGd6gLIA7nflhTqN5JuvUFptCgt0VfIfhx1OxBsDVnmBcn0SlLpVXEsJShqHlMfZhCv+sFdrChXKfp+6DA; 25:YTOjl3kaL2JvoRnFYPHE7YR8QPuGD3mHscbLNgUzSCRArg64kzBvlqoiOMATeYNtSGYxxrBP2C6ttkrLhoQFQq6MvHRUkbDjYVDq+Wp9zp9bCcOw170qYWafCHv/Vn2QLSl3SDxUrf2C1wFJRRN6K0Bcb5IUiSqkLdXVS7cfUa4DZhWuNSg7IFVjvcSdP3wjZwdUhrD+YqUUShxg6YHwwlNq/7mPFlC6KMhaZw+6Gs4lGvhLuzlwmUZlM6T/SiMWA8wwEuVlxCNKfinvBPkjAugOaTNgzYoautUgBTF4s5uLleaI6Hq775H24WRyqKvOP6u10p2egYUNvj+NctDqgA==; 31:bSglSo5jbBLiOprGi6jRdinOauCYzNyQN7NnBc98bxwbwOW6tB1e5rzYZ/8F9U2VOBL3ow64QjUkWegz0HwEzyahn9HxN8y+K7wlohnRnAEE0huBwq+uBZwPUqUB9I+f1Je1x5H+QEh27DB3pVsciY8MroIxLE7c93EoiZjqEkklMdAWU3Syx3g4MJS3X6jXNrA38/U5zoWWe9ANHYpqTB8C5gMbZ9nGZQqZd+Zdrbg= X-MS-TrafficTypeDiagnostic: AM4PR08MB2849: X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:mn7YNbJJkY2GjR519C2x+iHWeF29DdFsvGDsr3M/K2NUFWNiYNG7Hg6DTymse8bkcAXLROpYT7xapLS0BrarvFdRuWK4vGXBB/0zkmbIMDA2svliHGYbVXZIYgZyLHDyPsuuKax3dlNj9xCgeoZax2f+uhWiva3Ub88+q/JUXeCa4jpRNxoPttLVVXUa56i6Olf7wd9AaGTymcudC5J31H/F689EOq5Im72hx9t69kWUja48jHaWo/5EHc7cof9ofaVyCAlQDbnZrSeN3M+MHdQjFH1rfp8V5tgl4c2NNpe2uzFNOi6kkp1QRGq6vQkERio/RsQT5e43RuTfDNrINgKEnCP21BO7ocsprq1J7ZbVQKbE3eiMAYm8zjhEPThSllYTusn7v6jz6y0V7GPQpo6ktJ6nsqKe32zVcHrKjFt4lih8F52B4xmjn+KLCiUePvn5da9S3BSB9WSgE09dGypVQQxujLFEeZVW36CfKRHA2h2PBYYq6QK3SSKYxJmF; 4:VXFjsR6d16hV51wTM+sYVoBGCbQgpETtfqwSTCJEmRnFTAxvQFqx441RNMm4WnhsmMlYzi/LT0AM33YE9f3zqCWdwc0y4ADXy4v1CNAi6osTLwALOetDg1bIp/hKEkME3i6ivgV9bchmYapKS4w+9F6iD4h5gn3LMU6C9XvyzDREbwdZk4dVYBB3AxS4kjP/hwsUU9rcostSnrrh3qC+Nd0835dJJm13z1unTjBbO0acTmswdctZ92m7iHhy0SjokltrN1NtpMqsxrrFUn4OXQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(3231101)(944501161)(93006095)(93001095)(10201501046)(3002001)(6041288)(20161123560045)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM4PR08MB2849; BCL:0; PCL:0; RULEID:; SRVR:AM4PR08MB2849; X-Forefront-PRVS: 05891FB07F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(39850400004)(366004)(396003)(39380400002)(346002)(376002)(199004)(189003)(52116002)(16586007)(478600001)(54906003)(59450400001)(5660300001)(1076002)(68736007)(6666003)(51416003)(107886003)(69596002)(50466002)(86362001)(48376002)(8676002)(16526019)(186003)(76176011)(6116002)(55236004)(2950100002)(6916009)(26005)(3846002)(316002)(2906002)(386003)(81156014)(6506007)(81166006)(7736002)(97736004)(53416004)(8936002)(6486002)(305945005)(36756003)(50226002)(53936002)(66066001)(6512007)(47776003)(25786009)(2351001)(105586002)(4326008)(106356001)(2361001)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM4PR08MB2849; H:vprutyanov-pc.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 23:TFSUrGBnjnwBKSlXf5Gm13EmKiLyjXWDzV59g0D/SUjOTZxsN3s/ZqMowcS8ZYyoByvcbq6xz9Rhflw44PGcX793QRYawnGPocMyYN5x02+AFfkP+TYcJozE/GEQkoUgznQlKeH+UDmnKDjjSxrDzOH+loIYh7BbTLFaPuGi91zMY9S86f9zDjZL1rfy92nuGY9I1uI8HWTYIqlaU304g9j6RHtMAKptFLicKIpo0dQfowB5lNTvUrOTNuqlhdvZB8WJuFBavQq+HzE+nUNePIZ2P/8QJJaCVWhMW1M//iHjFoWi89DHZi2oSrq536oC9t/lbxaBskvp0rtl8tNggvhKpOuBvNCpRskcptR3IGLy9Gf6xO0+KcK0dgupi6LvXd/FfGMb7HraOzXDO1iUAimKLfKWZn6dxzoAzyzXzsB1BGH/dyhB8Kay3ehP8/GODmgfqjNtjB2RC1xOukEcWbEC4vNyDnJ+60WEXiwCjTvCkODJ1FCg9Uh0UkjrTrXJvDcO2qt4xdfx+SscfD/Y6eJOCWgzOi14G2pnfIVZLMKNMyE2oKx4Hnz6aih3tuOFwFmHMnUvcnzzORsREw2cHMMnl820wSRRI0hADpZb2HN7wXumvggIUDQvWGQKAAhI8FulsIcOI6iwCGPQj/XRrmnSmTWz9v1N9anLjlWTXrUADrKGRMcK3qqM75aT2aSiPJEPVCLiBGlvH9ir7bHNfrAAgKWrR3TOt1WDs075Z202ODe7iO/vf3DgAq5QQ2sVZ2CZ7OkFUvl9DLnXFkXlZ6uVw3SOzr1iXCrVBKEu84GHlz1NdlDBwizovl5eAmUENODzOe6OLS8g/t0/l5SKAkHknrhnE3IFavVr2U8+OQ4vJ2EMHJw4FQQq/qCyNzVQ8cIVRyV5sl3W7P7+ocnv8tUnM1dd4RcEKslLYqK+M7ZVuAR84TzSTKxGsDUAPYekJm/0IRGCvIF3Iv8I6DCKp79rFisjUm1swcy/yydMqd/tzUsoiFC4CaEllNuLmP+VxM/foUeBNQjoj5VngEK1w8N/dkc28EpnfghY+VIQZA4pbR3S0RlLvkTbmV24K0zjr0VdT7o55z9eEB1TK9BWxYACNuiqqUEQ1/g+/Sep+hAmDK8HBxWDofjq0sGOHLPDIsI2IGTMKYC2kwGTzCdMQqavacnNR2q0zuj95+q+/NDvz13xiFfdmq6PD3aMioHeFrpAEICK+ioZbl7fS6axBNKGW1ZVWpNofuN8xjUSBrHYsPRzl1+YpMlSxECrC10zWDD2bZJ+epB8TJDeDWsKWYbWgxkQSNP9CR9/h9AyNr0= X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 6:9O1vBT3nvu1vlM4EXmpwE4JKolBp5xAi51OtnNdTerjUfhTr3WAZMd7sypVkgQUbqFXJH104EdnTTT4NhjoRJ5pYcDhyTT2mhcsytDUrQKt6tMgBLiObpGL+/5I4AtLTp4t1uiVS1BdulP7dhORrsxSzoMcxYQFkyBGN8HGPfhh2wmb+lfDcuTVUkDCsWvcQG1z2MR+wckFrhH+p7/TE6AwKkcOjWbKW1cILsrorgJvV+BWgcx+x2TzFOC4szUtjcomMWh2G5l0txpnlIsOE7yHdfnhKI9CKluZohM6wPMfV6EbLDY7ZVq14c+u3QUUjelCRWRDgkW0fU5vnN9XW7EoLZFxRbx9uruqOqqx+jw0=; 5:x2ubWt4gCAEZp38JRNj6jQB0CCBBOxk/RxWoG0Ny0Zo4pAdeDhnzpLCtH+mX5wm+sgkEcnKQIysfAM5CXDkWlgFUuCCEtxDdb3GH6eGg8xFHVgscbWpNJ0efRO6tSHzbxy9vGTvy1v3BIFtufxTiG/qk0JDOTvE6i32Mq9BIROQ=; 24:5ilF5yun1vHfjkyr2SSSPIqq1lXyj5c+0UmCJ5Xi+Kt81FeGQERujD37LS6zFNNRFsKWA2MHERyXx4j3w+K3S8dGp95D1tSZMryUUOTtZ9s=; 7:RGynYLY2/5vukDvMIW5Dq5KJQB3GzhfdvEdhzgdhTJCCbgvf9gDqLwcLGxHtt+7oD4Pu2SFiqHYBkAVbCAYglE2kkJIiqshkJMjA0Kmk7+bEqXT+q27gtkhcFYM8Ql8KOGv38XzPzHGqqDUoYrs6LuN62LDQjlV4Q72Yi3bdA8LF2QEBtZVR/Bh1H7zfBMa9eFmLI76SH9C572FCPtf39dznc9gqSTMVyHU+17GJ/8PKLWusjD19TlasGpfMx23+ SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:t3yV0LuRLF4Xn2MMhgfB93nAo3MNtt50o9ClJS0COlAWx+mgLIyZSJ/AAMrUI3yc/SbVKw/rSCipphmK1hWJV96YkLiPxqomppCgGPLoofqK4gnPkG4JNgaknuLH6qRkmRxGFmKo3kBEzj2PFGPWftbxMUWRhembvOxDL2/e6MA= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Feb 2018 10:00:09.9899 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c5530abc-c880-407b-3f2a-08d57848ba6d X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR08MB2849 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds JSON output of journal information Signed-off-by: Viktor Prutyanov --- lib/e2p/e2p.h | 2 ++ lib/e2p/ljs.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ misc/dumpe2fs.c | 20 +++++++++++++------- 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h index 88c08d73..cd3793e5 100644 --- a/lib/e2p/e2p.h +++ b/lib/e2p/e2p.h @@ -83,3 +83,5 @@ int e2p_string2os(char *str); unsigned int e2p_percent(int percent, unsigned int base); void fill_json_super(struct json_obj *obj, struct ext2_super_block * s); +void e2p_fill_json_journal_super(struct json_obj *obj, char *journal_sb_buf, + int exp_block_size, int flags); diff --git a/lib/e2p/ljs.c b/lib/e2p/ljs.c index 2db700b0..c75610b8 100644 --- a/lib/e2p/ljs.c +++ b/lib/e2p/ljs.c @@ -111,3 +111,60 @@ void e2p_list_journal_super(FILE *f, char *journal_sb_buf, fprintf(f, "Journal errno: %d\n", (int) ntohl(jsb->s_errno)); } + +void e2p_fill_json_journal_super(struct json_obj *obj, char *journal_sb_buf, + int exp_block_size, int flags) +{ + journal_superblock_t *jsb = (journal_superblock_t *) journal_sb_buf; + __u32 *mask_ptr, mask, m; + unsigned int size; + int i, j, printed = 0; + unsigned int nr_users; + struct json_obj *journal_obj = json_obj_create_in_obj(obj, "journal"); + struct json_list *features_list, *users_list; + char buf[64]; + + features_list = json_list_create_in_obj(journal_obj, "journal-features", JSON_VAL_STRING); + for (i=0, mask_ptr=&jsb->s_feature_compat; i <3; i++,mask_ptr++) { + mask = e2p_be32(*mask_ptr); + for (j=0,m=1; j < 32; j++, m<<=1) { + if (mask & m) + json_list_add_str(features_list, e2p_jrnl_feature2string(i, m)); + } + } + size = (ntohl(jsb->s_blocksize) / 1024) * ntohl(jsb->s_maxlen); + if (size < 8192) + json_obj_add_fmt_buf_str(journal_obj, "journal-size", buf, sizeof(buf), "%uk", size); + else + json_obj_add_fmt_buf_str(journal_obj, "journal-size", buf, sizeof(buf), "%uM", size >> 10); + nr_users = (unsigned int) ntohl(jsb->s_nr_users); + if (exp_block_size != ntohl(jsb->s_blocksize)) + json_obj_add_fmt_buf_str(journal_obj, "journal-block-size", buf, sizeof(buf), "%u", + (unsigned int)ntohl(jsb->s_blocksize)); + json_obj_add_fmt_buf_str(journal_obj, "journal-length", buf, sizeof(buf), "%u", + (unsigned int)ntohl(jsb->s_maxlen)); + if (ntohl(jsb->s_first) != 1) + json_obj_add_fmt_buf_str(journal_obj, "journal-first-block", buf, sizeof(buf), "%u", + (unsigned int)ntohl(jsb->s_first)); + json_obj_add_fmt_buf_str(journal_obj, "journal-sequence", buf, sizeof(buf), "0x%08x", (unsigned int)ntohl(jsb->s_sequence)); + json_obj_add_fmt_buf_str(journal_obj, "journal-start", buf, sizeof(buf), "%u", (unsigned int)ntohl(jsb->s_start)); + if (nr_users != 1) + json_obj_add_fmt_buf_str(journal_obj, "journal-number-of-users", buf, sizeof(buf), "%u", nr_users); + if (jsb->s_feature_compat & e2p_be32(JFS_FEATURE_COMPAT_CHECKSUM)) + json_obj_add_str(journal_obj, "journal-checksum-type", "crc32"); + if ((jsb->s_feature_incompat & + e2p_be32(JFS_FEATURE_INCOMPAT_CSUM_V3)) || + (jsb->s_feature_incompat & + e2p_be32(JFS_FEATURE_INCOMPAT_CSUM_V2))) { + json_obj_add_str(journal_obj, "journal-checksum-type", journal_checksum_type_str(jsb->s_checksum_type)); + json_obj_add_fmt_buf_str(journal_obj, "journal-checksum", buf, sizeof(buf), "0x%08x", e2p_be32(jsb->s_checksum)); + } + if ((nr_users > 1) || + !e2p_is_null_uuid(&jsb->s_users[0])) { + users_list = json_list_create_in_obj(journal_obj, "journal-users", JSON_VAL_STRING); + for (i=0; i < nr_users; i++) + json_list_add_str(users_list, e2p_uuid2str(&jsb->s_users[i*16])); + } + if (jsb->s_errno != 0) + json_obj_add_fmt_buf_str(journal_obj, "journal-errno", buf, sizeof(buf), "%d", (int) ntohl(jsb->s_errno)); +} diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 93e4b2ff..dc18d508 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -607,7 +607,7 @@ static void list_bad_blocks(ext2_filsys fs, int dump) ext2fs_badblocks_list_free(bb_list); } -static void print_inline_journal_information(ext2_filsys fs) +static void print_inline_journal_information(ext2_filsys fs, struct json_obj *obj) { journal_superblock_t *jsb; struct ext2_inode inode; @@ -643,10 +643,13 @@ static void print_inline_journal_information(ext2_filsys fs) _("Journal superblock magic number invalid!\n")); exit(1); } - e2p_list_journal_super(stdout, buf, fs->blocksize, 0); + if (obj) + e2p_fill_json_journal_super(obj, buf, fs->blocksize, 0); + else + e2p_list_journal_super(stdout, buf, fs->blocksize, 0); } -static void print_journal_information(ext2_filsys fs) +static void print_journal_information(ext2_filsys fs, struct json_obj *obj) { errcode_t retval; char buf[1024]; @@ -668,7 +671,10 @@ static void print_journal_information(ext2_filsys fs) _("Couldn't find journal superblock magic numbers")); exit(1); } - e2p_list_journal_super(stdout, buf, fs->blocksize, 0); + if (obj) + e2p_fill_json_journal_super(obj, buf, fs->blocksize, 0); + else + e2p_list_journal_super(stdout, buf, fs->blocksize, 0); } static void parse_extended_opts(const char *opts, blk64_t *superblock, @@ -762,7 +768,7 @@ int main (int argc, char ** argv) int c; int grp_only = 0; int json = 0; - struct json_obj *dump_obj; + struct json_obj *dump_obj = NULL; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); @@ -877,9 +883,9 @@ try_open_again: ext2fs_close_free(&fs); exit(0); } - if (!json && ext2fs_has_feature_journal(fs->super) && + if (ext2fs_has_feature_journal(fs->super) && (fs->super->s_journal_inum != 0)) - print_inline_journal_information(fs); + print_inline_journal_information(fs, dump_obj); if (!json) list_bad_blocks(fs, 0); if (header_only) { From patchwork Tue Feb 20 09:59:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viktor Prutyanov X-Patchwork-Id: 875459 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="FdnyIcgD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zlx266nb2z9ryy for ; Tue, 20 Feb 2018 21:00:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751677AbeBTKA1 (ORCPT ); Tue, 20 Feb 2018 05:00:27 -0500 Received: from mail-he1eur01on0116.outbound.protection.outlook.com ([104.47.0.116]:10020 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751532AbeBTKAX (ORCPT ); Tue, 20 Feb 2018 05:00:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=6ese44I0Krnlb72NCVtV81Y5vqaVe6U3w/ILf+y4+Ic=; b=FdnyIcgDEWjlrkngExHZ+MWCQeMXeuEXa1geCbt1p+f4kPQGKDyFX1VNtDXtqKJE4lVQ4vIG77SyJoz7txiFOEDvl5HzjFaSvK5HfQxkdxkJX24rLXJ2PSLkicxZBTccrhEKcMQ/DURG4l89Tgvz4MXvYTfhX6em5J4DfJd9dkI= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=viktor.prutyanov@virtuozzo.com; Received: from vprutyanov-pc.sw.ru (195.214.232.6) by AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.506.18; Tue, 20 Feb 2018 10:00:10 +0000 From: Viktor Prutyanov To: linux-ext4@vger.kernel.org Cc: Theodore Ts'o , Dmitry Monakhov , Viktor Prutyanov Subject: [PATCH v3 5/5] dumpe2fs: add JSON output of bad blocks Date: Tue, 20 Feb 2018 12:59:50 +0300 Message-Id: <20180220095950.23462-6-viktor.prutyanov@virtuozzo.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> References: <20180220095950.23462-1-viktor.prutyanov@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: HE1PR0902CA0058.eurprd09.prod.outlook.com (2603:10a6:7:15::47) To AM4PR08MB2849.eurprd08.prod.outlook.com (2603:10a6:205:d::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 17cd92a3-4367-4ad7-26ff-08d57848bad6 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:AM4PR08MB2849; X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 3:lehtF+w7fydrqDBtVI763VTlfRc8dVAcaFIPcXGYSH4ubL5i0Uuy+sqKFQ66cG5EzLCux89sMh4SjXSmBkRlWZCZlu2c+Rje83N3sjGAwcju7sNSmT2YihAN1QFElEVDzPNOJ5eahqIbtOYHDXI0tboBohHWRuRdmVJeCdgmPEPdXCzWcM6vUgkdCm1poSivcUzFRx/rLg6noaHVccyike4mG4dSSp7fUwDxIO97EhcQLVJEpAapcqKTEAB40bdi; 25:o38uQ2Fyx00ug4kfHRKuKJuQCLVl5RsWPkVNxzqpdQe9kQV5EsJB0608S5WpVSOrPyHlw8DvbqyXZNAmVKPlHG24QDCE635E+8RW7ZCcKVGkPcIbzo4j0CQs1OY89PNUpgNLfxjINSIAKKWyGGf2l1S1CZThFjdM7+G/ClFVDktUCo7G4Bu3hESwr3rDNokZOAg1DXR8Mc12wwzfj3PA4Q056hdehAw0oI7q5F1hSZ8ezJ4+Vch9SFu/0Ukbf+SS47XGVthDSUou+GC9qx5+bHw8+3kiXsAhN/4wqodEgoXRavC+p+FrpZTgCYV07O8c5TP3I65g3Kn8M6wIsrMCbg==; 31:Y9tzkGAz1Xu+a2qZhna8vnq81jPEko8oaY6+m8Ovu+wLS2sAIFM9QH63tbBooy1K03eLkoZApfc0aB9RWtYtjxpZeuRg2hhUVPus3qua4F4izE8XV0cpHC8qkfvO3k9NtyeKT5K2GkSamIypU0UYr2eO7bTfbm/tBHWD/tfBDqDuqIaaOxCjUWHmeAAT9ps3KEaLARHT7u8l874lBuZjORvFyaaQI97GzBv5dNGZ0EQ= X-MS-TrafficTypeDiagnostic: AM4PR08MB2849: X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:HGHRELqoX1C8GhZwCZItYzSbAAvd2bx7XydFZVwlCCvIQTetDs2NQoAR/lFWMwbjhgGNIeGVvJVff4eagPkHZystbHHx7h5z1+hKoGSojojqNXKCN6lLM3ZsEjB2c0fmH7bhAvxWmHQmm9egK+fyllAFVRvqyNkpnxMy5q/PMny1V+CtQ8H7GBJqwwQXnOMl1+enWv6Bjg9P+YjY+cVDbyFBhoBwswY3iD4uXIlDs6NfaeFVr/E9LQj2rRWsmd2jxUmbL77/e96/BpB6KKXvjSFHed016ruJbjHLZtjgeSfnySzkMptijGfLKpd8Z96vCPnV/MuZrmwrp86g0JqSjBujCIC2A8a1PgnhEMCCPWt5pCxv96S3HVMKf0m7685fUCJIe1jo1PCA3WROSlKfAO5UDRikBH0maYTw8i13s9EtngA/Ydp2lVn4DiH7doyI7pRNAZtuBMIHVQHy/ZIq9ZyyLfNuRrAt3UC0znclIT+ob0oS5Lf+622iiDk6lo1g; 4:3IydrnfdUti0RmjIziqN9PghoA/RzVTiicz7LTo01iLjbRJTpccmSXIn7LEz4cOWNJiDopA3hw52x6qZ4mFTtCUgH1RUbxf9GyXCB34ZI/FPlY67/QvbzIwA5ESKcpBopBZy+Lc7ZHv61OnW7cTmCKZeFLESXBWThwVQVtIYGGWifn/grn+KEMMQQ/stjT4AraIAbSwUA+UWLTxxCu3tWkBIko2huxcxZ7ZDf2QoYlSjc1goh9gC6HpQq4uTfiaNnQhuxAV75ycK5I1fdnJFKw== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(3231101)(944501161)(93006095)(93001095)(10201501046)(3002001)(6041288)(20161123560045)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM4PR08MB2849; BCL:0; PCL:0; RULEID:; SRVR:AM4PR08MB2849; X-Forefront-PRVS: 05891FB07F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(39850400004)(366004)(396003)(39380400002)(346002)(376002)(199004)(189003)(52116002)(16586007)(478600001)(54906003)(5660300001)(1076002)(68736007)(6666003)(51416003)(107886003)(69596002)(50466002)(86362001)(48376002)(8676002)(16526019)(186003)(76176011)(6116002)(55236004)(2950100002)(6916009)(26005)(3846002)(316002)(2906002)(386003)(81156014)(6506007)(81166006)(7736002)(97736004)(53416004)(8936002)(6486002)(305945005)(36756003)(50226002)(53936002)(66066001)(6512007)(47776003)(25786009)(2351001)(105586002)(4326008)(106356001)(2361001)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM4PR08MB2849; H:vprutyanov-pc.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 23:vgg/JV4evqF1LdUq1QdN50TfhvCXtVxx13QKJalp/v1RpE0CPlTVVWbu5sAuAKeopxHBzNAIuvLBHikPU1GqAPQyqf1CKGJlfBChUk4v8C4fzzZNTFwo++xEr77q1trZNJ/nZYRe01l3oa8xKPcR09K1tZ5McJJMTTBwQjH/X2e07C1tWvpsw2h3WnA5FGe7G8iAYWvz03Hgi+2UV2bCp5oaUU+QM3ukCZc0HUFC9VALpG8PY4/qQwRaxJxySvUccEOxWkr96bExhH30bGLrYSCW/ZPmVDVtX3kip6DcyEokAVV+1x5D3uyZ/uH7vQyytCy00IEb3lOwqe1sr2GBcpZGP5EgDjW0J2LrV+peeQXTfKK2Udb+TlajaxO/tZI+b2imFqS86H1IweLR9Aw6qNpyIIN4GojVSmKJ5ngdglfRQyeY6yGvj80V88l97ctSV4pi+1fqkunYeuwJe2wJUjnTmeqXu/w0RZ6Jj126hJ9BoLKVlv1mI95JDmyZRsPRpnKsN4l/JTayW+dVg3xZ+UM8tVofqCDqaVDFCJN7xKSM84pxrOhqFxOXJy899BJ+VFNCmplipgheV4HMR552UXBQmYfRnmlyWSz4kvBZpaDI2nRcUnKyKIRFTOcY5X4mD280GlRVjIdlAwlpnQzeEbNyTknSOwSQXq9qPtXHYvyaAgjjxXaLAaH3glg/IusrUONXTjKuWl64uNI1itidI824lc8dxMOUJTvbCd32VIN6gcYpfkoAMpPsrAYWDP9QDrBxGlAXZ7cedN4wbx6h1JDNJVluN+aI/5jboERZ7e5RB0D7UPyiWDo9gM8ACK/bfg4d8VHxjramnVTc0TE0SfhYDbO3BxcJZkNaQXGCzwB6Cy8yDQuHRGPAaL978K1fu7EQ4np0y/rnLCuKry1Rf50v3pQ8MGckfVGPMetYNSkrlF+gidxKibOhEBr/a6JbwrOfK/gumbeQLQOQ8s0x/MnAJj0qTw6doEaPhHtzV19xrXlixI3pUuKvLXL8xyOcmUakp7ZmUtzHLKDxnRNYZqlYuNRxSFH+Hm3Eh+rZlZx4YLOh31WCbr+o1uGsreubs73v6tc4yloDypRpoFxC43FPNlbM/EbWcfzY4miGZ0zb785hYqG5y2kY/efnHveeV6QIPDLz99s2Bdh5/tD2RJsGd6avTJmDPwbqQ5B0CFPaTxFXXsmHLXBo24r2dc37xyxYI2gfE+Sp9VO6QwHW+YHnk8Qy/mm3QOV6V4b8hM7DY2Y44VImsApI6ictXwCz9LV/2YRrAtt+1lXRQySTnQ== X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 6:eIyf4xN9enBC5Iqpuk0QnmTG38QWm0awCIog2IJ6EPuXFWH66VKzYsPAT277eW/M9nZapdvTWU2eFDHrGU/HQPdd+ls4hJEGN+2BoB8ZL8wXI+iiJrYh3HAk4u1nweg6Xj8d7c7mxr/CGtJt0GZa7pzoKgX5/o0RQ6G+zQpVvinxvzWu3kIdMa+siFojNg75btdvo4eWByk1TyNgyXEoCKqMlHGlk8DcpbuFeIlMYKBjOMifF32L55kFxwb3siLDd+By4IDDXTZ7mloYBYm7e/7xxqPnzHdkvS/27yukRTV392GjCcTOpIVLHg8eEISWZZ4TOCBcO9z2ad87Ewvt4OiNp8zCYPdC4mGPh93jMYM=; 5:vtU5eIBz2XEBca3D7XNWpFNs9klMiVymrLdF1pav+lZw7EfsA6pOmm4wwCP70OwZ+3AyTJ3jZgvvsKoa9Njx1BkBWeBZJRpUK3pqPgSSFOl9SCGCCJqmzBfuVEuEptPw0lG2aSGI9HRT55FILNQmsi4pWAVIUD79UN0K4hR/PZM=; 24:GuY1otxEPhoVG1rCjJB3+5Kdp9mnjxf/gSO6G9RZeFKaDlt1qWa83EhFpFax5O2NY52mRAH1qNcIOyI/i2n/9ubF52SzqJmAeegmyiCP4rA=; 7:c/Ai3cffKfaGUKmzCq6zQICfoD28H9CnPq14T8U4sIF5Fa/s30TUt+haI4j6ARDUt9N00xS4vZ/o4OvQJGar5lKO1w9C1nEkcaxffQuA+flpTbARwu0wYKol9te8TYReGBeOuQrnGSxLPX8KQqgpOuq0kYgp7TLKKALpmbwqxZ95x16HLn6piDTs3eJMLygqUiNpN7ll9U8WwRLyxpiYpN2cno/ZcNQ7CYCJg44RhgsDOMesx0L/WLWI8DjfH8EP SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR08MB2849; 20:TW/qrMnANZi5r30EPKW4/pdVsUuDgwJAh5BzXcMgldLoNGVCKzyYU3hczWinv7Qbmt5rsED2MzuFkbHBAdCgyV97TVD1U58WUIXNEUXeNtALDu5fCrrSDPVkVeX3a3xf+XD4Teo//fp/PLY5y315CbglCYgk6H+g3ucHgEQwzQ4= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Feb 2018 10:00:10.6774 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 17cd92a3-4367-4ad7-26ff-08d57848bad6 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR08MB2849 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds output of bad blocks list in JSON format Signed-off-by: Viktor Prutyanov --- misc/dumpe2fs.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index dc18d508..819023f5 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -572,14 +572,19 @@ static void fill_json_desc(struct json_obj *obj, ext2_filsys fs) free(inode_bitmap); } -static void list_bad_blocks(ext2_filsys fs, int dump) +static void list_bad_blocks(ext2_filsys fs, int dump, struct json_obj *obj) { badblocks_list bb_list = 0; badblocks_iterate bb_iter; blk_t blk; errcode_t retval; const char *header, *fmt; + struct json_list *bb_json_list = NULL; + char buf[32]; + if (obj) + bb_json_list = json_list_create_in_obj(obj, "bad-blocks", + JSON_VAL_STRING); retval = ext2fs_read_bb_inode(fs, &bb_list); if (retval) { com_err("ext2fs_read_bb_inode", retval, 0); @@ -598,11 +603,16 @@ static void list_bad_blocks(ext2_filsys fs, int dump) fmt = ", %u"; } while (ext2fs_badblocks_list_iterate(bb_iter, &blk)) { + if (bb_json_list) { + snprintf(buf, sizeof(buf), "%u", blk); + json_list_add_str(bb_json_list, buf); + continue; + } printf(header ? header : fmt, blk); header = 0; } ext2fs_badblocks_list_iterate_end(bb_iter); - if (!dump) + if (!dump && !bb_json_list) fputc('\n', stdout); ext2fs_badblocks_list_free(bb_list); } @@ -865,7 +875,7 @@ try_open_again: if (ext2fs_has_feature_64bit(fs->super)) blocks64 = 1; if (print_badblocks) { - list_bad_blocks(fs, 1); + list_bad_blocks(fs, 1, dump_obj); } else { if (grp_only) goto just_descriptors; @@ -886,8 +896,7 @@ try_open_again: if (ext2fs_has_feature_journal(fs->super) && (fs->super->s_journal_inum != 0)) print_inline_journal_information(fs, dump_obj); - if (!json) - list_bad_blocks(fs, 0); + list_bad_blocks(fs, 0, dump_obj); if (header_only) { if (json) { json_obj_print_json(dump_obj, 0);