Log the filesystem type and label
Some checks failed
Build / build-mac (push) Has been cancelled
Build / build-linux (push) Has been cancelled
Build / build-win (push) Has been cancelled
CodeQL Advanced / Analyze (c-cpp) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled

This commit is contained in:
Andrea Mazzoleni 2026-01-29 18:43:00 +01:00
parent 5a5668851d
commit 9f081f9c22
10 changed files with 435 additions and 81 deletions

View file

@ -742,6 +742,8 @@ struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev
disk->smartctl[0] = 0;
for (i = 0; i < SMART_IGNORE_MAX; ++i)
disk->smartignore[i] = 0;
disk->fstype[0] = 0;
disk->fslabel[0] = 0;
disk->device = dev;
disk->tick = 0;
disk->cached_blocks = 0;

View file

@ -40,6 +40,12 @@
*/
#define UUID_MAX 128
/**
* Max filesystem type/label length
*/
#define FSINFO_MAX 64
/**
* Invalid position.
*/
@ -334,6 +340,8 @@ struct snapraid_disk {
char smartctl[PATH_MAX]; /**< Custom command for smartctl. Empty means auto. */
int smartignore[SMART_IGNORE_MAX]; /**< Smart attributes to ignore for this device. */
char uuid[UUID_MAX]; /**< UUID of the disk. They are probed during the config reading. */
char fstype[FSINFO_MAX]; /**< Filesystem type */
char fslabel[FSINFO_MAX]; /**< Filesystem label */
uint64_t device; /**< Device identifier. */
block_off_t total_blocks; /**< Number of total blocks. */
@ -456,6 +464,8 @@ struct snapraid_map {
struct snapraid_split {
char path[PATH_MAX]; /**< Path of the parity file. */
char uuid[UUID_MAX]; /**< UUID of the disk. Empty if unknown. They are probed during the config reading, and later read from the content file. */
char fstype[FSINFO_MAX]; /**< Filesystem type */
char fslabel[FSINFO_MAX]; /**< Filesystem label */
/**
* Size of the parity split.

View file

@ -1890,7 +1890,7 @@ int filephy(const char* file, uint64_t size, uint64_t* physical)
return 0;
}
int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space)
int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space, char* fstype, size_t fstype_size, char* fslabel, size_t fslabel_size)
{
wchar_t conv_buf[CONV_MAX];
@ -1961,6 +1961,33 @@ int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_har
*free_space = total_free_bytes.QuadPart;
}
if (fstype && fslabel) {
wchar_t volume_root[MAX_PATH];
wchar_t fs_name[MAX_PATH];
wchar_t vol_name[MAX_PATH];
fstype[0] = 0;
fslabel[0] = 0;
if (GetVolumePathNameW(convert(conv_buf, path), volume_root, MAX_PATH)) {
if (GetVolumeInformationW(volume_root, vol_name, MAX_PATH, 0, 0, 0, fs_name, MAX_PATH)) {
char u8[CONV_MAX];
size_t len;
u16tou8ex(u8, fs_name, wcslen(fs_name), &len);
if (len + 1 <= fstype_size) {
memcpy(fstype, u8, len);
fstype[len] = 0;
}
u16tou8ex(u8, vol_name, wcslen(vol_name), &len);
if (len + 1 <= fslabel_size) {
memcpy(fslabel, u8, len);
fslabel[len] = 0;
}
}
}
}
return 0;
}

View file

@ -357,7 +357,7 @@ int filephy(const char* path, uint64_t size, uint64_t* physical);
* Check if the underline file-system support persistent inodes.
* Return -1 on error, 0 on success.
*/
int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space);
int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space, char* fstype, size_t fstype_size, char* fslabel, size_t fslabel_size);
/**
* Get the tick counter value.

View file

@ -1575,7 +1575,7 @@ static void* scan_disk(void* arg)
uint64_t start;
/* check if the disk supports persistent inodes */
ret = fsinfo(disk->dir, &has_persistent_inodes, &has_syncronized_hardlinks, 0, 0);
ret = fsinfo(disk->dir, &has_persistent_inodes, &has_syncronized_hardlinks, 0, 0, 0, 0, 0, 0);
if (ret < 0) {
/* LCOV_EXCL_START */
log_fatal("Error accessing disk '%s' to get file-system info. %s.\n", disk->dir, strerror(errno));

View file

@ -151,6 +151,8 @@ void state_init(struct snapraid_state* state)
for (s = 0; s < SPLIT_MAX; ++s) {
state->parity[l].split_map[s].path[0] = 0;
state->parity[l].split_map[s].uuid[0] = 0;
state->parity[l].split_map[s].fstype[0] = 0;
state->parity[l].split_map[s].fslabel[0] = 0;
state->parity[l].split_map[s].size = PARITY_SIZE_INVALID;
state->parity[l].split_map[s].device = 0;
}
@ -1683,7 +1685,7 @@ void state_refresh(struct snapraid_state* state)
/* LCOV_EXCL_STOP */
}
ret = fsinfo(disk->dir, 0, 0, &total_space, &free_space);
ret = fsinfo(disk->dir, 0, 0, &total_space, &free_space, disk->fstype, sizeof(disk->fstype), disk->fslabel, sizeof(disk->fslabel));
if (ret != 0) {
/* LCOV_EXCL_START */
log_fatal("Error accessing disk '%s' to retrieve file-system info. %s.\n", disk->dir, strerror(errno));
@ -1698,6 +1700,9 @@ void state_refresh(struct snapraid_state* state)
/* also update the disk info */
disk->total_blocks = map->total_blocks;
disk->free_blocks = map->free_blocks;
if (disk->fstype[0])
log_tag("fsinfo_data:%s:%s:%s\n", disk->name, disk->fstype, disk->fslabel);
}
/* for all parities */
@ -1707,14 +1712,15 @@ void state_refresh(struct snapraid_state* state)
state->parity[l].free_blocks = 0;
for (s = 0; s < state->parity[l].split_mac; ++s) {
struct snapraid_split* split = &state->parity[l].split_map[s];
uint64_t total_space;
uint64_t free_space;
int ret;
ret = fsinfo(state->parity[l].split_map[s].path, 0, 0, &total_space, &free_space);
ret = fsinfo(split->path, 0, 0, &total_space, &free_space, split->fstype, sizeof(split->fstype), split->fslabel, sizeof(split->fslabel));
if (ret != 0) {
/* LCOV_EXCL_START */
log_fatal("Error accessing file '%s' to retrieve file-system info. %s.\n", state->parity[l].split_map[s].path, strerror(errno));
log_fatal("Error accessing file '%s' to retrieve file-system info. %s.\n", split->path, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
@ -1722,6 +1728,13 @@ void state_refresh(struct snapraid_state* state)
/* add the new free blocks */
state->parity[l].total_blocks += total_space / state->block_size;
state->parity[l].free_blocks += free_space / state->block_size;
if (split->fstype[0]) {
if (s == 0)
log_tag("fsinfo_parity:%s:%s:%s\n", lev_config_name(l), split->fstype, split->fslabel);
else
log_tag("fsinfo_parity:%s/%u:%s:%s\n", lev_config_name(l), s, split->fstype, split->fslabel);
}
}
}

View file

@ -596,6 +596,44 @@ static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size)
}
#endif
/**
* Get the LABEL using libblkid.
* It uses a cache to work without root permission, resulting in LABEL
* not necessarily recent.
*/
#if HAVE_BLKID
static int devuuid_label(uint64_t device, char* label, size_t label_size)
{
char* devname;
char* labelname;
devname = blkid_devno_to_devname(device);
if (!devname) {
log_tag("label:blkid:%u:%u: blkid_devno_to_devname() failed, %s\n", major(device), minor(device), strerror(errno));
/* device mapping failed */
return -1;
}
labelname = blkid_get_tag_value(cache, "LABEL", devname);
if (!labelname) {
log_tag("label:blkid:%u:%u: blkid_get_tag_value(LABEL,%s) failed, %s\n", major(device), minor(device), devname, strerror(errno));
free(devname);
/* label mapping failed */
return -1;
}
pathcpy(label, label_size, labelname);
log_tag("label:blkid:%u:%u:%s: found %s\n", major(device), minor(device), label, devname);
free(devname);
free(labelname);
return 0;
}
#endif
#ifdef __APPLE__
static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size)
{
@ -818,11 +856,203 @@ int filephy(const char* path, uint64_t size, uint64_t* physical)
return 0;
}
int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space)
{
char type[64];
const char* ptype;
/* from man statfs */
#define ADFS_SUPER_MAGIC 0xadf5
#define AFFS_SUPER_MAGIC 0xADFF
#define BDEVFS_MAGIC 0x62646576
#define BEFS_SUPER_MAGIC 0x42465331
#define BFS_MAGIC 0x1BADFACE
#define BINFMTFS_MAGIC 0x42494e4d
#define BTRFS_SUPER_MAGIC 0x9123683E
#define CGROUP_SUPER_MAGIC 0x27e0eb
#define CIFS_MAGIC_NUMBER 0xFF534D42
#define CODA_SUPER_MAGIC 0x73757245
#define COH_SUPER_MAGIC 0x012FF7B7
#define CRAMFS_MAGIC 0x28cd3d45
#define DEBUGFS_MAGIC 0x64626720
#define DEVFS_SUPER_MAGIC 0x1373
#define DEVPTS_SUPER_MAGIC 0x1cd1
#define EFIVARFS_MAGIC 0xde5e81e4
#define EFS_SUPER_MAGIC 0x00414A53
#define EXT_SUPER_MAGIC 0x137D
#define EXT2_OLD_SUPER_MAGIC 0xEF51
#define EXT4_SUPER_MAGIC 0xEF53 /* also ext2/ext3 */
#define FUSE_SUPER_MAGIC 0x65735546
#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
#define HFS_SUPER_MAGIC 0x4244
#define HFSPLUS_SUPER_MAGIC 0x482b
#define HOSTFS_SUPER_MAGIC 0x00c0ffee
#define HPFS_SUPER_MAGIC 0xF995E849
#define HUGETLBFS_MAGIC 0x958458f6
#define ISOFS_SUPER_MAGIC 0x9660
#define JFFS2_SUPER_MAGIC 0x72b6
#define JFS_SUPER_MAGIC 0x3153464a
#define MINIX_SUPER_MAGIC 0x137F
#define MINIX_SUPER_MAGIC2 0x138F
#define MINIX2_SUPER_MAGIC 0x2468
#define MINIX2_SUPER_MAGIC2 0x2478
#define MINIX3_SUPER_MAGIC 0x4d5a
#define MQUEUE_MAGIC 0x19800202
#define MSDOS_SUPER_MAGIC 0x4d44
#define NCP_SUPER_MAGIC 0x564c
#define NFS_SUPER_MAGIC 0x6969
#define NILFS_SUPER_MAGIC 0x3434
#define NTFS_SB_MAGIC 0x5346544e
#define OCFS2_SUPER_MAGIC 0x7461636f
#define OPENPROM_SUPER_MAGIC 0x9fa1
#define PIPEFS_MAGIC 0x50495045
#define PROC_SUPER_MAGIC 0x9fa0
#define PSTOREFS_MAGIC 0x6165676C
#define QNX4_SUPER_MAGIC 0x002f
#define QNX6_SUPER_MAGIC 0x68191122
#define RAMFS_MAGIC 0x858458f6
#define REISERFS_SUPER_MAGIC 0x52654973
#define ROMFS_MAGIC 0x7275
#define SELINUX_MAGIC 0xf97cff8c
#define SMACK_MAGIC 0x43415d53
#define SMB_SUPER_MAGIC 0x517B
#define SOCKFS_MAGIC 0x534F434B
#define SQUASHFS_MAGIC 0x73717368
#define SYSFS_MAGIC 0x62656572
#define SYSV2_SUPER_MAGIC 0x012FF7B6
#define SYSV4_SUPER_MAGIC 0x012FF7B5
#define TMPFS_MAGIC 0x01021994
#define UDF_SUPER_MAGIC 0x15013346
#define UFS_MAGIC 0x00011954
#define USBDEVICE_SUPER_MAGIC 0x9fa2
#define V9FS_MAGIC 0x01021997
#define VXFS_SUPER_MAGIC 0xa501FCF5
#define XENFS_SUPER_MAGIC 0xabba1974
#define XENIX_SUPER_MAGIC 0x012FF7B4
#define XFS_SUPER_MAGIC 0x58465342
#define _XIAFS_SUPER_MAGIC 0x012FD16D
#define AFS_SUPER_MAGIC 0x5346414F
#define AUFS_SUPER_MAGIC 0x61756673
#define ANON_INODE_FS_SUPER_MAGIC 0x09041934
#define CEPH_SUPER_MAGIC 0x00C36400
#define ECRYPTFS_SUPER_MAGIC 0xF15F
#define FAT_SUPER_MAGIC 0x4006
#define FHGFS_SUPER_MAGIC 0x19830326
#define FUSEBLK_SUPER_MAGIC 0x65735546
#define FUSECTL_SUPER_MAGIC 0x65735543
#define GFS_SUPER_MAGIC 0x1161970
#define GPFS_SUPER_MAGIC 0x47504653
#define MTD_INODE_FS_SUPER_MAGIC 0x11307854
#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
#define ISOFS_R_WIN_SUPER_MAGIC 0x4004
#define ISOFS_WIN_SUPER_MAGIC 0x4000
#define JFFS_SUPER_MAGIC 0x07C0
#define KAFS_SUPER_MAGIC 0x6B414653
#define LUSTRE_SUPER_MAGIC 0x0BD00BD0
#define NFSD_SUPER_MAGIC 0x6E667364
#define PANFS_SUPER_MAGIC 0xAAD7AAEA
#define RPC_PIPEFS_SUPER_MAGIC 0x67596969
#define SECURITYFS_SUPER_MAGIC 0x73636673
#define UFS_BYTESWAPPED_SUPER_MAGIC 0x54190100
#define VMHGFS_SUPER_MAGIC 0xBACBACBC
#define VZFS_SUPER_MAGIC 0x565A4653
#define ZFS_SUPER_MAGIC 0x2FC12FC1
struct filesystem_entry {
unsigned id;
const char* name;
int remote;
} FILESYSTEMS[] = {
{ ADFS_SUPER_MAGIC, "adfs", 0 },
{ AFFS_SUPER_MAGIC, "affs", 0 },
{ AFS_SUPER_MAGIC, "afs", 1 },
{ AUFS_SUPER_MAGIC, "aufs", 1 },
{ BEFS_SUPER_MAGIC, "befs", 0 },
{ BDEVFS_MAGIC, "bdevfs", 0 },
{ BFS_MAGIC, "bfs", 0 },
{ BINFMTFS_MAGIC, "binfmt_misc", 0 },
{ BTRFS_SUPER_MAGIC, "btrfs", 0 },
{ CEPH_SUPER_MAGIC, "ceph", 1 },
{ CGROUP_SUPER_MAGIC, "cgroupfs", 0 },
{ CIFS_MAGIC_NUMBER, "cifs", 1 },
{ CODA_SUPER_MAGIC, "coda", 1 },
{ COH_SUPER_MAGIC, "coh", 0 },
{ CRAMFS_MAGIC, "cramfs", 0 },
{ DEBUGFS_MAGIC, "debugfs", 0 },
{ DEVFS_SUPER_MAGIC, "devfs", 0 },
{ DEVPTS_SUPER_MAGIC, "devpts", 0 },
{ ECRYPTFS_SUPER_MAGIC, "ecryptfs", 0 },
{ EFS_SUPER_MAGIC, "efs", 0 },
{ EXT_SUPER_MAGIC, "ext", 0 },
{ EXT4_SUPER_MAGIC, "ext4", 0 },
{ EXT2_OLD_SUPER_MAGIC, "ext2", 0 },
{ FAT_SUPER_MAGIC, "fat", 0 },
{ FHGFS_SUPER_MAGIC, "fhgfs", 1 },
{ FUSEBLK_SUPER_MAGIC, "fuseblk", 1 },
{ FUSECTL_SUPER_MAGIC, "fusectl", 1 },
{ FUTEXFS_SUPER_MAGIC, "futexfs", 0 },
{ GFS_SUPER_MAGIC, "gfs/gfs2", 1 },
{ GPFS_SUPER_MAGIC, "gpfs", 1 },
{ HFS_SUPER_MAGIC, "hfs", 0 },
{ HFSPLUS_SUPER_MAGIC, "hfsplus", 0 },
{ HPFS_SUPER_MAGIC, "hpfs", 0 },
{ HUGETLBFS_MAGIC, "hugetlbfs", 0 },
{ MTD_INODE_FS_SUPER_MAGIC, "inodefs", 0 },
{ INOTIFYFS_SUPER_MAGIC, "inotifyfs", 0 },
{ ISOFS_SUPER_MAGIC, "isofs", 0 },
{ ISOFS_R_WIN_SUPER_MAGIC, "isofs", 0 },
{ ISOFS_WIN_SUPER_MAGIC, "isofs", 0 },
{ JFFS_SUPER_MAGIC, "jffs", 0 },
{ JFFS2_SUPER_MAGIC, "jffs2", 0 },
{ JFS_SUPER_MAGIC, "jfs", 0 },
{ KAFS_SUPER_MAGIC, "k-afs", 1 },
{ LUSTRE_SUPER_MAGIC, "lustre", 1 },
{ MINIX_SUPER_MAGIC, "minix", 0 },
{ MINIX_SUPER_MAGIC2, "minix", 0 },
{ MINIX2_SUPER_MAGIC, "minix2", 0 },
{ MINIX2_SUPER_MAGIC2, "minix2", 0 },
{ MINIX3_SUPER_MAGIC, "minix3", 0 },
{ MQUEUE_MAGIC, "mqueue", 0 },
{ MSDOS_SUPER_MAGIC, "msdos", 0 },
{ NCP_SUPER_MAGIC, "novell", 1 },
{ NFS_SUPER_MAGIC, "nfs", 1 },
{ NFSD_SUPER_MAGIC, "nfsd", 1 },
{ NILFS_SUPER_MAGIC, "nilfs", 0 },
{ NTFS_SB_MAGIC, "ntfs", 0 },
{ OPENPROM_SUPER_MAGIC, "openprom", 0 },
{ OCFS2_SUPER_MAGIC, "ocfs2", 1 },
{ PANFS_SUPER_MAGIC, "panfs", 1 },
{ PIPEFS_MAGIC, "pipefs", 1 },
{ PROC_SUPER_MAGIC, "proc", 0 },
{ PSTOREFS_MAGIC, "pstorefs", 0 },
{ QNX4_SUPER_MAGIC, "qnx4", 0 },
{ QNX6_SUPER_MAGIC, "qnx6", 0 },
{ RAMFS_MAGIC, "ramfs", 0 },
{ REISERFS_SUPER_MAGIC, "reiserfs", 0 },
{ ROMFS_MAGIC, "romfs", 0 },
{ RPC_PIPEFS_SUPER_MAGIC, "rpc_pipefs", 0 },
{ SECURITYFS_SUPER_MAGIC, "securityfs", 0 },
{ SELINUX_MAGIC, "selinux", 0 },
{ SMB_SUPER_MAGIC, "smb", 1 },
{ SOCKFS_MAGIC, "sockfs", 0 },
{ SQUASHFS_MAGIC, "squashfs", 0 },
{ SYSFS_MAGIC, "sysfs", 0 },
{ SYSV2_SUPER_MAGIC, "sysv2", 0 },
{ SYSV4_SUPER_MAGIC, "sysv4", 0 },
{ TMPFS_MAGIC, "tmpfs", 0 },
{ UDF_SUPER_MAGIC, "udf", 0 },
{ UFS_MAGIC, "ufs", 0 },
{ UFS_BYTESWAPPED_SUPER_MAGIC, "ufs", 0 },
{ USBDEVICE_SUPER_MAGIC, "usbdevfs", 0 },
{ V9FS_MAGIC, "v9fs", 0 },
{ VMHGFS_SUPER_MAGIC, "vmhgfs", 1 },
{ VXFS_SUPER_MAGIC, "vxfs", 0 },
{ VZFS_SUPER_MAGIC, "vzfs", 0 },
{ XENFS_SUPER_MAGIC, "xenfs", 0 },
{ XENIX_SUPER_MAGIC, "xenix", 0 },
{ XFS_SUPER_MAGIC, "xfs", 0 },
{ _XIAFS_SUPER_MAGIC, "xia", 0 },
{ ZFS_SUPER_MAGIC, "zfs", 0 },
{ 0 }
};
int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space, char* fstype, size_t fstype_size, char* fslabel, size_t fslabel_size)
{
#if HAVE_STATFS
struct statfs st;
@ -857,8 +1087,8 @@ int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_har
if (has_persistent_inode) {
#if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
switch (st.f_type) {
case 0x65735546 : /* FUSE, "fuseblk" in the stat command */
case 0x4d44 : /* VFAT, "msdos" in the stat command */
case FUSEBLK_SUPER_MAGIC : /* FUSE, "fuseblk" in the stat command */
case MSDOS_SUPER_MAGIC : /* VFAT, "msdos" in the stat command */
*has_persistent_inode = 0;
break;
default :
@ -875,8 +1105,8 @@ int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_har
if (has_syncronized_hardlinks) {
#if HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
switch (st.f_type) {
case 0x5346544E : /* NTFS */
case 0x4d44 : /* VFAT, "msdos" in the stat command */
case NTFS_SB_MAGIC : /* NTFS */
case MSDOS_SUPER_MAGIC : /* VFAT, "msdos" in the stat command */
*has_syncronized_hardlinks = 0;
break;
default :
@ -906,36 +1136,38 @@ int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_har
#endif
}
const char* ptype = 0;
#if HAVE_STATFS && HAVE_STRUCT_STATFS_F_FSTYPENAME
/* get the filesystem type directly from the struct (Mac OS X) */
(void)type;
ptype = st.f_fstypename;
#elif HAVE_STATFS && HAVE_STRUCT_STATFS_F_TYPE
/* get the filesystem type from f_type (Linux) */
/* from: https://github.com/influxdata/gopsutil/blob/master/disk/disk_linux.go */
switch (st.f_type) {
case 0x65735546 : ptype = "fuseblk"; break;
case 0x4D44 : ptype = "vfat/msdos"; break;
case 0xEF53 : ptype = "ext2/3/4"; break;
case 0x6969 : ptype = "nfs"; break; /* remote */
case 0x6E667364 : ptype = "nfsd"; break; /* remote */
case 0x517B : ptype = "smb"; break; /* remote */
case 0x5346544E : ptype = "ntfs"; break;
case 0x52654973 : ptype = "reiserfs"; break;
case 0x3153464A : ptype = "jfs"; break;
case 0x58465342 : ptype = "xfs"; break;
case 0x9123683E : ptype = "btrfs"; break;
case 0x2FC12FC1 : ptype = "zfs"; break;
default :
snprintf(type, sizeof(type), "0x%X", (unsigned)st.f_type);
ptype = type;
for (int i = 0; FILESYSTEMS[i].id != 0; ++i) {
if (st.f_type == FILESYSTEMS[i].id) {
ptype = FILESYSTEMS[i].name;
break;
}
}
#else
(void)type;
ptype = "unknown";
#endif
log_tag("statfs:%s: %s \n", ptype, path);
if (fstype) {
fstype[0] = 0;
if (ptype)
snprintf(fstype, fstype_size, "%s", ptype);
}
if (fslabel) {
fslabel[0] = 0;
#if HAVE_BLKID
struct stat fst;
if (stat(path, &fst) == 0)
devuuid_label(fst.st_dev, fslabel, fslabel_size);
#else
(void)fslabel_size;
#endif
}
return 0;
}

View file

@ -130,6 +130,32 @@ The UUID of the filesystem containing the path.
.PD
.RE
.TP
.B fsinfo_data:<disk_name>:<type>:<label>
The filesystem information of the specified data disk.
.RS 4
.PD 0
.HP 4
.I <type>
The filesystem type. A string like \`ext4\`, \`ntfs\`.
.HP 4
.I <label>
The label associated to the filesystem.
.PD
.RE
.TP
.B fstype_parity]:<parity_level>[/<split_index>]:<type>:<label>
The filesystem information of the specified parity disk.
.RS 4
.PD 0
.HP 4
.I <type>
The filesystem type. A string like \`ext4\`, \`ntfs\`.
.HP 4
.I <label>
The label associated to the filesystem.
.PD
.RE
.TP
.B pool:<dir>
The configured dir to the pool mount point (escaped).
This is the optional mount point for the \'pool\' feature.
@ -1613,6 +1639,16 @@ The disk\'s model identifier (escaped).
.PD
.RE
.TP
.B attr:<device_file>:<disk_name>[/<split_index>]:interface:<interface>
Logs the disk\'s interface. Something like \`USB\`, \`SATA\`, \`NVMe\`.
.RS 4
.PD 0
.HP 4
.I <interface>
The disk\'s interface (escaped).
.PD
.RE
.TP
.B attr:<device_file>:<disk_name>[/<split_index>]:afr:<afr>:<prob>
Logs the estimated Annual Failure Rate (AFR) and the
probability of at least one failure in the next year based on

View file

@ -93,6 +93,18 @@ Configuration Tags
<path> - The path (escaped).
<uuid> - The UUID of the filesystem containing the path.
=fsinfo_data:<disk_name>:<type>:<label>
The filesystem information of the specified data disk.
<type> - The filesystem type. A string like `ext4`, `ntfs`.
<label> - The label associated to the filesystem.
=fstype_parity]:<parity_level>[/<split_index>]:<type>:<label>
The filesystem information of the specified parity disk.
<type> - The filesystem type. A string like `ext4`, `ntfs`.
<label> - The label associated to the filesystem.
=pool:<dir>
The configured dir to the pool mount point (escaped).
This is the optional mount point for the 'pool' feature.
@ -120,7 +132,7 @@ Content Tags
The absolute path to a content file being used (escaped).
Content files store the metadata (like file hashes and timestamps)
for the array.
=content_write:<path>
The absolute path to a content file being written (escaped).
You will see multiple writes as the content file is saved in
@ -275,7 +287,7 @@ Scan Tags
=summary:exit:<status>
Logs the overall exit status of the command. The `status` is
one of the following:
equal - Indicates that no differences were found.
The array is already synchronized.
diff - Indicates that differences were found.
@ -288,7 +300,7 @@ General Progress and Execution Tags
=run:begin:<blockbegin>:<blockend>:<count>
A tag indicating the start of the command execution.
<blockbegin> - Starting block index (uint).
<blockend> - Ending block index + 1 (uint).
<count> - Number of blocks to process. It may be less
@ -359,7 +371,7 @@ Thermal Tags
Logs a temperature reading from a connected disk that is being
considered as a candidate for determining the ambient system
temperature.
<temp> - The current temperature read from the disk
(uint, degrees Celsius).
@ -386,7 +398,7 @@ Thermal Tags
Logs the highest temperature observed among all monitored disks
in the current measurement cycle. This is used for thermal
throttling.
<temp> - The highest temperature observed in degrees Celsius.
=thermal:heat:<disk_name>[/<split_index>]:<device>:<count>:<data_points>
@ -405,14 +417,14 @@ Thermal Tags
=thermal:params:<disk_name>[/<split_index>]:<device>:<k_heat>:<t_ambient>:<t_steady>:<rmse>:<r_squared>:<max_error>
Logs the estimated parameters for the exponential heating model
(fit using least squares) and associated quality metrics for a
specific disk.
specific disk.
The model is: T(t) = T_steady - (T_steady - T_0) e^(-kt),
where T_0 is the initial temperature.
<device> - The unique device ID (uint).
<k_heat> - The heating rate constant, k (float).
<t_ambient> - The ambient temperature, T_ambient (float).
<t_steady> - The estimated steady-state temperature, T_steady (float),
<t_steady> - The estimated steady-state temperature, T_steady (float),
which is the maximum expected temperature of the disk.
<rmse> - Root Mean Square Error of the fit (float).
<r_squared> - Coefficient of determination (R^2) of the fit (float).
@ -630,9 +642,9 @@ Command Status Tags
<new> - Count of newly synced (unscrubbed) blocks in that day range.
Command Sync/Scrub Tags
Tags specific for the `sync` and `scrub` commands.
Tags specific for the `sync` and `scrub` commands.
Also the error tags are possible.
Summary Tags
These tags provide summary statistics at the end of the command.
@ -647,20 +659,20 @@ Command Sync/Scrub Tags
=summary:error_soft:<count>
Logs the total count of file-related errors encountered during
the process (e.g., missing files, file attribute changes).
<count> - The total number of file errors encountered (uint).
=summary:error_io:<count>
Logs the total count of input/output errors encountered on
data or parity disks.
<count> - The total number of I/O errors encountered (uint).
=summary:error_data:<count>
Logs the total count of `silent data errors` (data blocks
not matching their expected hash) encountered during the sync
process.
<count> - The total number of silent data errors encountered (uint).
=summary:exit:<status>
@ -681,7 +693,7 @@ Command Check/Fix Tags
Fixed/Recovered Tags
These tags log successful repairs during fix operations.
=fixed:<block_pos>:<disk_name>:<file_path>:<msg>
Indicates that a file was successfully fixed using parity data.
@ -718,7 +730,7 @@ Command Check/Fix Tags
=symlink_fixed:<disk_name>:<link_path>:<msg>
Logs successful recreation of a symbolic link during fix operation.
<disk_name> - The name of the disk.
<link_path> - The symlink path relative to disk root (escaped).
<msg> - A descriptive message indicating the nature of the fix
@ -735,7 +747,7 @@ Command Check/Fix Tags
Unrecoverable Error Tags
These tags log errors that could not be recovered.
=unrecoverable:<block_pos>:<disk_name>:<file_path>:<msg>
Indicates that a block error could not be fixed due to
insufficient parity or other recovery limitations.
@ -766,10 +778,10 @@ Command Check/Fix Tags
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
=status:recovered:<disk_name>:<file_path>
Logs that a file was successfully recovered during fix operation.
<disk_name> - The name of the disk.
<file_path> - The file path relative to disk root (escaped).
@ -788,31 +800,31 @@ Command Check/Fix Tags
Summary Tags
These tags provide summary statistics at the end of the command.
=summary:error_soft:<count>
Logs the total count of file-related errors encountered during
the process (e.g., missing files, file attribute changes).
<count> - The total number of file errors encountered (uint).
=summary:error_io:<count>
Logs the total count of input/output errors encountered on
data or parity disks.
<count> - The total number of I/O errors encountered (uint).
=summary:error_data:<count>
Logs the total count of `silent data errors` (data blocks
not matching their expected hash) encountered during the sync
process.
<count> - The total number of silent data errors encountered (uint).
=summary:error_recovered:<recovered_count>
Logs the total number of errors successfully recovered (fix).
<recovered_count> - Number of recovered errors (uint).
=summary:error_recoverable:<recoverable_count>
Logs the total number of errors that can be recovered (check).
@ -820,7 +832,7 @@ Command Check/Fix Tags
=summary:error_unrecoverable:<unrecoverable_count>
Logs the total number of unrecoverable errors (fix/check).
<unrecoverable_count> - Number of unrecoverable errors (uint).
=summary:exit:<status>
@ -966,7 +978,7 @@ Command Rehash Tags
=summary:exit:<status>
Logs the overall exit status of the command. The `status` is one of
the following:
scheduled - Indicates that a rehash operation has
been successfully scheduled. The rehash will be performed
incrementally in future `sync` or `scrub` commands.
@ -987,8 +999,8 @@ Command Smart And Probe Tags
Note that a `<disk_name>` may be associated with more `<device_file>`,
in case the logical disk uses more physical disks. In such a case,
you'll see multiple `<attr>` and `<smart>` tags for the same
`<disk_name>` but with different `<device_file>`. The exception is the
you'll see multiple `<attr>` and `<smart>` tags for the same
`<disk_name>` but with different `<device_file>`. The exception is the
`stat` attrbute that is cumulative for all the devices part of the
disk.
@ -1022,6 +1034,11 @@ Command Smart And Probe Tags
<model> - The disk's model identifier (escaped).
=attr:<device_file>:<disk_name>[/<split_index>]:interface:<interface>
Logs the disk's interface. Something like `USB`, `SATA`, `NVMe`.
<interface> - The disk's interface (escaped).
=attr:<device_file>:<disk_name>[/<split_index>]:afr:<afr>:<prob>
Logs the estimated Annual Failure Rate (AFR) and the
probability of at least one failure in the next year based on
@ -1072,7 +1089,7 @@ Command Smart And Probe Tags
=attr:<device_file>:<disk_name>[/<split_index>]:rotationrate:<rate>
Logs the disk's rotation rate.
<rate> - The rotation rate. A value of 0 indicates a
<rate> - The rotation rate. A value of 0 indicates a
solid-state drive (SSD) or other non-rotating medium.
A value of 1 indicates a rotational disk of unknown
precise speed. Values greater than 1 indicate the
@ -1080,9 +1097,9 @@ Command Smart And Probe Tags
=attr:<device_file>:<disk_name>[/<split_index>]:flags:<flags_decimal>:<flags_hex>
Logs the SMART status flags from the `smartctl` utility.
Per the smartctl manpage, these flags are bit-mapped
to indicate specific issues like `Command line did not parse`,
`Device could not be opened`, or `SMART status check
Per the smartctl manpage, these flags are bit-mapped
to indicate specific issues like `Command line did not parse`,
`Device could not be opened`, or `SMART status check
returned 'DISK FAILING'`.
<flags_decimal> - The raw flags value (uint, decimal).
@ -1096,7 +1113,7 @@ Command Smart And Probe Tags
<value_hex> - The raw attribute value (uint, hexadecimal).
=attr:<device_file>:<disk_name>[/<split_index>]:power:active
Logs that the device was confirmed to be in an active power
Logs that the device was confirmed to be in an active power
state after a status probe.
=attr:<device_file>:<disk_name>[/<split_index>]:power:standby
@ -1104,11 +1121,11 @@ Command Smart And Probe Tags
state.
=attr:<device_file>:<disk_name>[/<split_index>]:power:up
Logs a successful spin-up operation via direct O_DIRECT
Logs a successful spin-up operation via direct O_DIRECT
read.
=attr:<device_file>:<disk_name>[/<split_index>]:power:down
Logs a successful spin-down operation initiated via the
Logs a successful spin-down operation initiated via the
smartctl command.
=stat:<disk_name>:<access_number>
@ -1148,22 +1165,22 @@ Device Status Tags
=device:<device_file>:<disk_name>[/<split_index>]:error:<errno>
Logs a low-level system error during direct file operations.
This is triggered when open(), read(), or close()
This is triggered when open(), read(), or close()
calls fail during a spin-up attempt.
<errno> - The standard integer error number provided by
<errno> - The standard integer error number provided by
the OS.
=device:<device_file>:<disk_name>[/<split_index>]:error:abort
Logs that an external process (smartctl) failed to complete
normally, such as being terminated by a signal rather than
Logs that an external process (smartctl) failed to complete
normally, such as being terminated by a signal rather than
exiting.
=device:<device_file>:<disk_name>[/<split_index>]:exit:<exit_code>
Logs that the external command (smartctl) returned a non-zero
exit code that was not explicitly recognized as a valid state.
Logs that the external command (smartctl) returned a non-zero
exit code that was not explicitly recognized as a valid state.
<exit_code> - The integer exit status returned by the
<exit_code> - The integer exit status returned by the
process (int).
Error Tags
@ -1173,9 +1190,9 @@ Error Tags
=error[_io|_data]:<block>:<disk_name>:<file>:<msg>
Logs file access errors (open, read, file changed) during the
data disk read operation for parity calculation or verification.
_io - Indicates a physical Input/Output error.
The disk was unable to read or write a specific block,
The disk was unable to read or write a specific block,
typically signaling a failing sector or cable issue.
_data - Indicates the data was read successfully but failed
the checksum/hash verification. This signals `silent`
@ -1190,9 +1207,9 @@ Error Tags
=parity_error[_io|_data]:<block>:<level>:<msg>
Logs errors during parity disk read or write operations.
_io - Indicates a physical Input/Output error.
The disk was unable to read or write a specific block,
_io - Indicates a physical Input/Output error.
The disk was unable to read or write a specific block,
typically signaling a failing sector or cable issue.
_data - Indicates the data was read successfully but failed
the checksum/hash verification. This signals `silent`
@ -1227,7 +1244,7 @@ Error Tags
=dir_error[_io]:<disk_name>:<dir_path>:<msg>
Indicates an error when attempting to access a directory.
<disk_name> - The name of the disk.
<dir_path> - The directory path relative to disk root (escaped).
<msg> - A descriptive message indicating the nature of the

View file

@ -100,6 +100,18 @@ These tags report the memory usage and global configuration.
<path> - The path (escaped).
<uuid> - The UUID of the filesystem containing the path.
fsinfo_data:<disk_name>:<type>:<label>
The filesystem information of the specified data disk.
<type> - The filesystem type. A string like `ext4`, `ntfs`.
<label> - The label associated to the filesystem.
fstype_parity]:<parity_level>[/<split_index>]:<type>:<label>
The filesystem information of the specified parity disk.
<type> - The filesystem type. A string like `ext4`, `ntfs`.
<label> - The label associated to the filesystem.
pool:<dir>
The configured dir to the pool mount point (escaped).
This is the optional mount point for the 'pool' feature.
@ -1068,6 +1080,11 @@ Tags logging specific disk identification and attribute values.
<model> - The disk's model identifier (escaped).
attr:<device_file>:<disk_name>[/<split_index>]:interface:<interface>
Logs the disk's interface. Something like `USB`, `SATA`, `NVMe`.
<interface> - The disk's interface (escaped).
attr:<device_file>:<disk_name>[/<split_index>]:afr:<afr>:<prob>
Logs the estimated Annual Failure Rate (AFR) and the
probability of at least one failure in the next year based on