NEW API:xfs:xfs_repair

Add a new api xfs_repair for repairing an XFS filesystem.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>

RWMJ:
  - Fix non-error return path so it doesn't send two replies.
  - Document return code.
This commit is contained in:
Wanlong Gao
2012-08-30 17:25:47 +08:00
committed by Richard W.M. Jones
parent bcbad66b18
commit 7036a3bccf
5 changed files with 156 additions and 3 deletions

View File

@@ -528,3 +528,125 @@ error:
free (err);
return -1;
}
int
do_xfs_repair (const char *device,
int forcelogzero, int nomodify,
int noprefetch, int forcegeometry,
int64_t maxmem, int64_t ihashsize,
int64_t bhashsize, int64_t agstride,
const char *logdev, const char *rtdev)
{
int r;
char *err = NULL;
const char *argv[MAX_ARGS];
char *buf = NULL;
char maxmem_s[64];
char ihashsize_s[70];
char bhashsize_s[70];
char agstride_s[74];
size_t i = 0;
int is_device;
ADD_ARG (argv, i, "xfs_repair");
/* Optional arguments */
if (optargs_bitmask & GUESTFS_XFS_REPAIR_FORCELOGZERO_BITMASK) {
if (forcelogzero)
ADD_ARG (argv, i, "-L");
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_NOMODIFY_BITMASK) {
if (nomodify)
ADD_ARG (argv, i, "-n");
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_NOPREFETCH_BITMASK) {
if (noprefetch)
ADD_ARG (argv, i, "-P");
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_FORCEGEOMETRY_BITMASK) {
if (forcegeometry) {
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, "force_geometry");
}
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_MAXMEM_BITMASK) {
if (maxmem < 0) {
reply_with_error ("maxmem must be >= 0");
goto error;
}
snprintf(maxmem_s, sizeof maxmem_s, "%" PRIi64, maxmem);
ADD_ARG (argv, i, "-m");
ADD_ARG (argv, i, maxmem_s);
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_IHASHSIZE_BITMASK) {
if (ihashsize < 0) {
reply_with_error ("ihashsize must be >= 0");
goto error;
}
snprintf(ihashsize_s, sizeof ihashsize_s, "ihash=" "%" PRIi64, ihashsize);
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, ihashsize_s);
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_BHASHSIZE_BITMASK) {
if (bhashsize < 0) {
reply_with_error ("bhashsize must be >= 0");
goto error;
}
snprintf(bhashsize_s, sizeof bhashsize_s, "bhash=" "%" PRIi64, bhashsize);
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, bhashsize_s);
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_AGSTRIDE_BITMASK) {
if (agstride < 0) {
reply_with_error ("agstride must be >= 0");
goto error;
}
snprintf(agstride_s, sizeof agstride_s, "ag_stride=" "%" PRIi64, agstride);
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, agstride_s);
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_LOGDEV_BITMASK) {
ADD_ARG (argv, i, "-l");
ADD_ARG (argv, i, logdev);
}
if (optargs_bitmask & GUESTFS_XFS_REPAIR_RTDEV_BITMASK) {
ADD_ARG (argv, i, "-r");
ADD_ARG (argv, i, rtdev);
}
is_device = STREQLEN (device, "/dev/", 5);
if (!is_device) {
buf = sysroot_path (device);
if (buf == NULL) {
reply_with_perror ("malloc");
goto error;
}
ADD_ARG (argv, i, "-f");
ADD_ARG (argv, i, buf);
} else {
ADD_ARG (argv, i, device);
}
ADD_ARG (argv, i, NULL);
r = commandrv (NULL, &err, argv);
if (buf) free (buf);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
goto error;
}
free (err);
return r;
error:
if (err) free (err);
return -1;
}

View File

@@ -9682,6 +9682,34 @@ C<key> is the name, C<t> is the type, and C<val> is the data.
This is a wrapper around the L<hivex(3)> call of the same name." };
{ defaults with
name = "xfs_repair";
style = RInt "status", [Dev_or_Path "device"], [OBool "forcelogzero"; OBool "nomodify"; OBool "noprefetch"; OBool "forcegeometry"; OInt64 "maxmem"; OInt64 "ihashsize"; OInt64 "bhashsize"; OInt64 "agstride"; OString "logdev"; OString "rtdev"];
proc_nr = Some 366;
optional = Some "xfs";
tests = [
InitEmpty, IfAvailable "xfs", TestRun (
[["part_disk"; "/dev/sda"; "mbr"];
["mkfs"; "xfs"; "/dev/sda1"; ""; "NOARG"; ""; ""];
["xfs_repair"; "/dev/sda1"; ""; "true"; ""; ""; ""; ""; ""; ""; "NOARG"; "NOARG"]
])
];
shortdesc = "repair an XFS filesystem";
longdesc = "\
Repair corrupt or damaged XFS filesystem on C<device>.
The filesystem is specified using the C<device> argument which should be
the device name of the disk partition or volume containing the filesystem.
If given the name of a block device, C<xfs_repair> will attempt to find
the raw device associated with the specified block device and will use
the raw device instead.
Regardless, the filesystem to be repaired must be unmounted, otherwise,
the resulting filesystem may be inconsistent or corrupt.
The returned status indicates whether filesystem corruption was
detected (returns C<1>) or was not detected (returns C<0>)." };
]
(* Non-API meta-commands available only in guestfish.

View File

@@ -77,7 +77,8 @@ guestfs_gobject_headers= \
include/guestfs-gobject/optargs-rsync_in.h \
include/guestfs-gobject/optargs-rsync_out.h \
include/guestfs-gobject/optargs-xfs_admin.h \
include/guestfs-gobject/optargs-hivex_open.h
include/guestfs-gobject/optargs-hivex_open.h \
include/guestfs-gobject/optargs-xfs_repair.h
guestfs_gobject_sources= \
src/session.c \
@@ -136,4 +137,5 @@ guestfs_gobject_sources= \
src/optargs-rsync_in.c \
src/optargs-rsync_out.c \
src/optargs-xfs_admin.c \
src/optargs-hivex_open.c
src/optargs-hivex_open.c \
src/optargs-xfs_repair.c

View File

@@ -172,6 +172,7 @@ gobject/src/optargs-umount.c
gobject/src/optargs-umount_local.c
gobject/src/optargs-xfs_admin.c
gobject/src/optargs-xfs_growfs.c
gobject/src/optargs-xfs_repair.c
gobject/src/session.c
gobject/src/struct-application.c
gobject/src/struct-btrfssubvolume.c

View File

@@ -1 +1 @@
365
366