Skip to content

Commit b3a289a

Browse files
author
Darrick J. Wong
committed
xfs: create event queuing, formatting, and discovery infrastructure
Create the basic infrastructure that we need to report health events to userspace. We need a compact form for recording critical information about an event and queueing them; a means to notice that we've lost some events; and a means to format the events into something that userspace can handle. Make the kernel export C structures via read(). In a previous iteration of this new subsystem, I wanted to explore data exchange formats that are more flexible and easier for humans to read than C structures. The thought being that when we want to rev (or worse, enlarge) the event format, it ought to be trivially easy to do that in a way that doesn't break old userspace. I looked at formats such as protobufs and capnproto. These look really nice in that extending the wire format is fairly easy, you can give it a data schema and it generates the serialization code for you, handles endianness problems, etc. The huge downside is that neither support C all that well. Too hard, and didn't want to port either of those huge sprawling libraries first to the kernel and then again to xfsprogs. Then I thought, how about JSON? Javascript objects are human readable, the kernel can emit json without much fuss (it's all just strings!) and there are plenty of interpreters for python/rust/c/etc. There's a proposed schema format for json, which means that xfs can publish a description of the events that kernel will emit. Userspace consumers (e.g. xfsprogs/xfs_healer) can embed the same schema document and use it to validate the incoming events from the kernel, which means it can discard events that it doesn't understand, or garbage being emitted due to bugs. However, json has a huge crutch -- javascript is well known for its vague definitions of what are numbers. This makes expressing a large number rather fraught, because the runtime is free to represent a number in nearly any way it wants. Stupider ones will truncate values to word size, others will roll out doubles for uint52_t (yes, fifty-two) with the resulting loss of precision. Not good when you're dealing with discrete units. It just so happens that python's json library is smart enough to see a sequence of digits and put them in a u64 (at least on x86_64/aarch64) but an actual javascript interpreter (pasting into Firefox) isn't necessarily so clever. It turns out that none of the proposed json schemas were ever ratified even in an open-consensus way, so json blobs are still just loosely structured blobs. The parsing in userspace was also noticeably slow and memory-consumptive. Hence only the C interface survives. Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
1 parent a48373e commit b3a289a

5 files changed

Lines changed: 768 additions & 6 deletions

File tree

fs/xfs/libxfs/xfs_fs.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,12 +1003,59 @@ struct xfs_rtgroup_geometry {
10031003
#define XFS_RTGROUP_GEOM_SICK_RMAPBT (1U << 3) /* reverse mappings */
10041004
#define XFS_RTGROUP_GEOM_SICK_REFCNTBT (1U << 4) /* reference counts */
10051005

1006+
/* Health monitor event domains */
1007+
1008+
/* affects the whole fs */
1009+
#define XFS_HEALTH_MONITOR_DOMAIN_MOUNT (0)
1010+
1011+
/* Health monitor event types */
1012+
1013+
/* status of the monitor itself */
1014+
#define XFS_HEALTH_MONITOR_TYPE_RUNNING (0)
1015+
#define XFS_HEALTH_MONITOR_TYPE_LOST (1)
1016+
1017+
/* lost events */
1018+
struct xfs_health_monitor_lost {
1019+
__u64 count;
1020+
};
1021+
1022+
struct xfs_health_monitor_event {
1023+
/* XFS_HEALTH_MONITOR_DOMAIN_* */
1024+
__u32 domain;
1025+
1026+
/* XFS_HEALTH_MONITOR_TYPE_* */
1027+
__u32 type;
1028+
1029+
/* Timestamp of the event, in nanoseconds since the Unix epoch */
1030+
__u64 time_ns;
1031+
1032+
/*
1033+
* Details of the event. The primary clients are written in python
1034+
* and rust, so break this up because bindgen hates anonymous structs
1035+
* and unions.
1036+
*/
1037+
union {
1038+
struct xfs_health_monitor_lost lost;
1039+
} e;
1040+
1041+
/* zeroes */
1042+
__u64 pad[2];
1043+
};
1044+
10061045
struct xfs_health_monitor {
10071046
__u64 flags; /* flags */
10081047
__u8 format; /* output format */
10091048
__u8 pad[23]; /* zeroes */
10101049
};
10111050

1051+
/* Return all health status events, not just deltas */
1052+
#define XFS_HEALTH_MONITOR_VERBOSE (1ULL << 0)
1053+
1054+
#define XFS_HEALTH_MONITOR_ALL (XFS_HEALTH_MONITOR_VERBOSE)
1055+
1056+
/* Initial return format version */
1057+
#define XFS_HEALTH_MONITOR_FMT_V0 (0)
1058+
10121059
/*
10131060
* ioctl commands that are used by Linux filesystems
10141061
*/

0 commit comments

Comments
 (0)