+2002-08-18 Theodore Ts'o <tytso@mit.edu>
+
+ * fs_ext2.c (fs_fsck, fs_shrink, fs_expand): Change to use new
+ calling convention of fsim_fsck. Fixed bug in fs_shrink
+ and f_expand where the shrink or expand would get aborted
+ if fsck returned an exit status code of 1 (which is normal).
+
+ * fsimext2.c (fsim_fsck): Add new parameter ret_status, and return
+ the exit status there. The return code now returns 0 for
+ success, and an error code in case of failure, which
+ removes a lot of the ambiguity.
+
2002-08-17 Theodore Ts'o <tytso@mit.edu>
* fs_ext2.c, fsimext2.c: Synchronize with EVMS CVS tree.
(sb->s_state & EXT2_ERROR_FS) ||
((sb->s_state & EXT2_VALID_FS) == 0)) {
MESSAGE("Running fsck before expanding volume");
- rc = fsim_fsck(volume, NULL );
- if (rc)
+ rc = fsim_fsck(volume, NULL, &status );
+ if (rc) {
+ MESSAGE("Attempt to execute fsck failed (%d)", rc);
+ MESSAGE("Aborting volume expand");
goto errout;
+ }
+ if (status >= 4) {
+ MESSAGE("Aborting volume expand");
+ rc = status;
+ goto errout;
+ }
}
/* don't expand if mounted */
(sb->s_state & EXT2_ERROR_FS) ||
((sb->s_state & EXT2_VALID_FS) == 0)) {
MESSAGE("Running fsck before shrinking volume");
- rc = fsim_fsck(volume, NULL );
- if (rc)
+ rc = fsim_fsck(volume, NULL, &status );
+ if (rc) {
+ MESSAGE("Attempt to execute fsck failed (%d)", rc);
+ MESSAGE("Aborting volume shrink");
goto errout;
+ }
+ if (status >= 4) {
+ MESSAGE("Aborting volume shrink");
+ rc = status;
+ goto errout;
+ }
}
if (pipe(fds1)) {
static int fs_fsck(logical_volume_t * volume, option_array_t * options )
{
int rc = EINVAL;
+ int status;
LOGENTRY();
- rc = fsim_fsck( volume, options );
-
- /*
- * If fsck.ext2 returns FSCK_CORRECTED, the
- * file system is clean, so return FSCK_OK.
- */
- if ( rc == FSCK_CORRECTED ) {
- rc = FSCK_OK;
- /*
- * The value of FSCK_CORRECTED is the same as
- * EPERM, so fsim_fsck will return -1 for EPERM.
- */
- } else if (rc == -1) {
- rc = EPERM;
- }
-
- /*
- * If the volume is mounted, e2fsck checked READ ONLY
- * regardless of options specified. If the check was READ ONLY
- * and errors were found, let the user know how to fix them.
- */
- if (EVMS_IS_MOUNTED(volume) && rc) {
- MESSAGE( "%s is mounted.", EVMS_GET_DEVNAME(volume) );
- MESSAGE( "e2fsck checked the volume READ ONLY and found, but did not fix, errors." );
- MESSAGE( "Unmount %s and run e2fsck again to repair the file system.", EVMS_GET_DEVNAME(volume) );
- }
+ rc = fsim_fsck( volume, options, &status );
+ if (rc)
+ goto errout;
+
+ /*
+ * If the volume is mounted, e2fsck checked READ ONLY
+ * regardless of options specified. If the check was READ
+ * ONLY and errors were found, let the user know how to fix
+ * them.
+ */
+ if (EVMS_IS_MOUNTED(volume) && (status & FSCK_ERRORS_UNCORRECTED)) {
+ MESSAGE( "%s is mounted.", EVMS_GET_DEVNAME(volume) );
+ MESSAGE( "e2fsck checked the volume READ ONLY and found, but did not fix, errors." );
+ MESSAGE( "Unmount %s and run e2fsck again to repair the file system.", EVMS_GET_DEVNAME(volume) );
+ }
+ if (status > 4) {
+ MESSAGE( "e2fsck exited with status code %d.", status);
+ }
+errout:
LOGEXITRC();
return rc;
}
/*
* Run fsck on the volume.
*/
-int fsim_fsck(logical_volume_t * volume, option_array_t * options )
+int fsim_fsck(logical_volume_t * volume, option_array_t * options,
+ int *ret_status)
{
int rc = FSIM_ERROR;
char *argv[FSCK_EXT2_OPTIONS_COUNT + 3];
/* open pipe, alloc buffer for collecting fsck.jfs output */
rc = pipe(fds2);
if (rc) {
- return(rc);
+ return(errno);
}
if (!(buffer = EngFncs->engine_alloc(MAX_USER_MESSAGE_LEN))) {
return(ENOMEM);
/* child */
case 0:
- set_fsck_options( options, argv, volume );
+ set_fsck_options( options, argv, volume );
/* pipe stderr, stdout */
- dup2(fds2[1],1); /* fds2[1] replaces stdout */
- dup2(fds2[1],2); /* fds2[1] replaces stderr */
- close(fds2[0]); /* don't need this here */
-
- rc = execvp( argv[0], argv );
-
- /*
- * The value of fsck exit code FSCK_CORRECTED is the same
- * as errno EPERM. Thus, if EPERM is returned from execv,
- * exit out of the child with rc = -1 instead of EPERM.
- */
- if( rc && (errno == EPERM) ) {
- /* using exit() can hang GUI, use _exit */
- _exit(-1);
- } else {
- /* using exit() can hang GUI, use _exit */
- _exit(errno);
- }
-
+ dup2(fds2[1],1); /* fds2[1] replaces stdout */
+ dup2(fds2[1],2); /* fds2[1] replaces stderr */
+ close(fds2[0]); /* don't need this here */
+
+ execvp( argv[0], argv );
+ /* should never get here */
+ _exit(8); /* FSCK_ERROR -- operational error */
+
/* parent */
default:
close(fds2[1]);
}
if ( WIFEXITED(status) ) {
/* get e2fsck exit code */
- rc = WEXITSTATUS(status);
- LOG("e2fsck completed with exit code %d \n", rc);
+ *ret_status = WEXITSTATUS(status);
+ LOG("e2fsck completed with exit code %d \n",
+ *ret_status);
+ rc = 0;
}
}
int fsim_get_ext2_superblock( logical_volume_t *, struct ext2_super_block * );
int fsim_unmkfs( logical_volume_t * );
int fsim_mkfs( logical_volume_t *, option_array_t * );
-int fsim_fsck( logical_volume_t *, option_array_t * );
+int fsim_fsck( logical_volume_t *, option_array_t *, int * );
int fsim_get_volume_limits( struct ext2_super_block *, sector_count_t *,
sector_count_t *, sector_count_t * );
int fsim_test_version( void );