diff options
author | Goffredo Baroncelli <kreijack@inwind.it> | 2011-06-15 21:55:25 +0200 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-10-25 09:19:00 -0400 |
commit | 0dbd99fb3e117cd5f87eda492b6b4fab1b5bea23 (patch) | |
tree | 2eac9041b342d4f120e7578db697b368e20fc5b2 | |
parent | 521770b7a9bef17dcbcee514da5052b3e06120d2 (diff) | |
download | btrfs-progs-0dbd99fb3e117cd5f87eda492b6b4fab1b5bea23.tar.gz |
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.
-rw-r--r-- | btrfs.c | 2 | ||||
-rw-r--r-- | btrfs_cmds.c | 47 | ||||
-rw-r--r-- | man/btrfs.8.in | 27 | ||||
-rw-r--r-- | utils.c | 58 | ||||
-rw-r--r-- | utils.h | 2 |
5 files changed, 119 insertions, 17 deletions
@@ -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 diff --git a/btrfs_cmds.c b/btrfs_cmds.c index d099847..ecdae16 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -607,11 +607,29 @@ 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"); - ret = btrfs_scan_one_dir("/dev", 1); + 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); return 18; @@ -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,14 +766,33 @@ 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); - 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) { diff --git a/man/btrfs.8.in b/man/btrfs.8.in index e830abd..ab9f44f 100644 --- a/man/btrfs.8.in +++ b/man/btrfs.8.in @@ -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 @@ -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; +} + @@ -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 |