From d1711dae9dbd7f516469f88807604894c1304228 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 27 Feb 2012 14:05:38 +0000 Subject: New API: set-label, for setting a label on any filesystem. Currently only ext2/3/4 and (newly) NTFS are supported. This change also deprecates set-e2label. --- TODO | 4 -- daemon/Makefile.am | 1 + daemon/daemon.h | 3 + daemon/ext2.c | 26 +------- daemon/labels.c | 100 ++++++++++++++++++++++++++++++ generator/generator_actions.ml | 28 ++++++++- po/POTFILES.in | 1 + src/MAX_PROC_NR | 2 +- tests/guests/guest-aux/make-debian-img.sh | 2 +- tests/guests/guest-aux/make-fedora-img.pl | 4 +- tests/guests/guest-aux/make-ubuntu-img.sh | 2 +- 11 files changed, 137 insertions(+), 36 deletions(-) create mode 100644 daemon/labels.c diff --git a/TODO b/TODO index 9dafb4d3..499c3454 100644 --- a/TODO +++ b/TODO @@ -381,10 +381,6 @@ More ntfs tools ntfsprogs actually has a lot more useful tools than we currently use. Interesting ones are: -ntfslabel: display or change filesystem label (we should unify all - set*label APIs into a single set_vfs_label which can deal with any - filesystem) - ntfscluster: display file(s) that occupy a cluster or sector ntfsinfo: print various information about NTFS volume and files diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 2dd8149f..74d24fcf 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -125,6 +125,7 @@ guestfsd_SOURCES = \ inotify.c \ internal.c \ is.c \ + labels.c \ link.c \ ls.c \ luks.c \ diff --git a/daemon/daemon.h b/daemon/daemon.h index c92e1108..c45a7fe1 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -132,6 +132,9 @@ extern int sync_disks (void); /*-- in ext2.c --*/ extern int e2prog (char *name); /* Massive hack for RHEL 5. */ +/* Confirmed this is true up to ext4 from the Linux sources. */ +#define EXT2_LABEL_MAX 16 + /*-- in lvm.c --*/ extern int lv_canonical (const char *device, char **ret); diff --git a/daemon/ext2.c b/daemon/ext2.c index a6439352..02cd68aa 100644 --- a/daemon/ext2.c +++ b/daemon/ext2.c @@ -29,9 +29,6 @@ #include "c-ctype.h" #include "actions.h" -/* Confirmed this is true up to ext4 from the Linux sources. */ -#define EXT2_LABEL_MAX 16 - #define MAX_ARGS 64 /* Choose which tools like mke2fs to use. For RHEL 5 (only) there @@ -154,28 +151,7 @@ do_tune2fs_l (const char *device) int do_set_e2label (const char *device, const char *label) { - int r; - char *err; - - char prog[] = "e2label"; - if (e2prog (prog) == -1) - return -1; - - if (strlen (label) > EXT2_LABEL_MAX) { - reply_with_error ("%s: ext2 labels are limited to %d bytes", - label, EXT2_LABEL_MAX); - return -1; - } - - r = command (NULL, &err, prog, device, label, NULL); - if (r == -1) { - reply_with_error ("%s", err); - free (err); - return -1; - } - - free (err); - return 0; + return do_set_label (device, label); } char * diff --git a/daemon/labels.c b/daemon/labels.c new file mode 100644 index 00000000..71176984 --- /dev/null +++ b/daemon/labels.c @@ -0,0 +1,100 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2012 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include +#include +#include + +#include "daemon.h" +#include "actions.h" +#include "optgroups.h" + +static int +e2label (const char *device, const char *label) +{ + int r; + char *err; + + char prog[] = "e2label"; + if (e2prog (prog) == -1) + return -1; + + if (strlen (label) > EXT2_LABEL_MAX) { + reply_with_error ("%s: ext2 labels are limited to %d bytes", + label, EXT2_LABEL_MAX); + return -1; + } + + r = command (NULL, &err, prog, device, label, NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (err); + return -1; + } + + free (err); + return 0; +} + +static int +ntfslabel (const char *device, const char *label) +{ + int r; + char *err; + + /* XXX We should check if the label is longer than 128 unicode + * characters and return an error. This is not so easy since we + * don't have the required libraries. + */ + r = command (NULL, &err, "ntfslabel", device, label, NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (err); + return -1; + } + + free (err); + return 0; +} + +int +do_set_label (const char *device, const char *label) +{ + char *vfs_type; + + /* How we set the label depends on the filesystem type. */ + vfs_type = do_vfs_type (device); + if (vfs_type == NULL) + return -1; + + if (STREQ (vfs_type, "ext2") || STREQ (vfs_type, "ext3") + || STREQ (vfs_type, "ext4")) + return e2label (device, label); + + else if (STREQ (vfs_type, "ntfs")) + return ntfslabel (device, label); + + else { + reply_with_error ("don't know how to set the label for '%s' filesystems", + vfs_type); + return -1; + } +} diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index 2d24e6ae..d9f88afd 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -3007,7 +3007,7 @@ The implementation uses the C command which refuses to wipe physical volumes that contain any volume groups, so you have to remove those first."); - ("set_e2label", (RErr, [Device "device"; String "label"], []), 80, [], + ("set_e2label", (RErr, [Device "device"; String "label"], []), 80, [DeprecatedBy "set_label"], [InitBasicFS, Always, TestOutput ( [["set_e2label"; "/dev/sda1"; "testlabel"]; ["get_e2label"; "/dev/sda1"]], "testlabel")], @@ -5698,7 +5698,7 @@ a file in the host and attach it as a device."); ("vfs_label", (RString "label", [Device "device"], []), 253, [], [InitBasicFS, Always, TestOutput ( - [["set_e2label"; "/dev/sda1"; "LTEST"]; + [["set_label"; "/dev/sda1"; "LTEST"]; ["vfs_label"; "/dev/sda1"]], "LTEST")], "get the filesystem label", "\ @@ -6709,6 +6709,30 @@ Restore the C (from a previous call to C) to C, overwriting any existing contents of this device."); + ("set_label", (RErr, [Device "device"; String "label"], []), 310, [], + [InitBasicFS, Always, TestOutput ( + [["set_label"; "/dev/sda1"; "testlabel"]; + ["vfs_label"; "/dev/sda1"]], "testlabel"); + InitPartition, IfAvailable "ntfs3g", TestOutput ( + [["mkfs"; "ntfs"; "/dev/sda1"]; + ["set_label"; "/dev/sda1"; "testlabel2"]; + ["vfs_label"; "/dev/sda1"]], "testlabel2"); + InitPartition, Always, TestLastFail ( + [["zero"; "/dev/sda1"]; + ["set_label"; "/dev/sda1"; "testlabel2"]])], + "set filesystem label", + "\ +Set the filesystem label on C to C