X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=sidebyside;f=lustre%2Futils%2Flustre_lfsck.c;h=4f04f0241ef9fce17771f4f25ec724c43440228c;hb=281671b5ee43c2aea5d5b708aadf10fd1df45b16;hp=403219ab23e9a267b09dfa5f340bb8a09d3bfb2e;hpb=0d8a372d30572077fbf943c7d3f32e3d5d7ee3d5;p=fs%2Flustre-release.git diff --git a/lustre/utils/lustre_lfsck.c b/lustre/utils/lustre_lfsck.c index 403219a..4f04f02 100644 --- a/lustre/utils/lustre_lfsck.c +++ b/lustre/utils/lustre_lfsck.c @@ -20,7 +20,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2012 Whamcloud, Inc. + * Copyright (c) 2012, 2013, Intel Corporation. */ /* * lustre/utils/lustre_lfsck.c @@ -40,57 +40,83 @@ #include "obdctl.h" -#include #include #include #include +#include static struct option long_opt_start[] = { - {"device", required_argument, 0, 'M'}, - {"error", required_argument, 0, 'e'}, - {"help", no_argument, 0, 'h'}, - {"dryrun", required_argument, 0, 'n'}, - {"reset", no_argument, 0, 'r'}, - {"speed", required_argument, 0, 's'}, - {"type", required_argument, 0, 't'}, - {0, 0, 0, 0} + {"device", required_argument, 0, 'M'}, + {"all", no_argument, 0, 'A'}, + {"create_ostobj", optional_argument, 0, 'c'}, + {"error", required_argument, 0, 'e'}, + {"help", no_argument, 0, 'h'}, + {"dryrun", optional_argument, 0, 'n'}, + {"orphan", no_argument, 0, 'o'}, + {"reset", no_argument, 0, 'r'}, + {"speed", required_argument, 0, 's'}, + {"type", required_argument, 0, 't'}, + {"windows", required_argument, 0, 'w'}, + {0, 0, 0, 0 } }; static struct option long_opt_stop[] = { {"device", required_argument, 0, 'M'}, + {"all", no_argument, 0, 'A'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; -struct lfsck_types_names { - char *name; - __u16 type; +struct lfsck_type_name { + char *name; + int namelen; + enum lfsck_type type; }; -static struct lfsck_types_names lfsck_types_names[3] = { - { "layout", LT_LAYOUT }, - { "DNE", LT_DNE }, - { 0, 0 } +static struct lfsck_type_name lfsck_types_names[] = { + { "layout", 6, LT_LAYOUT }, + { "namespace", 9, LT_NAMESPACE}, + { 0, 0, 0 } }; +static inline int lfsck_name2type(const char *name, int namelen) +{ + int i = 0; + + while (lfsck_types_names[i].name != NULL) { + if (namelen == lfsck_types_names[i].namelen && + strncmp(lfsck_types_names[i].name, name, namelen) == 0) + return lfsck_types_names[i].type; + i++; + } + return 0; +} + static void usage_start(void) { fprintf(stderr, "Start LFSCK.\n" "SYNOPSIS:\n" - "lfsck_start <-M | --device MDT_device>\n" + "lfsck_start <-M | --device [MDT,OST]_device>\n" + " [-A | --all] [-c | --create_ostobj [swtich]]\n" " [-e | --error error_handle] [-h | --help]\n" - " [-n | --dryrun switch] [-r | --reset]\n" - " [-s | --speed speed_limit]\n" + " [-n | --dryrun [switch]] [-o | --orphan]\n" + " [-r | --reset] [-s | --speed speed_limit]\n" " [-t | --type lfsck_type[,lfsck_type...]]\n" + " [-w | --windows win_size]\n" "OPTIONS:\n" - "-M: The MDT device to start LFSCK on.\n" + "-M: The device to start LFSCK/scrub on.\n" + "-A: Start LFSCK on all MDT devices.\n" + "-c: create the lost OST-object for dangling LOV EA. " + "'off'(default) or 'on'.\n" "-e: Error handle, 'continue'(default) or 'abort'.\n" "-h: Help information.\n" "-n: Check without modification. 'off'(default) or 'on'.\n" + "-o: handle orphan objects.\n" "-r: Reset scanning start position to the device beginning.\n" "-s: How many items can be scanned at most per second. " "'%d' means no limit (default).\n" - "-t: The LFSCK type(s) to be started.\n", + "-t: The LFSCK type(s) to be started.\n" + "-w: The windows size for async requests pipeline.\n", LFSCK_SPEED_NO_LIMIT); } @@ -98,9 +124,11 @@ static void usage_stop(void) { fprintf(stderr, "Stop LFSCK.\n" "SYNOPSIS:\n" - "lfsck_stop <-M | --device MDT_device> [-h | --help]\n" + "lfsck_stop <-M | --device [MDT,OST]_device>\n" + "[-A | --all] [-h | --help]\n" "OPTIONS:\n" - "-M: The MDT device to stop LFSCK on.\n" + "-M: The device to stop LFSCK/scrub on.\n" + "-A: Stop LFSCK on all MDT devices.\n" "-h: Help information.\n"); } @@ -109,7 +137,7 @@ static int lfsck_pack_dev(struct obd_ioctl_data *data, char *device, char *arg) int len = strlen(arg) + 1; if (len > MAX_OBD_NAME) { - fprintf(stderr, "MDT device name is too long. " + fprintf(stderr, "device name is too long. " "Valid length should be less than %d\n", MAX_OBD_NAME); return -EINVAL; } @@ -127,8 +155,8 @@ int jt_lfsck_start(int argc, char **argv) char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char device[MAX_OBD_NAME]; struct lfsck_start start; - char *optstring = "M:e:hn:rs:t:"; - int opt, index, rc, val, i; + char *optstring = "M:Ac::e:hn::ors:t:w:"; + int opt, index, rc, val, i, type; memset(&data, 0, sizeof(data)); memset(&start, 0, sizeof(start)); @@ -147,6 +175,22 @@ int jt_lfsck_start(int argc, char **argv) if (rc != 0) return rc; break; + case 'A': + start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST; + break; + case 'c': + if (optarg == NULL || strcmp(optarg, "on") == 0) { + start.ls_flags |= LPF_CREATE_OSTOBJ; + } else if (strcmp(optarg, "off") != 0) { + fprintf(stderr, "Invalid switch: %s. " + "The valid switch should be: 'on' " + "or 'off' (default) without blank, " + "or empty. For example: '-non' or " + "'-noff' or '-n'.\n", optarg); + return -EINVAL; + } + start.ls_valid |= LSV_CREATE_OSTOBJ; + break; case 'e': if (strcmp(optarg, "abort") == 0) { start.ls_flags |= LPF_FAILOUT; @@ -162,16 +206,22 @@ int jt_lfsck_start(int argc, char **argv) usage_start(); return 0; case 'n': - if (strcmp(optarg, "on") == 0) { + if (optarg == NULL || strcmp(optarg, "on") == 0) { start.ls_flags |= LPF_DRYRUN; } else if (strcmp(optarg, "off") != 0) { - fprintf(stderr, "Invalid dryrun switch: %s. " - "The valid value shou be: 'off'" - "(default) or 'on'\n", optarg); + fprintf(stderr, "Invalid switch: %s. " + "The valid switch should be: 'on' " + "or 'off' (default) without blank, " + "or empty. For example: '-non' or " + "'-noff' or '-n'.\n", optarg); return -EINVAL; } start.ls_valid |= LSV_DRYRUN; break; + case 'o': + start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST | + LPF_ORPHAN; + break; case 'r': start.ls_flags |= LPF_RESET; break; @@ -197,33 +247,46 @@ int jt_lfsck_start(int argc, char **argv) c = *p; *p = 0; - for (i = 0; i < 3; i++) { - if (strcmp(str, - lfsck_types_names[i].name) - == 0) { - start.ls_active |= - lfsck_types_names[i].type; - break; - } + type = lfsck_name2type(str, strlen(str)); + if (type == 0) { + fprintf(stderr, "Invalid type (%s).\n" + "The valid value should be " + "'layout' or 'namespace'.\n", + str); + *p = c; + return -EINVAL; } + *p = c; str = p; - if (i >= 3 ) { - fprintf(stderr, "Invalid LFSCK type.\n" - "The valid value should be " - "'layout' or 'DNE'.\n"); - return -EINVAL; - } + start.ls_active |= type; } if (start.ls_active == 0) { fprintf(stderr, "Miss LFSCK type(s).\n" "The valid value should be " - "'layout' or 'DNE'.\n"); + "'layout' or 'namespace'.\n"); return -EINVAL; } break; } + case 'w': + val = atoi(optarg); + if (val < 0 || val > LFSCK_ASYNC_WIN_MAX) { + fprintf(stderr, + "Too large async windows size, " + "which may cause memory issues. " + "The valid range is [0 - %u]. " + "If you do not want to restrict " + "the windows size for async reqeusts " + "pipeline, just set it as 0.\n", + LFSCK_ASYNC_WIN_MAX); + return -EINVAL; + } + + start.ls_async_windows = val; + start.ls_valid |= LSV_ASYNC_WINDOWS; + break; default: fprintf(stderr, "Invalid option, '-h' for help.\n"); return -EINVAL; @@ -231,9 +294,15 @@ int jt_lfsck_start(int argc, char **argv) } if (data.ioc_inlbuf4 == NULL) { - fprintf(stderr, - "Must sepcify MDT device to start LFSCK.\n"); - return -EINVAL; + if (lcfg_get_devname() != NULL) { + rc = lfsck_pack_dev(&data, device, lcfg_get_devname()); + if (rc != 0) + return rc; + } else { + fprintf(stderr, + "Must specify device to start LFSCK.\n"); + return -EINVAL; + } } data.ioc_inlbuf1 = (char *)&start; @@ -253,14 +322,16 @@ int jt_lfsck_start(int argc, char **argv) obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); if (start.ls_active == 0) { - printf("Started LFSCK on the MDT device %s", device); + printf("Started LFSCK on the device %s", device); } else { - printf("Started LFSCK on the MDT device %s:", device); - for (i = 0; i < 2; i++) { + printf("Started LFSCK on the device %s:", device); + i = 0; + while (lfsck_types_names[i].name != NULL) { if (start.ls_active & lfsck_types_names[i].type) { printf(" %s", lfsck_types_names[i].name); start.ls_active &= ~lfsck_types_names[i].type; } + i++; } if (start.ls_active != 0) printf(" unknown(0x%x)", start.ls_active); @@ -274,10 +345,12 @@ int jt_lfsck_stop(int argc, char **argv) struct obd_ioctl_data data; char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char device[MAX_OBD_NAME]; - char *optstring = "M:h"; + struct lfsck_stop stop; + char *optstring = "M:Ah"; int opt, index, rc; memset(&data, 0, sizeof(data)); + memset(&stop, 0, sizeof(stop)); memset(device, 0, MAX_OBD_NAME); /* Reset the 'optind' for the case of getopt_long() called multiple @@ -291,6 +364,9 @@ int jt_lfsck_stop(int argc, char **argv) if (rc != 0) return rc; break; + case 'A': + stop.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST; + break; case 'h': usage_stop(); return 0; @@ -301,11 +377,19 @@ int jt_lfsck_stop(int argc, char **argv) } if (data.ioc_inlbuf4 == NULL) { - fprintf(stderr, - "Must sepcify MDT device to stop LFSCK.\n"); - return -EINVAL; + if (lcfg_get_devname() != NULL) { + rc = lfsck_pack_dev(&data, device, lcfg_get_devname()); + if (rc != 0) + return rc; + } else { + fprintf(stderr, + "Must specify device to stop LFSCK.\n"); + return -EINVAL; + } } + data.ioc_inlbuf1 = (char *)&stop; + data.ioc_inllen1 = sizeof(stop); memset(buf, 0, sizeof(rawbuf)); rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { @@ -319,6 +403,6 @@ int jt_lfsck_stop(int argc, char **argv) return rc; } - printf("Stopped LFSCK on the MDT device %s.\n", device); + printf("Stopped LFSCK on the device %s.\n", device); return 0; }