disk: Fix detection of correct device in disk_open_dev()

This commit is contained in:
Pali Rohár committed 2017-07-09 14:56:30 +02:00
1 parent 27a55c3367
commit 31569c169a
1 file changed
+31 -13
+31 -13
View File
@@ -51,6 +51,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
DIR * dir; DIR * dir;
struct dirent * dirent; struct dirent * dirent;
int found; int found;
int old_errno;
size_t len; size_t len;
char blkdev[1024]; char blkdev[1024];
@@ -117,6 +118,19 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
blkdev[len] = 0; blkdev[len] = 0;
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
if ( fd < 0 ) {
if ( errno != ENOMEDIUM )
ERROR_INFO("Cannot open block device %s", blkdev);
return -1;
} else {
if ( fstat(fd, &st) != 0 || ! S_ISBLK(st.st_mode) || makedev(maj, min) != st.st_rdev ) {
ERROR("Block device %s does not have id %d:%d\n", blkdev, maj, min);
close(fd);
return -1;
}
}
} else if ( partition > 0 ) { } else if ( partition > 0 ) {
/* Select partition */ /* Select partition */
@@ -131,37 +145,41 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
ERROR("Block device name is too long"); ERROR("Block device name is too long");
return -1; return -1;
} }
if ( stat(blkdev, &st) != 0 || ! S_ISBLK(st.st_mode) ) { fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
if ( fd < 0 && errno == ENOENT ) {
if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) { if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) {
ERROR("Block device name is too long"); ERROR("Block device name is too long");
return -1; return -1;
} }
if ( stat(blkdev, &st) != 0 || ! S_ISBLK(st.st_mode) ) { fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
}
if ( fd < 0 && errno == ENOENT ) {
blkdev[len] = 0; blkdev[len] = 0;
fd = open(blkdev, O_RDONLY); fd = open(blkdev, O_RDONLY);
if ( fd < 0 ) { if ( fd < 0 ) {
if ( errno != ENOMEDIUM ) { if ( errno != ENOMEDIUM )
ERROR_INFO("Cannot open block device %s", blkdev); ERROR_INFO("Cannot open block device %s", blkdev);
return -1;
}
} else { } else {
close(fd); close(fd);
ERROR("Block device does not have partitions"); ERROR("Block device %s does not have partitions", blkdev);
}
return -1; return -1;
} }
} if ( fd < 0 )
} old_errno = errno;
printf("Found block device %s for partition %d\n", blkdev, partition); printf("Found block device %s for partition %d\n", blkdev, partition);
if ( fd < 0 ) {
errno = old_errno;
ERROR_INFO("Cannot open block device %s", blkdev);
} }
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL); } else {
ERROR("Invalid partition %d for block device %s", partition, blkdev);
fd = -1;
if ( fd < 0 ) {
if ( errno != ENOMEDIUM )
ERROR_INFO("Cannot open block device %s", blkdev);
return -1;
} }
return fd; return fd;