From: Russell Cattelan Date: Thu, 1 May 2003 21:31:58 +0000 (+0000) Subject: Allow repair to run on a read only filesystem. X-Git-Tag: XFS-1_3_0pre1~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c781939c66c0efe9141f89127dc97ea0ba39d5e9;p=thirdparty%2Fxfsprogs-dev.git Allow repair to run on a read only filesystem. Added LIBXFS_DANGEROUSLY flag --- diff --git a/include/libxfs.h b/include/libxfs.h index e6c45f427..579cf1d9a 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -110,6 +110,7 @@ typedef struct { #define LIBXFS_EXIT_ON_FAILURE 0x0001 /* exit the program if a call fails */ #define LIBXFS_ISREADONLY 0x0002 /* disallow all mounted filesystems */ #define LIBXFS_ISINACTIVE 0x0004 /* allow mounted only if mounted ro */ +#define LIBXFS_DANGEROUSLY 0x0008 /* repair is mounted ro */ extern char *progname; extern int libxfs_init (libxfs_init_t *); diff --git a/libxfs/init.c b/libxfs/init.c index 6176948f5..e5ffd11a0 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -170,6 +170,40 @@ libxfs_device_close(dev_t dev) exit(1); } +int +check_open(char *path, int flags,char **rawfile,char **blockfile){ + + int readonly = (flags & LIBXFS_ISREADONLY); + int inactive = (flags & LIBXFS_ISINACTIVE); + int dangerously = (flags & LIBXFS_DANGEROUSLY); + struct stat64 stbuf; + + if (stat64(path, &stbuf) < 0) { + perror(path); + return 0; + } + if (!(*rawfile = findrawpath(path))) { + fprintf(stderr, _("%s: " + "can't find a character device matching %s\n"), + progname, path); + return 0; + } + if (!(*blockfile = findblockpath(path))) { + fprintf(stderr, _("%s: " + "can't find a block device matching %s\n"), + progname, path); + return 0; + } + if (!readonly && !inactive && platform_check_ismounted(path, *blockfile, NULL, 1)) + return 0; + + if (inactive && check_isactive(path, *blockfile, ((readonly|dangerously)?1:0))) + return 0; + + return 1; +} + + /* * libxfs initialization. @@ -192,7 +226,7 @@ libxfs_init(libxfs_init_t *a) int rval = 0; int readonly; int inactive; - struct stat64 stbuf; + int flags; dpath[0] = logpath[0] = rtpath[0] = '\0'; dname = a->dname; @@ -207,28 +241,11 @@ libxfs_init(libxfs_init_t *a) fd = -1; readonly = (a->isreadonly & LIBXFS_ISREADONLY); inactive = (a->isreadonly & LIBXFS_ISINACTIVE); + flags = a->isreadonly; + if (a->volname) { - if (stat64(a->volname, &stbuf) < 0) { - perror(a->volname); - goto done; - } - if (!(rawfile = findrawpath(a->volname))) { - fprintf(stderr, _("%s: " - "can't find a character device matching %s\n"), - progname, a->volname); - goto done; - } - if (!(blockfile = findblockpath(a->volname))) { - fprintf(stderr, _("%s: " - "can't find a block device matching %s\n"), - progname, a->volname); - goto done; - } - if (!readonly && !inactive && - platform_check_ismounted(a->volname, blockfile, NULL, 1)) - goto done; - if (inactive && check_isactive( - a->volname, blockfile, readonly)) + + if(!check_open(a->volname,flags,&rawfile,&blockfile)) goto done; needcd = 1; fd = open(rawfile, O_RDONLY); @@ -314,29 +331,7 @@ voldone: a->setblksize); a->dfd = libxfs_device_to_fd(a->ddev); } else { - if (stat64(dname, &stbuf) < 0) { - fprintf(stderr, - _("%s: stat64 failed on %s: %s\n"), - progname, dname, strerror(errno)); - goto done; - } - if (!(rawfile = findrawpath(dname))) { - fprintf(stderr, - _("%s: can't find a char device " - "matching %s\n"), progname, dname); - goto done; - } - if (!(blockfile = findblockpath(dname))) { - fprintf(stderr, - _("%s: can't find a block device " - "matching %s\n"), progname, dname); - goto done; - } - if (!readonly && !inactive && - platform_check_ismounted(dname, blockfile, NULL, 1)) - goto done; - if (inactive && check_isactive( - dname, blockfile, readonly)) + if(!check_open(dname,flags,&rawfile,&blockfile)) goto done; a->ddev = libxfs_device_open(rawfile, a->dcreat, readonly, a->setblksize); @@ -354,29 +349,7 @@ voldone: a->lcreat, readonly, a->setblksize); a->logfd = libxfs_device_to_fd(a->logdev); } else { - if (stat64(logname, &stbuf) < 0) { - fprintf(stderr, - _("%s: stat64 failed on %s: %s\n"), - progname, logname, strerror(errno)); - goto done; - } - if (!(rawfile = findrawpath(logname))) { - fprintf(stderr, - _("%s: can't find a char device " - "matching %s\n"), progname, logname); - goto done; - } - if (!(blockfile = findblockpath(logname))) { - fprintf(stderr, - _("%s: can't find a block device " - "matching %s\n"), progname, logname); - goto done; - } - if (!readonly && !inactive && - platform_check_ismounted(logname, blockfile, NULL, 1)) - goto done; - else if (inactive && check_isactive( - logname, blockfile, readonly)) + if(!check_open(logname,flags,&rawfile,&blockfile)) goto done; a->logdev = libxfs_device_open(rawfile, a->lcreat, readonly, a->setblksize); @@ -394,29 +367,7 @@ voldone: a->rcreat, readonly, a->setblksize); a->rtfd = libxfs_device_to_fd(a->rtdev); } else { - if (stat64(rtname, &stbuf) < 0) { - fprintf(stderr, - _("%s: stat64 failed on %s: %s\n"), - progname, rtname, strerror(errno)); - goto done; - } - if (!(rawfile = findrawpath(rtname))) { - fprintf(stderr, - _("%s: can't find a char device " - "matching %s\n"), progname, rtname); - goto done; - } - if (!(blockfile = findblockpath(rtname))) { - fprintf(stderr, - _("%s: can't find a block device " - "matching %s\n"), progname, rtname); - goto done; - } - if (!readonly && !inactive && - platform_check_ismounted(rtname, blockfile, NULL, 1)) - goto done; - if (inactive && check_isactive( - rtname, blockfile, readonly)) + if(!check_open(rtname,flags,&rawfile,&blockfile)) goto done; a->rtdev = libxfs_device_open(rawfile, a->rcreat, readonly, a->setblksize); diff --git a/man/man8/xfs_repair.8 b/man/man8/xfs_repair.8 index 025ea71a0..0bca163bd 100644 --- a/man/man8/xfs_repair.8 +++ b/man/man8/xfs_repair.8 @@ -3,10 +3,10 @@ xfs_repair \- repair an XFS filesystem .SH SYNOPSIS .nf -\f3xfs_repair\f1 [ \f3\-nLvV\f1 ] [ \f3\-o\f1 subopt[=value] ] +\f3xfs_repair\f1 [ \f3\-nLvVd\f1 ] [ \f3\-o\f1 subopt[=value] ] [\f3-l\f1 logdev] [\f3-r\f1 rtdev] xfs_special .sp .8v -\f3xfs_repair\f1 \f3\-f\f1 [ \f3\-nLvV\f1 ] [ \f3\-o\f1 subopt[=value] ] +\f3xfs_repair\f1 \f3\-f\f1 [ \f3\-nLvVd\f1 ] [ \f3\-o\f1 subopt[=value] ] [\f3-l\f1 logfile] [\f3-r\f1 rtfile] file .fi .SH DESCRIPTION @@ -94,6 +94,11 @@ will ignore an EFS superblock if one is found. .TP .B \-v Verbose output. +.TP +.B \-d +Repair dangerously. Allow xfs_repair to repair an XFS filesystem +mounted read only. This is typically done on a root fileystem from +single user mode, immediately followed by a reboot. .SS Checks Performed Inconsistencies corrected include the following: .TP diff --git a/repair/globals.h b/repair/globals.h index 35fe62d6d..da0e62142 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -120,6 +120,7 @@ EXTERN int fs_fd; /* filesystem fd */ EXTERN int verbose; EXTERN int no_modify; +EXTERN int dangerously; /* live danderously ... repair a ro mounted fs */ EXTERN int isa_file; EXTERN int zap_log; EXTERN int dumpcore; /* abort, not exit on fatal errs */ diff --git a/repair/init.c b/repair/init.c index 7570a07e2..b7dc6e0f0 100644 --- a/repair/init.c +++ b/repair/init.c @@ -70,6 +70,10 @@ xfs_init(libxfs_init_t *args) if (no_modify) args->isreadonly = (LIBXFS_ISREADONLY | LIBXFS_ISINACTIVE); + + if(dangerously) + args->isreadonly = (LIBXFS_ISINACTIVE | LIBXFS_DANGEROUSLY); + if (!libxfs_init(args)) do_error(_("couldn't initialize XFS library\n")); diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index a227c3871..1effeaada 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -164,6 +164,7 @@ process_args(int argc, char **argv) fs_is_dirty = 0; verbose = 0; no_modify = 0; + dangerously = 0; isa_file = 0; zap_log = 0; dumpcore = 0; @@ -188,7 +189,7 @@ process_args(int argc, char **argv) * XXX have to add suboption processing here * attributes, quotas, nlinks, aligned_inos, sb_fbits */ - while ((c = getopt(argc, argv, "o:fl:r:LnDvV")) != EOF) { + while ((c = getopt(argc, argv, "o:fl:r:LnDvVd")) != EOF) { switch (c) { case 'D': dumpcore = 1; @@ -243,6 +244,9 @@ process_args(int argc, char **argv) case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); + case 'd': /* dangerously */ + dangerously = 1; + break; case '?': usage(); }