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
},
{ 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"
"is passed, info of all the btrfs filesystem are shown.",
NULL

View File

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

View File

@ -31,9 +31,9 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBfilesystem defragment\fP\fI <file>|<dir> [<file>|<dir>...]\fP
.PP
\fBbtrfs\fP \fBdevice scan\fP\fI [<device>...]\fP
\fBbtrfs\fP \fBdevice scan\fP\fI [--all-devices|<device> [<device>...]]\fP
.PP
\fBbtrfs\fP \fBdevice show\fP\fI [<device>|<uuid>|<label>]\fP
\fBbtrfs\fP \fBdevice show\fP\fI [--all-devices|<uuid>|<label>]\fP
.PP
\fBbtrfs\fP \fBdevice add\fP\fI <device> [<device>...] <path> \fP
.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.
.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
Force a sync for the filesystem identified by \fI<path>\fR.
.TP
@ -202,9 +197,11 @@ NOTE: Currently there are the following limitations:
- the filesystem should not have more than one device.
.TP
\fBfilesystem show\fR [<uuid>|<label>]\fR
Show the btrfs filesystem with some additional info. If no UUID or label is
passed, \fBbtrfs\fR show info of all the btrfs filesystem.
\fBfilesystem show\fR [--all-devices|<uuid>|<label>]\fR
Show the btrfs filesystem with some additional info. If no \fIUUID\fP or
\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
\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
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}
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;
}
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);
int check_label(char *input);
int get_mountpt(char *dev, char *mntpt, size_t size);
int btrfs_scan_block_devices(int run_ioctl);
#endif