Pino Toscano
2015-Jan-14 12:14 UTC
[Libguestfs] [PATCH] daemon: use btrfs(1) to get btrfs labels
blkid(1) (or actually, libblkid) seems to handle file system labels up to 127 characters. Considering that btrfs labels can be up to 255 characters, this means long labels are not read correctly (i.e. get truncated) by blkid. Get the file system type, and if btrfs is available invoke `btrfs filesystem` to get the label of btrfs file systems. --- daemon/blkid.c | 6 ++++++ daemon/btrfs.c | 24 ++++++++++++++++++++++++ daemon/daemon.h | 3 +++ 3 files changed, 33 insertions(+) diff --git a/daemon/blkid.c b/daemon/blkid.c index b98c155..2c9e2f1 100644 --- a/daemon/blkid.c +++ b/daemon/blkid.c @@ -26,6 +26,7 @@ #include "daemon.h" #include "actions.h" +#include "optgroups.h" GUESTFSD_EXT_CMD(str_blkid, blkid); @@ -76,6 +77,11 @@ do_vfs_type (const mountable_t *mountable) char * do_vfs_label (const mountable_t *mountable) { + CLEANUP_FREE char *type = do_vfs_type (mountable); + + if (type && STREQ (type, "btrfs") && optgroup_btrfs_available ()) + return btrfs_get_label (mountable->device); + return get_blkid_tag (mountable->device, "LABEL"); } diff --git a/daemon/btrfs.c b/daemon/btrfs.c index 150c089..cf1507d 100644 --- a/daemon/btrfs.c +++ b/daemon/btrfs.c @@ -44,6 +44,30 @@ optgroup_btrfs_available (void) return prog_exists (str_btrfs) && filesystem_available ("btrfs") > 0; } +char * +btrfs_get_label (const char *device) +{ + int r; + CLEANUP_FREE char *err = NULL; + char *out = NULL; + size_t len; + + r = command (&out, &err, str_btrfs, "filesystem", "label", + device, NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + return NULL; + } + + /* Trim trailing \n if present. */ + len = strlen (out); + if (len > 0 && out[len-1] == '\n') + out[len-1] = '\0'; + + return out; +} + /* Takes optional arguments, consult optargs_bitmask. */ int do_btrfs_filesystem_resize (const char *filesystem, int64_t size) diff --git a/daemon/daemon.h b/daemon/daemon.h index c101c3b..cf123bf 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -232,6 +232,9 @@ extern void wipe_device_before_mkfs (const char *device); extern void aug_read_version (void); extern void aug_finalize (void); +/*-- in btrfs.c --*/ +extern char *btrfs_get_label (const char *device); + /* The version of augeas, saved as: * (MAJOR << 16) | (MINOR << 8) | PATCH */ -- 1.9.3
Pino Toscano
2015-Jan-15 13:39 UTC
[Libguestfs] [PATCH 1/2] daemon: use btrfs(1) to get btrfs labels
blkid(1) (or actually, libblkid) seems to handle filesystem labels up to 127 characters. Considering that btrfs labels can be up to 255 characters, this means long labels are not read correctly (i.e. get truncated) by blkid. Get the filesystem type, and if btrfs is available invoke `btrfs filesystem` to get the label of btrfs filesystems. Related to RHBZ#1164708. --- daemon/blkid.c | 8 ++++++++ daemon/btrfs.c | 24 ++++++++++++++++++++++++ daemon/daemon.h | 3 +++ 3 files changed, 35 insertions(+) diff --git a/daemon/blkid.c b/daemon/blkid.c index b98c155..e8e7b58 100644 --- a/daemon/blkid.c +++ b/daemon/blkid.c @@ -26,6 +26,7 @@ #include "daemon.h" #include "actions.h" +#include "optgroups.h" GUESTFSD_EXT_CMD(str_blkid, blkid); @@ -76,6 +77,13 @@ do_vfs_type (const mountable_t *mountable) char * do_vfs_label (const mountable_t *mountable) { + CLEANUP_FREE char *type = do_vfs_type (mountable); + + if (type) { + if (STREQ (type, "btrfs") && optgroup_btrfs_available ()) + return btrfs_get_label (mountable->device); + } + return get_blkid_tag (mountable->device, "LABEL"); } diff --git a/daemon/btrfs.c b/daemon/btrfs.c index 150c089..cf1507d 100644 --- a/daemon/btrfs.c +++ b/daemon/btrfs.c @@ -44,6 +44,30 @@ optgroup_btrfs_available (void) return prog_exists (str_btrfs) && filesystem_available ("btrfs") > 0; } +char * +btrfs_get_label (const char *device) +{ + int r; + CLEANUP_FREE char *err = NULL; + char *out = NULL; + size_t len; + + r = command (&out, &err, str_btrfs, "filesystem", "label", + device, NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + return NULL; + } + + /* Trim trailing \n if present. */ + len = strlen (out); + if (len > 0 && out[len-1] == '\n') + out[len-1] = '\0'; + + return out; +} + /* Takes optional arguments, consult optargs_bitmask. */ int do_btrfs_filesystem_resize (const char *filesystem, int64_t size) diff --git a/daemon/daemon.h b/daemon/daemon.h index c101c3b..4ee1a40 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -262,6 +262,9 @@ extern char *debug_bmap (const char *subcmd, size_t argc, char *const *const arg extern char *debug_bmap_file (const char *subcmd, size_t argc, char *const *const argv); extern char *debug_bmap_device (const char *subcmd, size_t argc, char *const *const argv); +/*-- in btrfs.c --*/ +extern char *btrfs_get_label (const char *device); + /* ordinary daemon functions use these to indicate errors * NB: you don't need to prefix the string with the current command, * it is added automatically by the client-side RPC stubs. -- 1.9.3
Pino Toscano
2015-Jan-15 13:39 UTC
[Libguestfs] [PATCH 2/2] daemon: use ntfslabel(1) to get ntfs labels
blkid(1) (or actually, libblkid) seems to handle filesystem labels up to 127 characters. Considering that btrfs labels can be up to 128 characters, this means long labels are not read correctly (i.e. get truncated) by blkid. Furthermore, ntfs labels are actually unicode, and libblkid seems to not decode them correctly. Hence, if ntfsprogs is available invoke `ntfslabel` to get the label of ntfs filesystems. Related to RHBZ#1164708. --- daemon/blkid.c | 2 ++ daemon/daemon.h | 3 +++ daemon/ntfs.c | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/daemon/blkid.c b/daemon/blkid.c index e8e7b58..1ac42b4 100644 --- a/daemon/blkid.c +++ b/daemon/blkid.c @@ -82,6 +82,8 @@ do_vfs_label (const mountable_t *mountable) if (type) { if (STREQ (type, "btrfs") && optgroup_btrfs_available ()) return btrfs_get_label (mountable->device); + if (STREQ (type, "ntfs") && optgroup_ntfsprogs_available ()) + return ntfs_get_label (mountable->device); } return get_blkid_tag (mountable->device, "LABEL"); diff --git a/daemon/daemon.h b/daemon/daemon.h index 4ee1a40..9405ce6 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -265,6 +265,9 @@ extern char *debug_bmap_device (const char *subcmd, size_t argc, char *const *co /*-- in btrfs.c --*/ extern char *btrfs_get_label (const char *device); +/*-- in ntfs.c --*/ +extern char *ntfs_get_label (const char *device); + /* ordinary daemon functions use these to indicate errors * NB: you don't need to prefix the string with the current command, * it is added automatically by the client-side RPC stubs. diff --git a/daemon/ntfs.c b/daemon/ntfs.c index 762ca88..f1d12e0 100644 --- a/daemon/ntfs.c +++ b/daemon/ntfs.c @@ -33,6 +33,7 @@ GUESTFSD_EXT_CMD(str_ntfs3g_probe, ntfs-3g.probe); GUESTFSD_EXT_CMD(str_ntfsresize, ntfsresize); GUESTFSD_EXT_CMD(str_ntfsfix, ntfsfix); +GUESTFSD_EXT_CMD(str_ntfslabel, ntfslabel); int optgroup_ntfs3g_available (void) @@ -46,6 +47,29 @@ optgroup_ntfsprogs_available (void) return prog_exists (str_ntfsresize); } +char * +ntfs_get_label (const char *device) +{ + int r; + CLEANUP_FREE char *err = NULL; + char *out = NULL; + size_t len; + + r = command (&out, &err, str_ntfslabel, device, NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + return NULL; + } + + /* Trim trailing \n if present. */ + len = strlen (out); + if (len > 0 && out[len-1] == '\n') + out[len-1] = '\0'; + + return out; +} + int do_ntfs_3g_probe (int rw, const char *device) { -- 1.9.3