--- misc/Makefile.in +++ misc/Makefile.in @@ -36,7 +36,7 @@ DUMPE2FS_OBJS= dumpe2fs.o BADBLOCKS_OBJS= badblocks.o E2IMAGE_OBJS= e2image.o -FSCK_OBJS= fsck.o base_device.o +FSCK_OBJS= fsck.o base_device.o fsck_udev.o BLKID_OBJS= blkid.o FILEFRAG_OBJS= filefrag.o @@ -57,6 +57,9 @@ LIBS_BLKID= $(LIBBLKID) $(LIBUUID) DEPLIBS_BLKID= $(LIBBLKID) $(DEPLIBUUID) +LIBS_VOLID= -lvolume_id +DEPLIBS_VOLID= + LIBS_E2P= $(LIBE2P) $(LIBCOM_ERR) DEPLIBS_E2P= $(LIBE2P) $(LIBCOM_ERR) @@ -98,10 +101,6 @@ @$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(srcdir)/base_device.c \ -DDEBUG -o base_device -check:: base_device - ./base_device < $(srcdir)/base_device.tst > base_device.out - cmp $(srcdir)/base_device.tst base_device.out - mklost+found: $(MKLPF_OBJS) @echo " LD $@" @$(CC) $(ALL_LDFLAGS) -o mklost+found $(MKLPF_OBJS) $(LIBINTL) @@ -138,9 +137,9 @@ @$(CC) $(ALL_LDFLAGS) -o dumpe2fs $(DUMPE2FS_OBJS) $(LIBS) \ $(LIBS_E2P) $(LIBUUID) $(LIBINTL) -fsck: $(FSCK_OBJS) $(DEBLIBS_BLKID) +fsck: $(FSCK_OBJS) $(DEBLIBS_VOLID) @echo " LD $@" - @$(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBS_BLKID) $(LIBINTL) + @$(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBS_VOLID) $(LIBINTL) badblocks: $(BADBLOCKS_OBJS) $(DEPLIBS) @echo " LD $@" --- misc/base_device.c +++ misc/base_device.c @@ -27,6 +27,8 @@ #endif #include #include +#include +#include #include "fsck.h" --- misc/fsck.8.in +++ misc/fsck.8.in @@ -8,7 +8,7 @@ .SH SYNOPSIS .B fsck [ -.B \-sAVRTNP +.B \-sAVRTMNP ] [ .B \-C @@ -236,6 +236,14 @@ .B \-N Don't execute, just show what would be done. .TP +.B \-M +Emulate +.BR mount (1) +behaviour; do not check the filesystem if it's not listed in +/etc/fstab or if +.I fs_pass_no +of the corresponding entry is zero. +.TP .B \-P When the .B \-A --- misc/fsck.c +++ misc/fsck.c @@ -59,7 +59,6 @@ #include "../version.h" #include "nls-enable.h" #include "fsck.h" -#include "blkid/blkid.h" #ifndef _PATH_MNTTAB #define _PATH_MNTTAB "/etc/fstab" @@ -118,7 +117,6 @@ struct fsck_instance *instance_list; const char *fsck_prefix_path = "/sbin:/sbin/fs.d:/sbin/fs:/etc/fs:/etc"; char *fsck_path = 0; -blkid_cache cache = NULL; static char *string_copy(const char *s) { @@ -297,7 +295,7 @@ parse_escape(freq); parse_escape(passno); - dev = blkid_get_devname(cache, device, NULL); + dev = fsck_get_devname(device); if (dev) device = dev; @@ -322,7 +320,7 @@ if (strcmp(fs->type, "auto") != 0) return; - t = blkid_get_tag_value(cache, "TYPE", fs->device); + t = fsck_get_fstype(fs->device); if (t) { free(fs->type); fs->type = t; @@ -1048,7 +1046,7 @@ static void usage(NOARGS) { - fputs(_("Usage: fsck [-ANPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr); + fputs(_("Usage: fsck [-AMNPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr); exit(EXIT_USAGE); } @@ -1094,7 +1092,7 @@ progname); exit(EXIT_ERROR); } - dev = blkid_get_devname(cache, arg, NULL); + dev = fsck_get_devname(arg); if (!dev && strchr(arg, '=')) { /* * Check to see if we failed because @@ -1240,7 +1238,7 @@ bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif - blkid_get_cache(&cache, getenv("BLKID_FILE")); + fsck_get_cache(getenv("BLKID_FILE")); PRS(argc, argv); if (!notitle) @@ -1287,6 +1285,16 @@ break; } fs = lookup(devices[i]); + if (like_mount) { + /* + * Emulate mount behaviour: + * Do not check device if not found + * in /etc/fstab or if the passno + * is set to '0' + */ + if (!fs || ignore(fs)) + continue; + } if (!fs) { fs = create_fs_device(devices[i], 0, "auto", 0, -1, -1); @@ -1309,6 +1317,6 @@ } status |= wait_many(FLAG_WAIT_ALL); free(fsck_path); - blkid_put_cache(cache); + fsck_put_cache(); return status; } --- misc/fsck.h +++ misc/fsck.h @@ -68,3 +68,9 @@ extern dev_t base_devt(const char *device); extern int match_device(const char *dev1, const char *dev2); + +extern int fsck_get_cache(const char *filename); +extern void fsck_put_cache(void); +extern char *fsck_get_devname(const char *device); +extern char *fsck_get_fstype(const char *device); + --- misc/fsck_blkid.c +++ misc/fsck_blkid.c @@ -0,0 +1,29 @@ +/* + * Wrapper for libblkid + */ + +#include +#include "blkid/blkid.h" + +static blkid_cache cache = NULL; + +int fsck_get_cache(const char *filename) +{ + return blkid_get_cache(&cache, name); +} + +void fsck_put_cache(void) +{ + blkid_put_cache(cache); +} + +char *fsck_get_devname(const char *device) +{ + return blkid_get_devname(cache, device, NULL); +} + +char *fsck_get_fstype(const char *device) +{ + return blkid_get_tag_value(cache, "TYPE", device); +} + --- misc/fsck_udev.c +++ misc/fsck_udev.c @@ -0,0 +1,188 @@ +/* + * Wrapper for libvolume_id + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsck.h" + +int fsck_get_cache(const char *filename) +{ + return 0; +} + +void fsck_put_cache(void) +{ +} + +char *fsck_get_devname_by_uuid(const char *uuid) +{ + char *dev = NULL; + + if (!uuid) + return NULL; + + dev = malloc(19 + strlen(uuid)); + if (dev) { + strcpy(dev,"/dev/disk/by-uuid/"); + strcat(dev,uuid); + } + + return dev; +} + +char *fsck_get_devname_by_label(const char *label) +{ + char *dev = NULL; + + if (!label) + return NULL; + + dev = malloc(20 + strlen(label)); + if (dev) { + strcpy(dev,"/dev/disk/by-label/"); + strcat(dev,label); + } + + return dev; +} + +char *fsck_get_devname(const char *spec) +{ + char *token, *cp, *value; + char *nspec = NULL; + + if (!spec) + return NULL; + + token = strdup(spec); + if (!token) + return NULL; + + /* We have to return an allocated string */ + if (!(cp = strchr(token, '='))) + return token; + + value = token + (cp - token); + *value++ = '\0'; + + if (*value == '"' || *value == '\'') { + char c = *value++; + if (!(cp = strrchr(value, c))) + goto errout; /* missing closing quote */ + *cp = '\0'; + } + + if (!strcmp(token,"LABEL")) { + nspec = fsck_get_devname_by_label(value); + } else if (!strcmp(token,"UUID")) { + nspec = fsck_get_devname_by_uuid(value); + } + + free(token); + + errout: + return nspec; +} + +struct volume_id_types_t { + int id; + char *token; + char *env; +}; + +enum { + VOLUME_ID_NONE=0, + VOLUME_ID_TYPE, + VOLUME_ID_LABEL, + VOLUME_ID_UUID +}; + +#define volume_id_offset(member) (unsigned long)offsetof(struct volume_id,member) + +struct volume_id_types_t volume_id_types[] = { + { VOLUME_ID_TYPE, "TYPE", "ID_FS_TYPE" }, + { VOLUME_ID_LABEL, "LABEL", "ID_FS_LABEL" }, + { VOLUME_ID_UUID, "UUID", "ID_FS_UUID" }, + { VOLUME_ID_NONE, NULL, NULL }, +}; + +char *volume_id_get_tag(const char *spec, const char *token) +{ + struct volume_id *vid; + uint64_t size; + struct volume_id_types_t *volume_id_ptr = volume_id_types; + char *var, *value; + + value = malloc(VOLUME_ID_LABEL_SIZE); + if (!value) + return NULL; + + if (!spec) + return NULL; + + while (volume_id_ptr->token && strcmp(volume_id_ptr->token,token)) + volume_id_ptr++; + + if (!volume_id_ptr->token) { + free(value); + value = NULL; + goto out; + } + + /* Quick exit if ID_FS_* variables are set */ + if ((var = getenv(volume_id_ptr->env))) { + strcpy(value,var); + goto out; + } + + vid = volume_id_open_node(spec); + if (!vid) { + free(value); + value = NULL; + goto out; + } + + if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) + size = 0; + + if (volume_id_probe_all(vid, 0, size) == 0) { + switch(volume_id_ptr->id) { + case VOLUME_ID_TYPE: + strcpy(value, vid->type); + break; + case VOLUME_ID_LABEL: + strcpy(value, vid->label); + break; + case VOLUME_ID_UUID: + strcpy(value, vid->uuid); + break; + default: + free(value); + value = NULL; + break; + } + } else { + free(value); + volume_id_close(vid); + return NULL; + } + + volume_id_close(vid); + + out: + return value; +} + +char *fsck_get_fstype(const char *device) +{ + return volume_id_get_tag(device, "TYPE"); +} +