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.
This commit is contained in:
Richard W.M. Jones
2012-02-27 14:05:38 +00:00
parent e567f064e2
commit d1711dae9d
11 changed files with 137 additions and 36 deletions

4
TODO
View File

@@ -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

View File

@@ -125,6 +125,7 @@ guestfsd_SOURCES = \
inotify.c \
internal.c \
is.c \
labels.c \
link.c \
ls.c \
luks.c \

View File

@@ -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);

View File

@@ -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 *

100
daemon/labels.c Normal file
View File

@@ -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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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;
}
}

View File

@@ -3007,7 +3007,7 @@ The implementation uses the C<pvremove> 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<backupfile> (from a previous call to
C<guestfs_ntfsclone_out>) to C<device>, 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<device> to C<label>.
Only some filesystem types support labels, and libguestfs supports
setting labels on only a subset of these.
On ext2/3/4 filesystems, labels are limited to 16 bytes.
On NTFS filesystems, labels are limited to 128 unicode characters.
To read the label on a filesystem, call C<guestfs_vfs_label>.");
]
let all_functions = non_daemon_functions @ daemon_functions

View File

@@ -44,6 +44,7 @@ daemon/initrd.c
daemon/inotify.c
daemon/internal.c
daemon/is.c
daemon/labels.c
daemon/link.c
daemon/ls.c
daemon/luks.c

View File

@@ -1 +1 @@
309
310

View File

@@ -49,7 +49,7 @@ lvcreate home debian 32
# Phony /boot filesystem.
mkfs-opts ext2 /dev/sda1 blocksize:4096
set-e2label /dev/sda1 BOOT
set-label /dev/sda1 BOOT
set-e2uuid /dev/sda1 01234567-0123-0123-0123-012345678901
# Phony root and other filesystems.

View File

@@ -126,12 +126,12 @@ $g->lvcreate('LV3', 'VG', 64);
# Phony /boot filesystem
$g->mkfs_opts('ext2', $bootdev, blocksize => 4096);
$g->set_e2label($bootdev, 'BOOT');
$g->set_label($bootdev, 'BOOT');
$g->set_e2uuid($bootdev, '01234567-0123-0123-0123-012345678901');
# Phony root filesystem.
$g->mkfs_opts('ext2', '/dev/VG/Root', blocksize => 4096);
$g->set_e2label('/dev/VG/Root', 'ROOT');
$g->set_label('/dev/VG/Root', 'ROOT');
$g->set_e2uuid('/dev/VG/Root', '01234567-0123-0123-0123-012345678902');
# Enough to fool inspection API.

View File

@@ -47,7 +47,7 @@ part-add /dev/sda p 524288 -64
# Phony /boot filesystem.
mkfs-opts ext2 /dev/sda1 blocksize:4096
set-e2label /dev/sda1 BOOT
set-label /dev/sda1 BOOT
set-e2uuid /dev/sda1 01234567-0123-0123-0123-012345678901
# Phony root filesystem (Ubuntu doesn't use LVM by default).