Re: [obsoleted] [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware

2013-04-11 Thread Anand Jain


 This patch is replaced By:

btrfs-progs: avoid ioctl for multipath-dev with its non-multipath path

 which is also sent to this mailing list.

thanks, Anand


On 03/27/2013 06:07 PM, Anand Jain wrote:

  We should avoid using non multi-path (mp) path for mp disks
  As of now there is no good way (like api) to check that.
  A workaround way is to check if the O_EXCL open is unsuccessful.
  This is safe since otherwise the BTRFS_IOC_SCAN_DEV ioctl would
  fail if the disk-path can not be opened with the flag O_EXCL set.

  This patch also includes some (error) print format changes related
  to the btrfs dev scan..

Signed-off-by: Anand Jain 
---
  cmds-device.c | 53 +++--
  utils.c   | 31 ---
  2 files changed, 63 insertions(+), 21 deletions(-)

diff --git a/cmds-device.c b/cmds-device.c
index 41e79d3..b8d05fd 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -185,7 +185,7 @@ static const char * const cmd_scan_dev_usage[] = {

  static int cmd_scan_dev(int argc, char **argv)
  {
-   int i, fd, e;
+   int i, fd, e, ret = 0;
int checklist = 1;
int devstart = 1;

@@ -197,6 +197,21 @@ static int cmd_scan_dev(int argc, char **argv)
devstart += 1;
}

+   fd = open("/dev/btrfs-control", O_RDWR);
+   e = errno;
+   if (fd < 0) {
+   FILE *mfd = popen("lsmod | grep btrfs", "r");
+   char buf[16];
+
+   if (fread (buf, 1, sizeof (buf), mfd) > 0)
+   fprintf(stderr, "ERROR: failed to open "\
+   "/dev/btrfs-control - %s\n", strerror(e));
+   else
+   fprintf(stderr, "ERROR: btrfs kernel module "\
+   "is not loaded\n");
+   return 10;
+   }
+
if(argc<=devstart){

int ret;
@@ -210,20 +225,30 @@ static int cmd_scan_dev(int argc, char **argv)
fprintf(stderr, "ERROR: error %d while scanning\n", 
ret);
return 18;
}
+   printf("done\n");
return 0;
}

-   fd = open("/dev/btrfs-control", O_RDWR);
-   if (fd < 0) {
-   perror("failed to open /dev/btrfs-control");
-   return 10;
-   }
-
+   printf("Scanning for Btrfs in\n");
for( i = devstart ; i < argc ; i++ ){
+   int fdt;
struct btrfs_ioctl_vol_args args;
-   int ret;
+   printf("  %s ", argv[i]);
+   fflush(stdout);

-   printf("Scanning for Btrfs filesystems in '%s'\n", argv[i]);
+   /*
+* If for a multipath (mp) disk user provides the
+* non-mp path then open with flag O_EXCL will fail,
+* (also ioctl opens with O_EXCL), So test it before
+* calling ioctl.
+*/
+   fdt = open(argv[i], O_RDONLY|O_EXCL);
+   if (fdt < 0) {
+   perror("ERROR");
+   ret = -1;
+   continue;
+   }
+   close(fdt);

strncpy_null(args.name, argv[i]);
/*
@@ -235,15 +260,15 @@ static int cmd_scan_dev(int argc, char **argv)
e = errno;

if( ret < 0 ){
-   close(fd);
-   fprintf(stderr, "ERROR: unable to scan the device '%s' - 
%s\n",
-   argv[i], strerror(e));
-   return 11;
+   fprintf(stderr, "ERROR: unable to scan - %s\n",
+   strerror(e));
+   ret = -1;
}
+   printf("found\n");
}

close(fd);
-   return 0;
+   return ret;
  }

  static const char * const cmd_ready_dev_usage[] = {
diff --git a/utils.c b/utils.c
index a4f7b06..3a0d444 100644
--- a/utils.c
+++ b/utils.c
@@ -1105,25 +1105,32 @@ again:
if (!S_ISBLK(st.st_mode)) {
continue;
}
-   fd = open(fullpath, O_RDONLY);
+   fd = open(fullpath, O_RDONLY|O_EXCL);
if (fd < 0) {
/* ignore the following errors:
ENXIO (device don't exists)
ENOMEDIUM (No medium found ->
like a cd tray empty)
+   EBUSY (when mp disk is opened
+   using non-mp path).
*/
-   if(errno != ENXIO && errno != ENOMEDIUM)
+   if(errno != ENXIO && errno != ENOMEDIUM &&
+   errno != EBUSY)
fprintf(stderr, "failed to read %s: %s\n",
  

[PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware

2013-03-27 Thread Anand Jain
 We should avoid using non multi-path (mp) path for mp disks
 As of now there is no good way (like api) to check that.
 A workaround way is to check if the O_EXCL open is unsuccessful.
 This is safe since otherwise the BTRFS_IOC_SCAN_DEV ioctl would
 fail if the disk-path can not be opened with the flag O_EXCL set.

 This patch also includes some (error) print format changes related
 to the btrfs dev scan..

Signed-off-by: Anand Jain 
---
 cmds-device.c | 53 +++--
 utils.c   | 31 ---
 2 files changed, 63 insertions(+), 21 deletions(-)

diff --git a/cmds-device.c b/cmds-device.c
index 41e79d3..b8d05fd 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -185,7 +185,7 @@ static const char * const cmd_scan_dev_usage[] = {
 
 static int cmd_scan_dev(int argc, char **argv)
 {
-   int i, fd, e;
+   int i, fd, e, ret = 0;
int checklist = 1;
int devstart = 1;
 
@@ -197,6 +197,21 @@ static int cmd_scan_dev(int argc, char **argv)
devstart += 1;
}
 
+   fd = open("/dev/btrfs-control", O_RDWR);
+   e = errno;
+   if (fd < 0) {
+   FILE *mfd = popen("lsmod | grep btrfs", "r");
+   char buf[16];
+
+   if (fread (buf, 1, sizeof (buf), mfd) > 0)
+   fprintf(stderr, "ERROR: failed to open "\
+   "/dev/btrfs-control - %s\n", strerror(e));
+   else
+   fprintf(stderr, "ERROR: btrfs kernel module "\
+   "is not loaded\n");
+   return 10;
+   }
+
if(argc<=devstart){
 
int ret;
@@ -210,20 +225,30 @@ static int cmd_scan_dev(int argc, char **argv)
fprintf(stderr, "ERROR: error %d while scanning\n", 
ret);
return 18;
}
+   printf("done\n");
return 0;
}
 
-   fd = open("/dev/btrfs-control", O_RDWR);
-   if (fd < 0) {
-   perror("failed to open /dev/btrfs-control");
-   return 10;
-   }
-
+   printf("Scanning for Btrfs in\n");
for( i = devstart ; i < argc ; i++ ){
+   int fdt;
struct btrfs_ioctl_vol_args args;
-   int ret;
+   printf("  %s ", argv[i]);
+   fflush(stdout);
 
-   printf("Scanning for Btrfs filesystems in '%s'\n", argv[i]);
+   /*
+* If for a multipath (mp) disk user provides the
+* non-mp path then open with flag O_EXCL will fail,
+* (also ioctl opens with O_EXCL), So test it before
+* calling ioctl.
+*/
+   fdt = open(argv[i], O_RDONLY|O_EXCL);
+   if (fdt < 0) {
+   perror("ERROR");
+   ret = -1;
+   continue;
+   }
+   close(fdt);
 
strncpy_null(args.name, argv[i]);
/*
@@ -235,15 +260,15 @@ static int cmd_scan_dev(int argc, char **argv)
e = errno;
 
if( ret < 0 ){
-   close(fd);
-   fprintf(stderr, "ERROR: unable to scan the device '%s' 
- %s\n",
-   argv[i], strerror(e));
-   return 11;
+   fprintf(stderr, "ERROR: unable to scan - %s\n",
+   strerror(e));
+   ret = -1;
}
+   printf("found\n");
}
 
close(fd);
-   return 0;
+   return ret;
 }
 
 static const char * const cmd_ready_dev_usage[] = {
diff --git a/utils.c b/utils.c
index a4f7b06..3a0d444 100644
--- a/utils.c
+++ b/utils.c
@@ -1105,25 +1105,32 @@ again:
if (!S_ISBLK(st.st_mode)) {
continue;
}
-   fd = open(fullpath, O_RDONLY);
+   fd = open(fullpath, O_RDONLY|O_EXCL);
if (fd < 0) {
/* ignore the following errors:
ENXIO (device don't exists) 
ENOMEDIUM (No medium found -> 
like a cd tray empty)
+   EBUSY (when mp disk is opened
+   using non-mp path).
*/
-   if(errno != ENXIO && errno != ENOMEDIUM) 
+   if(errno != ENXIO && errno != ENOMEDIUM &&
+   errno != EBUSY)
fprintf(stderr, "failed to read %s: %s\n", 
fullpath, strerror(errno));
continue;
}
+   close(fd);
+
+   fd = open(fullpath, O_RDONLY);
ret = btrfs_scan_one_de