From 8f810496b9b13b79018b6889939a6de6e19ddddd Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Tue, 13 Oct 2015 17:22:40 +0800 Subject: [PATCH] LU-3569 utils: remove ll_recover_lost_found_obj remove obsolete tool ll_recover_lost_found_obj. Signed-off-by: Fan Yong Signed-off-by: Lai Siyao Signed-off-by: James Simmons Change-Id: I5d5f33f5c9d68bb1f05d7ab0da6fb2986e873501 Reviewed-on: http://review.whamcloud.com/16477 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/doc/Makefile.am | 5 +- lustre/doc/ll_decode_filter_fid.8 | 7 - lustre/doc/lustre.7 | 5 +- lustre/tests/conf-sanity.sh | 23 +- lustre/utils/.gitignore | 1 - lustre/utils/Makefile.am | 6 +- lustre/utils/ll_recover_lost_found_objs.c | 658 ------------------------------ 7 files changed, 11 insertions(+), 694 deletions(-) delete mode 100644 lustre/utils/ll_recover_lost_found_objs.c diff --git a/lustre/doc/Makefile.am b/lustre/doc/Makefile.am index eb98b01..9ab9b0d 100644 --- a/lustre/doc/Makefile.am +++ b/lustre/doc/Makefile.am @@ -38,9 +38,8 @@ MANFILES = lustre.7 lfs.1 mount.lustre.8 lctl.8 lnetctl.8 \ llverdev.8 llbackup.8 llapi_quotactl.3 llobdstat.8 llstat.8 \ - plot-llstat.8 l_getgroups.8 lst.8 routerstat.8 \ - ll_recover_lost_found_objs.8 llog_reader.8 llapi_file_open.3 \ - llapi_file_create.3 llapi_file_get_stripe.3 \ + plot-llstat.8 l_getgroups.8 lst.8 routerstat.8 llog_reader.8 \ + llapi_file_open.3 llapi_file_create.3 llapi_file_get_stripe.3 \ lustre_rsync.8 lfs_migrate.1 lhbadm.8 ldev.8 ldev.conf.5 nids.5 \ lfs-hsm.1 llapi_hsm_state_get.3 llapi_hsm_state_set.3 \ lustre_routes_config.8 lustre_routes_conversion.8 \ diff --git a/lustre/doc/ll_decode_filter_fid.8 b/lustre/doc/ll_decode_filter_fid.8 index a436a52..b3ff422 100644 --- a/lustre/doc/ll_decode_filter_fid.8 +++ b/lustre/doc/ll_decode_filter_fid.8 @@ -20,12 +20,6 @@ modified by Lustre after that time. .PP The OST object ID (objid) is useful in case of OST directory corruption, though normally the -.BR ll_recover_lost_found_objs (8) -utility is able to reconstruct the entire OST object directory hierarchy. -The MDS FID can be useful to determine which MDS inode an OST object -is (or was) used by. The stripe index can be used in conjunction with -other OST objects to reconstruct the layout of a file even if the MDT -inode was lost. .SH EXAMPLE .fi root@oss1# cd /mnt/ost/lost+found @@ -56,4 +50,3 @@ The idx field shows the stripe number of this OST object in the Lustre RAID-0 striped file. .SH SEE ALSO .BR lustre (7), -.BR ll_recover_lost_found_objs (8) diff --git a/lustre/doc/lustre.7 b/lustre/doc/lustre.7 index 3e05ff6..a8f013a 100644 --- a/lustre/doc/lustre.7 +++ b/lustre/doc/lustre.7 @@ -54,7 +54,7 @@ A low-level interface to control various aspects of Lustre .TP .BR lfs (1) A user-level interface to control Lustre-specific information for -individual files. +individual files. .B lustre_config.sh Format multiple Lustre targets simultaneously from definitions in a CSV file. @@ -62,7 +62,7 @@ file. Please report all bugs https://jira.hpdd.intel.com/ .SH AVAILABILITY .B The -.BR Lustre (7) +.BR Lustre (7) filesystem package is available via .br https://downloads.hpdd.intel.com/ @@ -76,7 +76,6 @@ https://downloads.hpdd.intel.com/ .BR liblustreapi (7), .BR l_getgroups (8), .BR llstat (8), -.BR ll_recover_lost_found_objs (8), .BR llverdev (8), .BR lst (8), .BR llobdstat (8), diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 41909f1..30eb1ff 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -3692,29 +3692,18 @@ test_52() { do_node $ost1node 'mv '$objects' '${ost1mnt}'/lost+found' [ $? -eq 0 ] || { error "Unable to move objects"; return 14; } - # recover objects dry-run - if [ $(lustre_version_code ost1) -ge $(version_code 2.5.56) ]; then - echo "ll_recover_lost_found_objs dry_run" - do_node $ost1node \ - "ll_recover_lost_found_objs -n -d $ost1mnt/O" || - error "ll_recover_lost_found_objs failed" - fi - - # recover objects - echo "ll_recover_lost_found_objs fix run" - do_node $ost1node "ll_recover_lost_found_objs -d $ost1mnt/lost+found" || - error "ll_recover_lost_found_objs failed" - - # compare restored objects against saved ones - diff_files_xattrs $ost1node $ost1tmp/objects $ost1tmp/object_xattrs $objects - [ $? -eq 0 ] || error "Unable to diff objects" - do_node $ost1node "umount $ost1mnt" || error "Unable to umount ost1 as ldiskfs" start_ost || error "Unable to start OST1" mount_client $MOUNT || error "Unable to mount client" + local REPAIRED=$(do_node $ost1node "$LCTL get_param \ + -n osd-ldiskfs.$FSNAME-OST0000.oi_scrub" | + awk '/^lf_repa[ri]*ed/ { print $2 }') + [ $REPAIRED -gt 0 ] || + error "Some entry under /lost+found should be repaired" + # compare files diff_files_xattrs $(hostname) $TMP/files $TMP/file_xattrs $files || error "Unable to diff files" diff --git a/lustre/utils/.gitignore b/lustre/utils/.gitignore index 3b8dc53..197a83d 100644 --- a/lustre/utils/.gitignore +++ b/lustre/utils/.gitignore @@ -19,7 +19,6 @@ /mount_lustre /tunefs_lustre /lreplicate -/ll_recover_lost_found_objs /ltrack_stats /lustre_rsync /ll_decode_filter_fid diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index b8afa14..90ef883 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -35,7 +35,7 @@ endif # TESTS if SERVER sbin_PROGRAMS += mkfs.lustre tunefs.lustre llverdev lr_reader \ - ll_recover_lost_found_objs ll_decode_filter_fid llog_reader + ll_decode_filter_fid llog_reader endif if LIBPTHREAD sbin_PROGRAMS += lhsmtool_posix @@ -61,10 +61,6 @@ lustre_rsync_SOURCES = lustre_rsync.c obd.c lustre_cfg.c lustre_rsync.h lustre_rsync_LDADD := liblustreapi.a $(LIBPTLCTL) $(LIBREADLINE) $(PTHREAD_LIBS) lustre_rsync_DEPENDENCIES := $(LIBPTLCTL) liblustreapi.a -ll_recover_lost_found_objs_SOURCES = ll_recover_lost_found_objs.c -ll_recover_lost_found_objs_LDADD := $(LIBPTLCTL) -ll_recover_lost_found_objs_DEPENDENCIES := $(LIBPTLCTL) - if EXT2FS_DEVEL EXT2FSLIB = -lext2fs E2PLIB = -le2p diff --git a/lustre/utils/ll_recover_lost_found_objs.c b/lustre/utils/ll_recover_lost_found_objs.c deleted file mode 100644 index cd9a6f4..0000000 --- a/lustre/utils/ll_recover_lost_found_objs.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * 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 version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2012, 2014, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/utils/ll_recover_lost_found_objs.c - * - * Tool for recovering objects from lost+found that might result from a - * Lustre OST with a corrupted directory. Running e2fsck will fix the - * directory, but puts all of the objects into lost+found, where they are - * inaccessible to Lustre. - * - * Author: Kalpak Shah - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define MAX_GROUPS 64 - -int verbose; -bool dry_run; - -struct obd_group_info { - __u64 grp_last_id; - __u64 grp_seq; - struct list_head grp_list; -}; - -struct list_head grp_info_list; - -static void grp_info_list_destroy(struct list_head *list) -{ - struct obd_group_info *grp, *tmp; - - list_for_each_entry_safe(grp, tmp, list, grp_list) { - list_del_init(&grp->grp_list); - free(grp); - } -} - -static void usage(char *progname) -{ - fprintf(stderr, "Usage: %s [-hnv] -d directory\n" - "Recover Lustre OST objects put in lost+found by e2fsck.\n" - "\t-d: Check directory, usually '/lost+found' (required).\n" - "\t Alternately, verify object directories under '/O'.\n" - "\t-n: Do not modify filesystem, only report changes.\n" - "\t-h: Print help message.\n" - "\t-v: Print changes verbosely.\n", - progname); - exit(1); -} - -static int _ll_sprintf(char *buf, size_t size, const char *func, int line, - const char *format, ...) -{ - int rc; - va_list ap; - - va_start(ap, format); - rc = vsnprintf(buf, size, format, ap); - if (!(rc > -1 && rc < size)) { - fprintf(stderr, - "error: %s:%d: path \"", func, line); - vfprintf(stderr, format, ap); - va_end(ap); - fprintf(stderr, "\" is too long\n"); - return 1; - } - va_end(ap); - return 0; -} - -#define ll_sprintf(buf, size, format, ...) \ - _ll_sprintf(buf, size, __FUNCTION__, __LINE__, format, ## __VA_ARGS__) - -static int mkdir_p(const char *dest_path, mode_t mode) -{ - struct stat stat_buf; - int rc; - - rc = stat(dest_path, &stat_buf); - if (rc == 0) { - if (S_ISDIR(stat_buf.st_mode)) - goto out; - if (!S_ISDIR(stat_buf.st_mode)) { - fprintf(stderr, "error: '%s' is not a directory (%o)\n", - dest_path, stat_buf.st_mode); - rc = -ENOTDIR; - goto out; - } - } else if (errno != ENOENT) { - rc = -errno; - fprintf(stderr, "error: error checking directory '%s': %s\n", - dest_path, strerror(errno)); - goto out; - } - - if (dry_run) { - fprintf(stderr, "dry_run: not creating directory '%s'\n", - dest_path); - rc = 0; - goto out; - } - - rc = mkdir(dest_path, mode); - if (rc != 0) - fprintf(stderr, "error: creating directory '%s': %s\n", - dest_path, strerror(errno)); -out: - return rc; -} - -/* This is returning 0 for an error */ -static __u64 read_last_id(char *file_path) -{ - __u64 last_id; - int fd; - int count; - - fd = open(file_path, O_RDONLY); - if (fd < 0) { - if (errno != ENOENT) - fprintf(stderr, "error: opening '%s': %s\n", - file_path, strerror(errno)); - return 0; - } - - count = read(fd, &last_id, sizeof(last_id)); - if (count < 0) { - fprintf(stderr, "error: reading file '%s': %s\n", - file_path, strerror(errno)); - close(fd); - return 0; - } - if (count != sizeof(last_id)) { - fprintf(stderr, "error: only read %d bytes from '%s'\n", - count, file_path); - close(fd); - return 0; - } - - close(fd); - return le64_to_cpu(last_id); -} - -struct obd_group_info *find_or_create_grp(struct list_head *list, __u64 seq, - const char *mount) -{ - struct obd_group_info *grp; - struct list_head *entry; - char tmp_path[PATH_MAX]; - char seq_name[32]; - int retval; - __u64 tmp_last_id; - - list_for_each(entry, list) { - grp = (struct obd_group_info *)list_entry(entry, - struct obd_group_info, - grp_list); - if (grp->grp_seq == seq) - return grp; - } - - grp = malloc(sizeof(struct obd_group_info)); - if (grp == NULL) - return NULL; - - sprintf(seq_name, (fid_seq_is_rsvd(seq) || - fid_seq_is_mdt0(seq)) ? LPU64 : LPX64i, - fid_seq_is_idif(seq) ? 0 : seq); - - /* Check whether the obj dir has been created */ - if (ll_sprintf(tmp_path, PATH_MAX, "%s/O/%s", mount, seq_name)) { - free(grp); - return NULL; - } - - retval = mkdir_p(tmp_path, 0700); - if (retval < 0) { - free(grp); - fprintf(stderr, "error: creating directory %s: %s\n", - tmp_path, strerror(errno)); - return NULL; - } - - if (ll_sprintf(tmp_path, PATH_MAX, "%s/O/%s/LAST_ID", - mount, seq_name)) { - free(grp); - return NULL; - } - - /* - * Object ID needs to be verified against last_id. - * LAST_ID file may not be present in the group directory - * due to corruption. In case of any error try to recover - * as many objects as possible by setting last_id to ~0ULL. - */ - tmp_last_id = read_last_id(tmp_path); - if (tmp_last_id == 0) - tmp_last_id = ~0ULL; - grp->grp_last_id = tmp_last_id; - grp->grp_seq = seq; - - list_add(&grp->grp_list, list); - return grp; -} - -static unsigned filetype_dir_table[] = { - [0]= DT_UNKNOWN, - [S_IFIFO]= DT_FIFO, - [S_IFCHR] = DT_CHR, - [S_IFDIR] = DT_DIR, - [S_IFBLK] = DT_BLK, - [S_IFREG] = DT_REG, - [S_IFLNK] = DT_LNK, - [S_IFSOCK]= DT_SOCK, -#if defined(DT_DOOR) && defined(S_IFDOOR) - [S_IFDOOR]= DT_DOOR, -#endif -}; - -static int traverse_lost_found(char *src_dir, const char *mount_path) -{ - DIR *dir_ptr; - struct lustre_mdt_attrs lma; - struct dirent64 *dirent; - __u64 ff_seq, ff_objid; - char *file_path; - char dest_path[PATH_MAX]; - struct stat st; - int obj_exists, xattr_len; - int len, ret = 0, error = 0; - char seq_name[32]; - char obj_name[32]; - struct obd_group_info *grp_info; - - len = strlen(src_dir); - - dir_ptr = opendir(src_dir); - if (!dir_ptr) { - fprintf(stderr, "error: opening directory: %s\n", - strerror(errno)); - return 1; - } - - while ((dirent = readdir64(dir_ptr)) != NULL) { - if (!strcmp(dirent->d_name, ".") || - !strcmp(dirent->d_name, "..")) - continue; - - src_dir[len] = 0; - if ((len + strlen(dirent->d_name) + 2) > PATH_MAX) { - fprintf(stderr, "error: %s/%s: path too long\n", - src_dir, dirent->d_name); - break; - } - strcat(src_dir, "/"); - strcat(src_dir, dirent->d_name); - - if (dirent->d_type == DT_UNKNOWN) { - ret = stat(src_dir, &st); - if (ret == -1) { - fprintf(stderr, - "error: stating %s: %s\n", - src_dir, strerror(errno)); - continue; - } - dirent->d_type = filetype_dir_table[st.st_mode & - S_IFMT]; - if (dirent->d_type == DT_UNKNOWN) { - fprintf(stderr, - "error: %s of unknown type 0%o\n", - src_dir, st.st_mode); - continue; - } - } - - switch(dirent->d_type) { - case DT_DIR: - ret = traverse_lost_found(src_dir, mount_path); - if (ret) { - closedir(dir_ptr); - return ret; - } - break; - - case DT_REG: - file_path = src_dir; - xattr_len = getxattr(file_path, "trusted.lma", - (void *)&lma, sizeof(lma)); - if (xattr_len == -1 || xattr_len < sizeof(lma)) { - struct filter_fid_old ff; - - /* try old filter_fid EA */ - xattr_len = getxattr(file_path, "trusted.fid", - (void *)&ff, sizeof(ff)); - /* It's very much possible that we don't find any - * FID on precreated or unused objects or LAST_ID. - * The xattr needs to hold the full filter_fid_old - * with the OID/parent to be useful. */ - if (xattr_len == -1 || xattr_len < sizeof(ff)) - continue; - - ff_seq = le64_to_cpu(ff.ff_seq); - ff_objid = le64_to_cpu(ff.ff_objid); - if (verbose) - printf(DOSTID": ", ff_seq, ff_objid); - } else { - if (verbose) - printf(DFID": ", PFID(&lma.lma_self_fid)); - ff_seq = le64_to_cpu(lma.lma_self_fid.f_seq); - ff_objid = le32_to_cpu(lma.lma_self_fid.f_oid); - } - - sprintf(seq_name, (fid_seq_is_rsvd(ff_seq) || - fid_seq_is_mdt0(ff_seq)) ? LPU64 : LPX64i, - fid_seq_is_idif(ff_seq) ? 0 : ff_seq); - - /* LAST_ID uses OID = 0. It will be regenerated later. */ - if (ff_objid == 0) { - if (verbose) - printf("'%s': LAST_ID\n", file_path); - continue; - } - - sprintf(obj_name, (fid_seq_is_rsvd(ff_seq) || - fid_seq_is_mdt0(ff_seq) || - fid_seq_is_idif(ff_seq)) ? - LPU64 : LPX64i, ff_objid); - - grp_info = find_or_create_grp(&grp_info_list, ff_seq, - mount_path); - if (grp_info == NULL) { - closedir(dir_ptr); - return 1; - } - - /* Might need to create the parent directory for this object */ - if (ll_sprintf(dest_path, PATH_MAX, "%s/O/%s/d"LPU64, - mount_path, seq_name, ff_objid % 32)) { - closedir(dir_ptr); - return 1; - } - - /* The O/{seq} directory was created in find_or_create_grp() */ - ret = mkdir_p(dest_path, 0700); - if (ret < 0) { - closedir(dir_ptr); - return ret; - } - - if (ff_objid > grp_info->grp_last_id) { - fprintf(stderr, "error: file skipped because object ID " - "greater than LAST_ID\nFilename: %s\n" - "Group: "LPU64"\nObjectid: "LPU64"\n" - "LAST_ID: "LPU64, file_path, ff_seq, ff_objid, - grp_info->grp_last_id); - continue; - } - - /* move file from lost+found to proper object directory */ - if (ll_sprintf(dest_path, PATH_MAX, - "%s/O/%s/d"LPU64"/%s", mount_path, - seq_name, ff_objid % 32, obj_name)) { - closedir(dir_ptr); - return 1; - } - - /* Source and destination are the same file, do nothing. */ - if (strcmp(file_path, dest_path) == 0) { - if (verbose) - printf("'%s': OK\n", file_path); - continue; - } - - obj_exists = 1; - ret = stat(dest_path, &st); - if (ret == 0) { - if (st.st_size == 0) - obj_exists = 0; - } else { - if (errno != ENOENT) - fprintf(stderr, "warning: stat for %s: %s\n", - dest_path, strerror(errno)); - obj_exists = 0; - } - - if (obj_exists) { - fprintf(dry_run ? stdout : stderr, - "%s: '%s' exists, will not replace with '%s'\n", - dry_run ? "dry_run" : "error", - dest_path, file_path); - continue; - } - if (dry_run) { - printf("dry_run: not renaming '%s' to '%s'\n", - file_path, dest_path); - continue; - } - if (rename(file_path, dest_path) < 0) { - fprintf(stderr, "error: rename failed for '%s': %s\n", - file_path, strerror(errno)); - error++; - continue; - } - - printf("object '%s' restored.\n", dest_path); - break; - } - } - - closedir(dir_ptr); - - return error; -} - -/* - * If LAST_ID file is not present in some group then restore it with the highest - * object ID found in that group. By the time we come here all possible objects - * have been restored. - */ -static int check_last_id(const char *mount_path) -{ - char lastid_path[PATH_MAX]; - char dirname[PATH_MAX], subdirname[PATH_MAX]; - DIR *groupdir, *subdir; - struct stat st; - struct dirent *dirent; - __u64 group; - __u64 max_objid; - int fd; - int ret; - - for (group = 0; group < MAX_GROUPS; group++) { - max_objid = 0; - - if (ll_sprintf(dirname, PATH_MAX, "%s/O/"LPU64, - mount_path, group)) - return 1; - if (ll_sprintf(lastid_path, PATH_MAX, "%s/LAST_ID", dirname)) - return 1; - - if (stat(lastid_path, &st) == 0) - continue; - - groupdir = opendir(dirname); - if (groupdir == NULL) { - if (errno != ENOENT) - fprintf(stderr, "error: opening %s: %s\n", - dirname, strerror(errno)); - continue; - } - - while ((dirent = readdir(groupdir)) != NULL) { - if (!strcmp(dirent->d_name, ".") || - !strcmp(dirent->d_name, "..")) - continue; - - if (ll_sprintf(subdirname, PATH_MAX, "%s/%s", - dirname, dirent->d_name)) { - closedir(groupdir); - return 1; - } - subdir = opendir(subdirname); - if (subdir == NULL) { - fprintf(stderr, "error: opening %s: %s\n", - subdirname, strerror(errno)); - continue; - } - - while ((dirent = readdir(subdir)) != NULL) { - __u64 objid; - char *end; - - if (!strcmp(dirent->d_name, ".") || - !strcmp(dirent->d_name, "..")) - continue; - - objid = strtoull(dirent->d_name, &end, 0); - if (end == dirent->d_name || *end != 0) { - fprintf(stderr, "error: unknown object" - "ID %s/%s\n", subdirname, - dirent->d_name); - continue; - } - if (objid > max_objid) - max_objid = objid; - } - closedir(subdir); - } - closedir(groupdir); - - if (dry_run) { - fprintf(stderr, "dry_run: not updating '%s' to " - LPU64"\n", lastid_path, max_objid); - return 0; - } - fd = open(lastid_path, O_RDWR | O_CREAT, 0700); - if (fd < 0) { - fprintf(stderr, "error: open '%s' failed: %s\n", - lastid_path, strerror(errno)); - return 1; - } - - max_objid = cpu_to_le64(max_objid); - ret = write(fd, &max_objid, sizeof(__u64)); - if (ret < sizeof(__u64)) { - fprintf(stderr, "error: write '%s' failed: %s\n", - lastid_path, strerror(errno)); - close(fd); - return 1; - } - - close(fd); - } - - return 0; -} - -int main(int argc, char **argv) -{ - char *progname; - char src_dir[PATH_MAX] = ""; - char mount_path[PATH_MAX]; - char tmp_path[PATH_MAX]; - int rc; - int c; - - progname = strrchr(argv[0], '/'); - if (progname++ == NULL) - progname = argv[0]; - - while ((c = getopt(argc, argv, "d:hnv")) != EOF) { - switch (c) { - case 'd': - if (chdir(optarg)) { - fprintf(stderr, "error: chdir to %s: %s\n", - optarg, strerror(errno)); - return 1; - } - if (getcwd(src_dir, PATH_MAX) == NULL) { - fprintf(stderr, - "error: getcwd of lost+found: %s\n", - strerror(errno)); - return 1; - } - if (chdir("..")) { - fprintf(stderr, "error: chdir to \"..\": %s\n", - strerror(errno)); - return 1; - } - if (getcwd(mount_path, PATH_MAX) == NULL) { - fprintf(stderr, - "error: getcwd of mount point: %s\n", - strerror(errno)); - return 1; - } - if (!strcmp(src_dir, mount_path)) { - fprintf(stderr, - "error: root directory is detected\n"); - return 1; - } - fprintf(stdout, "%s: %sscan directory path: %s\n", - progname, dry_run ? "read_only " : "", src_dir); - break; - case 'n': - dry_run = true; - break; - case 'v': - verbose = true; - break; - case 'h': - usage(progname); - default: - fprintf(stderr, "%s: bad option '%c'\n", - progname, c); - usage(progname); - } - } - - if (src_dir[0] == 0) - usage(progname); - - /* Check if 'O' directory exists and create it if needed */ - if (ll_sprintf(tmp_path, PATH_MAX, "%s/O", mount_path)) - return 1; - - rc = mkdir_p(tmp_path, 0700); - if (rc == -1) { - fprintf(stderr, "error: creating objects directory %s:" - " %s\n", tmp_path, strerror(errno)); - return 1; - } - - INIT_LIST_HEAD(&grp_info_list); - rc = traverse_lost_found(src_dir, mount_path); - if (rc) { - fprintf(stderr, "error: traversing lost+found looking for " - "orphan objects.\n"); - goto grp_destory; - } - - rc = check_last_id(mount_path); - if (rc) - fprintf(stderr, "error: while checking/restoring LAST_ID.\n"); - -grp_destory: - grp_info_list_destroy(&grp_info_list); - - printf("%s: scan finished: rc = %d\n", progname, rc); - return rc; -} -- 1.8.3.1