* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2016, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
*/
/*
* lustre/utils/lustre_lfsck.c
#include <time.h>
#include "obdctl.h"
+#include "lustreapi_internal.h"
-#include <lustre/lustre_lfsck_user.h>
-#include <lnet/lnetctl.h>
-#include <lustre_ioctl.h>
+#include <linux/lnet/lnetctl.h>
+#include <linux/lustre/lustre_ioctl.h>
+#include <linux/lustre/lustre_lfsck_user.h>
/* Needs to be last to avoid clashes */
#include <libcfs/util/ioctl.h>
#include <libcfs/util/param.h>
static struct option long_opt_start[] = {
- {"device", required_argument, 0, 'M'},
- {"all", no_argument, 0, 'A'},
- {"create_ostobj", optional_argument, 0, 'c'},
- {"create-ostobj", optional_argument, 0, 'c'},
- {"create_mdtobj", optional_argument, 0, 'C'},
- {"create-mdtobj", optional_argument, 0, 'C'},
- {"delay_create_ostobj", optional_argument, 0, 'd'},
- {"delay-create-ostobj", optional_argument, 0, 'd'},
- {"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'},
- {"window_size", required_argument, 0, 'w'},
- {"window-size", required_argument, 0, 'w'},
- {0, 0, 0, 0 }
-};
+{ .val = 'A', .name = "all", .has_arg = no_argument },
+{ .val = 'c', .name = "create_ostobj", .has_arg = optional_argument },
+{ .val = 'c', .name = "create-ostobj", .has_arg = optional_argument },
+{ .val = 'C', .name = "create_mdtobj", .has_arg = optional_argument },
+{ .val = 'C', .name = "create-mdtobj", .has_arg = optional_argument },
+{ .val = 'd', .name = "delay_create_ostobj", .has_arg = optional_argument },
+{ .val = 'd', .name = "delay-create-ostobj", .has_arg = optional_argument },
+{ .val = 'e', .name = "error", .has_arg = required_argument },
+{ .val = 'h', .name = "help", .has_arg = no_argument },
+{ .val = 'M', .name = "device", .has_arg = required_argument },
+{ .val = 'n', .name = "dryrun", .has_arg = optional_argument },
+{ .val = 'o', .name = "orphan", .has_arg = no_argument },
+{ .val = 'r', .name = "reset", .has_arg = no_argument },
+{ .val = 's', .name = "speed", .has_arg = required_argument },
+{ .val = 't', .name = "type", .has_arg = required_argument },
+{ .val = 'w', .name = "window_size", .has_arg = required_argument },
+{ .val = 'w', .name = "window-size", .has_arg = required_argument },
+{ .name = NULL } };
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 }
-};
+ { .val = 'A', .name = "all", .has_arg = no_argument },
+ { .val = 'h', .name = "help", .has_arg = no_argument },
+ { .val = 'M', .name = "device", .has_arg = required_argument },
+ { .name = NULL } };
static struct option long_opt_query[] = {
- {"device", required_argument, 0, 'M'},
- {"type", required_argument, 0, 't'},
- {"help", no_argument, 0, 'h'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0 }
-};
+ { .val = 'h', .name = "help", .has_arg = no_argument },
+ { .val = 'M', .name = "device", .has_arg = required_argument },
+ { .val = 't', .name = "type", .has_arg = required_argument },
+ { .val = 'w', .name = "wait", .has_arg = no_argument },
+ { .name = NULL } };
struct lfsck_type_name {
char *ltn_name;
enum lfsck_type ltn_type;
};
+/* Note types must be in order of increasing value so we can iterate through
+ * this correctly. See enum lfsck_type for values. LU-9894. */
static struct lfsck_type_name lfsck_types_names[] = {
- { "scrub", LFSCK_TYPE_SCRUB },
- { "layout", LFSCK_TYPE_LAYOUT },
- { "namespace", LFSCK_TYPE_NAMESPACE },
- { "default", LFSCK_TYPES_DEF },
- { "all", LFSCK_TYPES_SUPPORTED },
- { NULL, 0 }
-};
+ { .ltn_name = "layout", .ltn_type = LFSCK_TYPE_LAYOUT },
+ { .ltn_name = "namespace", .ltn_type = LFSCK_TYPE_NAMESPACE },
+ { .ltn_name = "scrub", .ltn_type = LFSCK_TYPE_SCRUB },
+ { .ltn_name = "all", .ltn_type = LFSCK_TYPES_SUPPORTED },
+ { .ltn_name = "default", .ltn_type = LFSCK_TYPES_DEF },
+ { .ltn_name = NULL } };
static enum lfsck_type lfsck_name2type(const char *name)
{
static void usage_start(void)
{
- fprintf(stderr, "start LFSCK\n"
+ fprintf(stdout, "start LFSCK\n"
"usage:\n"
"lfsck_start [-M | --device {MDT,OST}_device]\n"
" [-A | --all] [-c | --create_ostobj [on | off]]\n"
static void usage_stop(void)
{
- fprintf(stderr, "stop LFSCK\n"
+ fprintf(stdout, "stop LFSCK\n"
"usage:\n"
"lfsck_stop [-M | --device {MDT,OST}_device]\n"
" [-A | --all] [-h | --help]\n"
static void usage_query(void)
{
- fprintf(stderr, "check the LFSCK global status\n"
+ fprintf(stdout, "check the LFSCK global status\n"
"usage:\n"
"lfsck_query [-M | --device MDT_device] [-h | --help]\n"
" [-t | --type check_type[,check_type...]]\n"
int types, bool multipe_devices)
{
glob_t param = { 0 };
+ size_t count = 0;
char *ptr;
int rc;
int i;
}
}
- if (param.gl_pathc == 1)
+ /* we have both sysfs and debugfs entries so to get the correct number
+ * of devices only count the entries in the sysfs tree
+ */
+ for (i = 0; i < param.gl_pathc; i++) {
+ if (strstr(param.gl_pathv[i], "/sys/kernel/debug/lustre"))
+ continue;
+ count++;
+ }
+
+ if (count == 1)
goto pack;
if (!multipe_devices) {
}
for (i = 1; i < param.gl_pathc; i++) {
- char *ptr2 = strrchr(param.gl_pathv[i], '-');
+ char *ptr2;
+
+ if (strstr(param.gl_pathv[i], "/sys/kernel/debug/lustre"))
+ continue;
+ ptr2 = strrchr(param.gl_pathv[i], '-');
if (ptr2 == NULL) {
rc = -EINVAL;
goto out;
char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
char device[MAX_OBD_NAME];
struct lfsck_start start;
- char *optstring = "Ac::C::d::e:hM:n::ors:t:w:";
+ char *short_opts = "Ac::C::d::e:hM:n::ors:t:w:";
int opt, index, rc, val, i;
memset(&data, 0, sizeof(data));
/* Reset the 'optind' for the case of getopt_long() called multiple
* times under the same lctl. */
optind = 0;
- while ((opt = getopt_long(argc, argv, optstring, long_opt_start,
+ while ((opt = getopt_long(argc, argv, short_opts, long_opt_start,
&index)) != EOF) {
switch (opt) {
case 'A':
data.ioc_inlbuf1 = (char *)&start;
data.ioc_inllen1 = sizeof(start);
memset(buf, 0, sizeof(rawbuf));
- rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
+ rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf));
if (rc != 0) {
fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
return rc;
return rc;
}
- obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
+ llapi_ioctl_unpack(&data, buf, sizeof(rawbuf));
printf("Started LFSCK on the device %s: scrub", device);
for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++) {
if (start.ls_active & lfsck_types_names[i].ltn_type) {
char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
char device[MAX_OBD_NAME];
struct lfsck_stop stop;
- char *optstring = "AhM:";
+ char *short_opts = "AhM:";
int opt, index, rc;
memset(&data, 0, sizeof(data));
/* Reset the 'optind' for the case of getopt_long() called multiple
* times under the same lctl. */
optind = 0;
- while ((opt = getopt_long(argc, argv, optstring, long_opt_stop,
+ while ((opt = getopt_long(argc, argv, short_opts, long_opt_stop,
&index)) != EOF) {
switch (opt) {
case 'A':
data.ioc_inlbuf1 = (char *)&stop;
data.ioc_inllen1 = sizeof(stop);
memset(buf, 0, sizeof(rawbuf));
- rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
+ rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf));
if (rc != 0) {
fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
return rc;
data.ioc_inlbuf1 = (char *)&query;
data.ioc_inllen1 = sizeof(query);
memset(buf, 0, sizeof(rawbuf));
- rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
+ rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf));
if (rc != 0) {
fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
return rc;
return rc;
}
- obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
+ llapi_ioctl_unpack(&data, buf, sizeof(rawbuf));
for (i = 0, type = 1 << i; i < LFSCK_TYPE_BITS; i++, type = 1 << i) {
const char *name;
int j;
printf("%s_osts_%s: %d\n", name,
lfsck_status2name(j), query.lu_osts_count[i][j]);
- printf("%s_repaired: %llu\n", name, query.lu_repaired[i]);
+ printf("%s_repaired: %llu\n", name,
+ (unsigned long long)query.lu_repaired[i]);
}
return 0;