cgpt_find.c revision 250549d3e742cddaf72b4f53d5739e54faf5db96
1a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Use of this source code is governed by a BSD-style license that can be
3a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// found in the LICENSE file.
4a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
5a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include "cgpt.h"
6a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
7a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include <string.h>
8a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include <sys/stat.h>
9a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include <sys/types.h>
10a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
11a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include "cgptlib_internal.h"
12a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include "cgpt_params.h"
13a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
14a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define BUFSIZE 1024
15a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// FIXME: currently we only support 512-byte sectors.
16a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define LBA_SIZE 512
17a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
18a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
19a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// fill comparebuf with the data to be examined, returning true on success.
20250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasanstatic int FillBuffer(CgptFindParams *params, int fd, uint64_t pos,
21a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                       uint64_t count) {
22a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  uint8_t *bufptr = params->comparebuf;
23a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
24a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (-1 == lseek(fd, pos, SEEK_SET))
25a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return 0;
26a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
27a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  // keep reading until done or error
28a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  while (count) {
29a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    ssize_t bytes_read = read(fd, bufptr, count);
30a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    // negative means error, 0 means (unexpected) EOF
31a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (bytes_read <= 0)
32a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      return 0;
33a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    count -= bytes_read;
34a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    bufptr += bytes_read;
35a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
36a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
37a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  return 1;
38a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan}
39a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
40a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// check partition data content. return true for match, 0 for no match or error
41250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasanstatic int match_content(CgptFindParams *params, struct drive *drive,
42a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                             GptEntry *entry) {
43a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  uint64_t part_size;
44a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
45a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (!params->matchlen)
46a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return 1;
47a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
48a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  // Ensure that the region we want to match against is inside the partition.
49a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  part_size = LBA_SIZE * (entry->ending_lba - entry->starting_lba + 1);
50a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (params->matchoffset + params->matchlen > part_size) {
51a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return 0;
52a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
53a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
54a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  // Read the partition data.
55a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (!FillBuffer(params,
56a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                  drive->fd,
57a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                  (LBA_SIZE * entry->starting_lba) + params->matchoffset,
58a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                  params->matchlen)) {
59a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    Error("unable to read partition data\n");
60a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return 0;
61a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
62a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
63a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  // Compare it
64a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (0 == memcmp(params->matchbuf, params->comparebuf, params->matchlen)) {
65a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return 1;
66a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
67a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
68a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  // Nope.
69a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  return 0;
70a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan}
71a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
72a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This needs to handle /dev/mmcblk0 -> /dev/mmcblk0p3, /dev/sda -> /dev/sda3
73250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasanstatic void showmatch(CgptFindParams *params, char *filename,
74a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                           int partnum, GptEntry *entry) {
75a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  char * format = "%s%d\n";
76a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (strncmp("/dev/mmcblk", filename, 11) == 0)
77a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    format = "%sp%d\n";
78a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (params->numeric)
79a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    printf("%d\n", partnum);
80a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  else
81a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    printf(format, filename, partnum);
82a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (params->verbose > 0)
83a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    EntryDetails(entry, partnum - 1, params->numeric);
84a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan}
85a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
86a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This returns true if a GPT partition matches the search criteria. If a match
87a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// isn't found (or if the file doesn't contain a GPT), it returns false. The
88a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// filename and partition number that matched is left in a global, since we
89a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// could have multiple hits.
90a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic int do_search(CgptFindParams *params, char *fileName) {
91a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  int retval = 0;
92a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  int i;
93a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  struct drive drive;
94a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  GptEntry *entry;
95a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  char partlabel[GPT_PARTNAME_LEN];
96a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
97a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (CGPT_OK != DriveOpen(fileName, &drive))
98a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return 0;
99a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
100a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (GPT_SUCCESS != GptSanityCheck(&drive.gpt)) {
101a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    (void) DriveClose(&drive, 0);
102a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return 0;
103a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
104a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
105a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  for (i = 0; i < GetNumberOfEntries(&drive.gpt); ++i) {
106a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    entry = GetEntry(&drive.gpt, ANY_VALID, i);
107a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
108a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (IsZero(&entry->type))
109a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      continue;
110a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
111a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    int found = 0;
112a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if ((params->set_unique && GuidEqual(&params->unique_guid, &entry->unique))
113a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan        || (params->set_type && GuidEqual(&params->type_guid, &entry->type))) {
114a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      found = 1;
115a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    } else if (params->set_label) {
116a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      if (CGPT_OK != UTF16ToUTF8(entry->name,
117a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                                 sizeof(entry->name) / sizeof(entry->name[0]),
118a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan                                 (uint8_t *)partlabel, sizeof(partlabel))) {
119a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan        Error("The label cannot be converted from UTF16, so abort.\n");
120a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan        return 0;
121a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      }
122a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      if (!strncmp(params->label, partlabel, sizeof(partlabel)))
123a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan        found = 1;
124a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    }
125a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (found && match_content(params, &drive, entry)) {
126a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      params->hits++;
127a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      retval++;
128a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      showmatch(params, fileName, i+1, entry);
129a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      if (!params->match_partnum)
130a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan        params->match_partnum = i+1;
131a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    }
132a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
133a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
134a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  (void) DriveClose(&drive, 0);
135a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
136a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  return retval;
137a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan}
138a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
139a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
140a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define PROC_PARTITIONS "/proc/partitions"
141a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define DEV_DIR "/dev"
142a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define SYS_BLOCK_DIR "/sys/block"
143a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
144a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic const char *devdirs[] = { "/dev", "/devices", "/devfs", 0 };
145a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
146a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Given basename "foo", see if we can find a whole, real device by that name.
147a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This is copied from the logic in the linux utility 'findfs', although that
148a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// does more exhaustive searching.
149a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic char *is_wholedev(const char *basename) {
150a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  int i;
151a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  struct stat statbuf;
152a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  static char pathname[BUFSIZE];        // we'll return this.
153a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  char tmpname[BUFSIZE];
154a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
155a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  // It should be a block device under /dev/,
156a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  for (i = 0; devdirs[i]; i++) {
157a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    sprintf(pathname, "%s/%s", devdirs[i], basename);
158a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
159a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (0 != stat(pathname, &statbuf))
160a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      continue;
161a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
162a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (!S_ISBLK(statbuf.st_mode))
163a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      continue;
164a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
165a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    // It should have a symlink called /sys/block/*/device
166a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    sprintf(tmpname, "%s/%s/device", SYS_BLOCK_DIR, basename);
167a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
168a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (0 != lstat(tmpname, &statbuf))
169a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      continue;
170a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
171a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (!S_ISLNK(statbuf.st_mode))
172a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      continue;
173a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
174a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    // found it
175a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return pathname;
176a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
177a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
178a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  return 0;
179a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan}
180a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
181a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
182a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This scans all the physical devices it can find, looking for a match. It
183a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// returns true if any matches were found, false otherwise.
184a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic int scan_real_devs(CgptFindParams *params) {
185a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  int found = 0;
186a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  char line[BUFSIZE];
187a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  char partname[128];                   // max size for /proc/partition lines?
188a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  FILE *fp;
189a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  char *pathname;
190a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
191a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  fp = fopen(PROC_PARTITIONS, "r");
192a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (!fp) {
193a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    perror("can't read " PROC_PARTITIONS);
194a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return found;
195a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
196a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
197a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  while (fgets(line, sizeof(line), fp)) {
198a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    int ma, mi;
199a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    long long unsigned int sz;
200a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
201a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if (sscanf(line, " %d %d %llu %127[^\n ]", &ma, &mi, &sz, partname) != 4)
202a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      continue;
203a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
204a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    if ((pathname = is_wholedev(partname))) {
205a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      if (do_search(params, pathname)) {
206a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan        found++;
207a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan      }
208a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    }
209a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  }
210a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
211a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  fclose(fp);
212a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  return found;
213a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan}
214a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
215a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
216a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanvoid cgpt_find(CgptFindParams *params) {
217a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  if (params == NULL)
218a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    return;
219a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan
220250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasan  if (params->drive_name != NULL)
221250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasan    do_search(params, params->drive_name);
222a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan  else
223a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan    scan_real_devs(params);
224a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan}
225