Scan the devices listed in /proc/partitions

During the commands:
	- btrfs filesystem show
	- btrfs device scan
the devices "scanned" are extracted from /proc/partitions. This
should avoid to scan devices not suitable for a btrfs filesystem like cdrom
and floppy or to scan not existant devices.
The old behavior (scan all the block devices under /dev) may be
forced passing the "--all-devices" switch.
This commit is contained in:
Goffredo Baroncelli 2011-06-15 21:55:25 +02:00 committed by Chris Mason
parent 521770b7a9
commit 0dbd99fb3e
5 changed files with 119 additions and 17 deletions

View File

@ -109,7 +109,7 @@ static struct Command commands[] = {
NULL NULL
}, },
{ do_show_filesystem, 999, { do_show_filesystem, 999,
"filesystem show", "[<device>|<uuid>|<label>]\n" "filesystem show", "[--all-devices][<uuid>|<label>]\n"
"Show the info of a btrfs filesystem. If no argument\n" "Show the info of a btrfs filesystem. If no argument\n"
"is passed, info of all the btrfs filesystem are shown.", "is passed, info of all the btrfs filesystem are shown.",
NULL NULL

View File

@ -607,10 +607,28 @@ int do_fssync(int argc, char **argv)
int do_scan(int argc, char **argv) int do_scan(int argc, char **argv)
{ {
int i, fd, e; int i, fd, e;
if(argc<=1){ int checklist = 1;
int devstart = 1;
if( argc >= 2 && !strcmp(argv[1],"--all-devices")){
if( argc >2 ){
fprintf(stderr, "ERROR: too may arguments\n");
return 22;
}
checklist = 0;
devstart += 1;
}
if(argc<=devstart){
int ret; int ret;
printf("Scanning for Btrfs filesystems\n"); printf("Scanning for Btrfs filesystems\n");
if(checklist)
ret = btrfs_scan_block_devices(1);
else
ret = btrfs_scan_one_dir("/dev", 1); ret = btrfs_scan_one_dir("/dev", 1);
if (ret){ if (ret){
fprintf(stderr, "ERROR: error %d while scanning\n", ret); fprintf(stderr, "ERROR: error %d while scanning\n", ret);
@ -625,7 +643,7 @@ int do_scan(int argc, char **argv)
return 10; return 10;
} }
for( i = 1 ; i < argc ; i++ ){ for( i = devstart ; i < argc ; i++ ){
struct btrfs_ioctl_vol_args args; struct btrfs_ioctl_vol_args args;
int ret; int ret;
@ -748,15 +766,34 @@ int do_show_filesystem(int argc, char **argv)
struct list_head *all_uuids; struct list_head *all_uuids;
struct btrfs_fs_devices *fs_devices; struct btrfs_fs_devices *fs_devices;
struct list_head *cur_uuid; struct list_head *cur_uuid;
char *search = argv[1]; char *search = 0;
int ret; int ret;
int checklist = 1;
int searchstart = 1;
if( argc >= 2 && !strcmp(argv[1],"--all-devices")){
checklist = 0;
searchstart += 1;
}
if( argc > searchstart+1 ){
fprintf(stderr, "ERROR: too many arguments\n");
return 22;
}
if(checklist)
ret = btrfs_scan_block_devices(0);
else
ret = btrfs_scan_one_dir("/dev", 0); ret = btrfs_scan_one_dir("/dev", 0);
if (ret){ if (ret){
fprintf(stderr, "ERROR: error %d while scanning\n", ret); fprintf(stderr, "ERROR: error %d while scanning\n", ret);
return 18; return 18;
} }
if(searchstart < argc)
search = argv[searchstart];
all_uuids = btrfs_scanned_uuids(); all_uuids = btrfs_scanned_uuids();
list_for_each(cur_uuid, all_uuids) { list_for_each(cur_uuid, all_uuids) {
fs_devices = list_entry(cur_uuid, struct btrfs_fs_devices, fs_devices = list_entry(cur_uuid, struct btrfs_fs_devices,

View File

@ -31,9 +31,9 @@ btrfs \- control a btrfs filesystem
.PP .PP
\fBbtrfs\fP \fBfilesystem defragment\fP\fI <file>|<dir> [<file>|<dir>...]\fP \fBbtrfs\fP \fBfilesystem defragment\fP\fI <file>|<dir> [<file>|<dir>...]\fP
.PP .PP
\fBbtrfs\fP \fBdevice scan\fP\fI [<device>...]\fP \fBbtrfs\fP \fBdevice scan\fP\fI [--all-devices|<device> [<device>...]]\fP
.PP .PP
\fBbtrfs\fP \fBdevice show\fP\fI [<device>|<uuid>|<label>]\fP \fBbtrfs\fP \fBdevice show\fP\fI [--all-devices|<uuid>|<label>]\fP
.PP .PP
\fBbtrfs\fP \fBdevice add\fP\fI <device> [<device>...] <path> \fP \fBbtrfs\fP \fBdevice add\fP\fI <device> [<device>...] <path> \fP
.PP .PP
@ -153,11 +153,6 @@ use it if you use snapshots, have de-duplicated your data or made copies with
List the recently modified files in a subvolume, after \fI<last_gen>\fR ID. List the recently modified files in a subvolume, after \fI<last_gen>\fR ID.
.TP .TP
\fBdevice scan\fR \fI[<device>...]\fR
Scan devices for a btrfs filesystem. If no devices are passed, \fBbtrfs\fR scans
all the block devices.
.TP
\fBfilesystem sync\fR\fI <path> \fR \fBfilesystem sync\fR\fI <path> \fR
Force a sync for the filesystem identified by \fI<path>\fR. Force a sync for the filesystem identified by \fI<path>\fR.
.TP .TP
@ -202,9 +197,11 @@ NOTE: Currently there are the following limitations:
- the filesystem should not have more than one device. - the filesystem should not have more than one device.
.TP .TP
\fBfilesystem show\fR [<uuid>|<label>]\fR \fBfilesystem show\fR [--all-devices|<uuid>|<label>]\fR
Show the btrfs filesystem with some additional info. If no UUID or label is Show the btrfs filesystem with some additional info. If no \fIUUID\fP or
passed, \fBbtrfs\fR show info of all the btrfs filesystem. \fIlabel\fP is passed, \fBbtrfs\fR show info of all the btrfs filesystem.
If \fB--all-devices\fP is passed, all the devices under /dev are scanned;
otherwise the devices list is extracted from the /proc/partitions file.
.TP .TP
\fBdevice balance\fR \fI<path>\fR \fBdevice balance\fR \fI<path>\fR
@ -218,7 +215,15 @@ Add device(s) to the filesystem identified by \fI<path>\fR.
\fBdevice delete\fR\fI <dev> [<dev>..] <path>\fR \fBdevice delete\fR\fI <dev> [<dev>..] <path>\fR
Remove device(s) from a filesystem identified by \fI<path>\fR. Remove device(s) from a filesystem identified by \fI<path>\fR.
.PP .TP
\fBdevice scan\fR \fI[--all-devices|<device> [<device>...]\fR
If one or more devices are passed, these are scanned for a btrfs filesystem.
If no devices are passed, \fBbtrfs\fR scans all the block devices listed
in the /proc/partitions file.
Finally, if \fB--all-devices\fP is passed, all the devices under /dev are
scanned.
.TP
\fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP} \fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
Start a scrub on all devices of the filesystem identified by \fI<path>\fR or on Start a scrub on all devices of the filesystem identified by \fI<path>\fR or on

58
utils.c
View File

@ -1114,3 +1114,61 @@ int check_label(char *input)
return 0; return 0;
} }
int btrfs_scan_block_devices(int run_ioctl)
{
struct stat st;
int ret;
int fd;
struct btrfs_fs_devices *tmp_devices;
u64 num_devices;
FILE *proc_partitions;
int i;
char buf[1024];
char fullpath[110];
proc_partitions = fopen("/proc/partitions","r");
if (!proc_partitions) {
fprintf(stderr, "Unable to open '/proc/partitions' for scanning\n");
return -ENOENT;
}
/* skip the header */
for(i=0; i < 2 ; i++)
if(!fgets(buf, 1023, proc_partitions)){
fprintf(stderr, "Unable to read '/proc/partitions' for scanning\n");
fclose(proc_partitions);
return -ENOENT;
}
strcpy(fullpath,"/dev/");
while(fgets(buf, 1023, proc_partitions)) {
i = sscanf(buf," %*d %*d %*d %99s", fullpath+5);
ret = lstat(fullpath, &st);
if (ret < 0) {
fprintf(stderr, "failed to stat %s\n", fullpath);
continue;
}
if (!S_ISBLK(st.st_mode)) {
continue;
}
fd = open(fullpath, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "failed to read %s\n", fullpath);
continue;
}
ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices,
&num_devices,
BTRFS_SUPER_INFO_OFFSET);
if (ret == 0 && run_ioctl > 0) {
btrfs_register_one_device(fullpath);
}
close(fd);
}
fclose(proc_partitions);
return 0;
}

View File

@ -44,4 +44,6 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
char *pretty_sizes(u64 size); char *pretty_sizes(u64 size);
int check_label(char *input); int check_label(char *input);
int get_mountpt(char *dev, char *mntpt, size_t size); int get_mountpt(char *dev, char *mntpt, size_t size);
int btrfs_scan_block_devices(int run_ioctl);
#endif #endif