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) {