2022-03-08 11:35:40 +08:00
|
|
|
From 2051a9f6ea12dc90c9c5b90912b79984d9064d0d Mon Sep 17 00:00:00 2001
|
2020-01-10 17:13:17 +08:00
|
|
|
From: chenminhua <chenminhua1@huawei.com>
|
|
|
|
|
Date: Mon, 2 Apr 2018 04:01:04 -0400
|
2022-03-08 11:35:40 +08:00
|
|
|
Subject: [PATCH] remove local disk from pathvec
|
|
|
|
|
|
|
|
|
|
Here we provide a multipath_private.conf to enable remove_local_disk.
|
|
|
|
|
When enable remove_local_disk, the multipath devices are only created
|
|
|
|
|
on fc or iscsi devices.
|
2020-01-10 17:13:17 +08:00
|
|
|
|
|
|
|
|
[Changelog]:add upgrade path
|
|
|
|
|
[Author]:chenminhua
|
|
|
|
|
---
|
2022-03-08 11:35:40 +08:00
|
|
|
libmultipath/discovery.c | 137 ++++++++++++++++++++++++++++++++++++--
|
2021-11-23 21:49:34 +08:00
|
|
|
libmultipath/discovery.h | 1 +
|
|
|
|
|
libmultipath/libmultipath.version | 1 +
|
|
|
|
|
multipathd/main.c | 4 ++
|
2022-03-08 11:35:40 +08:00
|
|
|
4 files changed, 137 insertions(+), 6 deletions(-)
|
2020-01-10 17:13:17 +08:00
|
|
|
|
|
|
|
|
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
2022-03-08 11:35:40 +08:00
|
|
|
index f25fe9e..c9ebd49 100644
|
2020-01-10 17:13:17 +08:00
|
|
|
--- a/libmultipath/discovery.c
|
|
|
|
|
+++ b/libmultipath/discovery.c
|
2022-03-08 11:35:40 +08:00
|
|
|
@@ -37,6 +37,112 @@
|
2020-11-04 21:19:44 +08:00
|
|
|
#include "print.h"
|
2021-11-23 21:49:34 +08:00
|
|
|
#include "strbuf.h"
|
2020-01-10 17:13:17 +08:00
|
|
|
|
|
|
|
|
+const char *conf_file = "/etc/multipath_private.conf";
|
|
|
|
|
+static int conf_file_parsed = 0;
|
|
|
|
|
+static int should_remove_local_disk = 0;
|
|
|
|
|
+
|
|
|
|
|
+static void parse_config()
|
|
|
|
|
+{
|
|
|
|
|
+ FILE *fp = NULL;
|
|
|
|
|
+ char buffer[256] = {0};
|
|
|
|
|
+ char *str = NULL;
|
|
|
|
|
+ char *p = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ fp = fopen(conf_file, "r");
|
|
|
|
|
+ if (fp) {
|
|
|
|
|
+ while (fgets(buffer, sizeof(buffer), fp)) {
|
|
|
|
|
+ str = buffer;
|
|
|
|
|
+ /* skip the space */
|
|
|
|
|
+ while (isspace(*str))
|
|
|
|
|
+ str++;
|
|
|
|
|
+ /* skip the comment line */
|
|
|
|
|
+ if (strncmp(str, "#", 1) == 0)
|
|
|
|
|
+ continue;
|
|
|
|
|
+ /* skip line feed */
|
|
|
|
|
+ if((p = strchr(str, '\n')) != NULL)
|
|
|
|
|
+ *p = '\0';
|
|
|
|
|
+ if (strstr(str, "remove_local_disk") != NULL && (p = strstr(str, "=")) != NULL){
|
|
|
|
|
+ str = p + 1;
|
|
|
|
|
+ /* skip the space */
|
|
|
|
|
+ while (isspace(*str))
|
|
|
|
|
+ str++;
|
|
|
|
|
+ if (strcmp(str, "1") == 0){
|
|
|
|
|
+ should_remove_local_disk = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ fclose(fp);
|
|
|
|
|
+ fp = NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ conf_file_parsed = 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int get_should_remove_local_disk()
|
|
|
|
|
+{
|
|
|
|
|
+ if (!conf_file_parsed)
|
|
|
|
|
+ parse_config();
|
|
|
|
|
+ return should_remove_local_disk;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2022-03-08 11:35:40 +08:00
|
|
|
+/* Filter the local disks and remove them from pathvec.
|
|
|
|
|
+ * When bus type is SCSI and device type is (fc or scsi),
|
|
|
|
|
+ * return 0. This means the path is not local disk.
|
|
|
|
|
+ * When enable remove_local_disk, multipath only supports
|
|
|
|
|
+ * iscsi and fc device.
|
|
|
|
|
+ */
|
2020-01-10 17:13:17 +08:00
|
|
|
+static int
|
2022-03-08 11:35:40 +08:00
|
|
|
+transport(int type, int h)
|
2020-01-10 17:13:17 +08:00
|
|
|
+{
|
|
|
|
|
+ char buff[PATH_SIZE];
|
|
|
|
|
+ int len, off;
|
|
|
|
|
+ struct stat a_stat;
|
|
|
|
|
+
|
2022-03-08 11:35:40 +08:00
|
|
|
+ if (type != SYSFS_BUS_SCSI) {
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2020-01-10 17:13:17 +08:00
|
|
|
+ /* FC host */
|
|
|
|
|
+ strcpy(buff, "/sys");
|
|
|
|
|
+ strcat(buff, "/class/fc_host/");
|
|
|
|
|
+ len = strlen(buff);
|
|
|
|
|
+ snprintf(buff + len, PATH_SIZE - len, "host%d", h);
|
|
|
|
|
+ if ((stat(buff, &a_stat) >= 0) && S_ISDIR(a_stat.st_mode)) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ memset(buff, 0, PATH_SIZE);
|
|
|
|
|
+
|
|
|
|
|
+ /* iSCSI device */
|
|
|
|
|
+ strcpy(buff, "/sys");
|
|
|
|
|
+ strcat(buff, "/class/iscsi_host/");
|
|
|
|
|
+ off = strlen(buff);
|
|
|
|
|
+ snprintf(buff + off, PATH_SIZE - off, "host%d", h);
|
|
|
|
|
+ if ((stat(buff, &a_stat) >= 0) && S_ISDIR(a_stat.st_mode)) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ return 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int
|
|
|
|
|
+remove_local_path (vector pathvec, struct path *pp)
|
|
|
|
|
+{
|
|
|
|
|
+ int i = -1;
|
|
|
|
|
+
|
|
|
|
|
+ if(!get_should_remove_local_disk()){
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2022-03-08 11:35:40 +08:00
|
|
|
+ if (transport(pp->bus, pp->sg_id.host_no) == 0) {
|
2020-01-10 17:13:17 +08:00
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ((i = find_slot(pathvec, (void *)pp)) != -1) {
|
|
|
|
|
+ vector_del_slot(pathvec, i);
|
|
|
|
|
+ }
|
|
|
|
|
+ free_path(pp);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-07-16 18:51:36 +08:00
|
|
|
struct vpd_vendor_page vpd_vendor_pages[VPD_VP_ARRAY_SIZE] = {
|
|
|
|
|
[VPD_VP_UNDEF] = { 0x00, "undef" },
|
|
|
|
|
[VPD_VP_HP3PAR] = { 0xc0, "hp3par" },
|
2022-03-08 11:35:40 +08:00
|
|
|
@@ -128,22 +234,35 @@ path_discover (vector pathvec, struct config * conf,
|
2020-01-10 17:13:17 +08:00
|
|
|
{
|
2020-11-04 21:19:44 +08:00
|
|
|
struct path *pp;
|
|
|
|
|
char devt[BLK_DEV_SIZE];
|
2020-01-10 17:13:17 +08:00
|
|
|
+ int err = 1;
|
2020-11-04 21:19:44 +08:00
|
|
|
dev_t devnum = udev_device_get_devnum(udevice);
|
2020-01-10 17:13:17 +08:00
|
|
|
|
2020-11-04 21:19:44 +08:00
|
|
|
snprintf(devt, BLK_DEV_SIZE, "%d:%d",
|
|
|
|
|
major(devnum), minor(devnum));
|
|
|
|
|
pp = find_path_by_devt(pathvec, devt);
|
|
|
|
|
- if (!pp)
|
|
|
|
|
- return store_pathinfo(pathvec, conf,
|
|
|
|
|
- udevice, flag | DI_BLACKLIST,
|
|
|
|
|
- NULL);
|
|
|
|
|
- else
|
|
|
|
|
+ if (!pp) {
|
|
|
|
|
+ err = store_pathinfo(pathvec, conf,
|
|
|
|
|
+ udevice, flag | DI_BLACKLIST,
|
|
|
|
|
+ &pp);
|
|
|
|
|
+ if (err == 1)
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ if (err == 0)
|
|
|
|
|
+ remove_local_path(pathvec, pp);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
/*
|
|
|
|
|
* Don't use DI_BLACKLIST on paths already in pathvec. We rely
|
|
|
|
|
* on the caller to pre-populate the pathvec with valid paths
|
|
|
|
|
* only.
|
|
|
|
|
*/
|
|
|
|
|
- return pathinfo(pp, conf, flag);
|
|
|
|
|
+ err = pathinfo(pp, conf, flag);
|
|
|
|
|
+ if (err)
|
|
|
|
|
+ return err;
|
|
|
|
|
+
|
|
|
|
|
+ remove_local_path(pathvec, pp);
|
2020-01-10 17:13:17 +08:00
|
|
|
+ return err;
|
2020-11-04 21:19:44 +08:00
|
|
|
+ }
|
2020-01-10 17:13:17 +08:00
|
|
|
}
|
|
|
|
|
|
2020-07-16 18:51:36 +08:00
|
|
|
static void cleanup_udev_enumerate_ptr(void *arg)
|
2022-03-08 11:35:40 +08:00
|
|
|
@@ -2284,6 +2403,12 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
2020-07-16 18:51:36 +08:00
|
|
|
if (rc != PATHINFO_OK)
|
|
|
|
|
return rc;
|
2020-11-04 21:19:44 +08:00
|
|
|
|
2020-01-10 17:13:17 +08:00
|
|
|
+ /* free local device */
|
2022-03-08 11:35:40 +08:00
|
|
|
+ if (get_should_remove_local_disk() && transport(pp->bus, pp->sg_id.host_no)) {
|
2020-01-10 17:13:17 +08:00
|
|
|
+ condlog(3, "%s is a local device", pp->dev);
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
2020-11-04 21:19:44 +08:00
|
|
|
+
|
|
|
|
|
if (pp->bus == SYSFS_BUS_SCSI &&
|
|
|
|
|
pp->sg_id.proto_id == SCSI_PROTOCOL_USB &&
|
|
|
|
|
!conf->allow_usb_devices) {
|
2020-01-10 17:13:17 +08:00
|
|
|
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
|
2021-11-23 21:49:34 +08:00
|
|
|
index a5446b4..26b6db1 100644
|
2020-01-10 17:13:17 +08:00
|
|
|
--- a/libmultipath/discovery.h
|
|
|
|
|
+++ b/libmultipath/discovery.h
|
2021-11-23 21:49:34 +08:00
|
|
|
@@ -58,6 +58,7 @@ bool has_uid_fallback(struct path *pp);
|
2020-07-16 18:51:36 +08:00
|
|
|
int get_uid(struct path * pp, int path_state, struct udev_device *udev,
|
|
|
|
|
int allow_fallback);
|
2021-11-23 21:49:34 +08:00
|
|
|
bool is_vpd_page_supported(int fd, int pg);
|
2020-01-10 17:13:17 +08:00
|
|
|
+int remove_local_path(vector pathvec, struct path *pp);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* discovery bitmask
|
2021-11-23 21:49:34 +08:00
|
|
|
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
|
|
|
|
index eb5b5b5..bccf3f3 100644
|
|
|
|
|
--- a/libmultipath/libmultipath.version
|
|
|
|
|
+++ b/libmultipath/libmultipath.version
|
|
|
|
|
@@ -142,6 +142,7 @@ global:
|
|
|
|
|
recv_packet_from_client;
|
|
|
|
|
reinstate_paths;
|
|
|
|
|
remember_wwid;
|
|
|
|
|
+ remove_local_path;
|
|
|
|
|
remove_map;
|
|
|
|
|
remove_map_by_alias;
|
|
|
|
|
remove_maps;
|
2020-01-10 17:13:17 +08:00
|
|
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
2021-11-23 21:49:34 +08:00
|
|
|
index 02f368a..47ca1b5 100644
|
2020-01-10 17:13:17 +08:00
|
|
|
--- a/multipathd/main.c
|
|
|
|
|
+++ b/multipathd/main.c
|
2021-11-23 21:49:34 +08:00
|
|
|
@@ -1035,6 +1035,10 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map)
|
2020-01-10 17:13:17 +08:00
|
|
|
int start_waiter = 0;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
+ /* if pp is local path,remove it and return 0. */
|
|
|
|
|
+ if (!remove_local_path(vecs->pathvec, pp))
|
|
|
|
|
+ return 0;
|
|
|
|
|
+
|
|
|
|
|
/*
|
|
|
|
|
* need path UID to go any further
|
|
|
|
|
*/
|
|
|
|
|
--
|
2022-03-08 11:35:40 +08:00
|
|
|
2.14.3 (Apple Git-98)
|
2020-01-10 17:13:17 +08:00
|
|
|
|