8 #include <linux/major.h>
13 static DiskList
*dlist
= NULL
;
15 const char *stripdev(const char *s
) {
16 if (strncmp(s
,"/dev",4) == 0) s
+= 4;
21 DiskList
*find_dev(unsigned major
, unsigned minor
) {
23 for (dl
= dlist
; dl
; dl
= dl
->next
) {
24 if (dl
->major
== major
&& dl
->minor
== minor
) return dl
;
29 DiskList
*find_id(int hd_id
, int part_id
) {
31 for (dl
= dlist
; dl
; dl
= dl
->next
) {
32 if (((dl
->hd_id
== hd_id
) || hd_id
== -1) &&
33 ((dl
->part_id
== part_id
) || part_id
== -1)) return dl
;
38 DiskList *find_dev_by_name(const char *name) {
40 const char *sname = stripdev(name);
41 for (dl = dlist; dl; dl = dl->next) {
42 if (strcmp(sname, dl->name)==0) return dl;
47 DiskList
*next_hd_in_list(DiskList
*prev
) {
48 DiskList
*dl
= (prev
? prev
->next
: dlist
);
49 while (dl
&& IS_PARTITION(dl
)) dl
= dl
->next
;
53 DiskList
*first_hd_in_list() {
54 return next_hd_in_list(NULL
);
57 DiskList
*first_dev_in_list() {
64 for (dl
= first_hd_in_list(); dl
; dl
= next_hd_in_list(dl
)) ++i
;
68 int nb_dev_in_list() {
71 for (dl
= dlist
; dl
; dl
= dl
->next
) ++i
;
75 /*int is_partition_name(const char *name) {
77 if (l && name[l-1] >= '0' && name[l-1] <= '9') return 1;
82 static const char *to_num_(unsigned minor
) {
84 if (minor
== 0) return "";
85 else snprintf(id
,16,"%d",minor
);
89 int device_info(unsigned major
, unsigned minor
, char *name
, int *hd_id
, int *part_id
) {
91 #ifdef SCSI_DISK0_MAJOR
92 case (SCSI_DISK0_MAJOR
):
94 case (SCSI_DISK_MAJOR
):
96 if (name
) sprintf(name
, "sd%c%s", "abcdefghijklmnop"[(minor
)/16], to_num_(minor
%16));
97 if (hd_id
) *hd_id
= (minor
)/16;
98 if (part_id
) *part_id
= minor
%16;
101 if (name
) sprintf(name
, "hd%c%s", "ab"[(minor
)/64], to_num_(minor
%64));
102 if (hd_id
) *hd_id
= 100 + (minor
)/64;
103 if (part_id
) *part_id
= minor
%64;
106 if (name
) sprintf(name
, "hd%c%s", "cd"[(minor
)/64], to_num_(minor
%64));
107 if (hd_id
) *hd_id
= 200 + (minor
)/64;
108 if (part_id
) *part_id
= minor
%64;
112 if (name
) sprintf(name
, "hd%c%s", "ef"[(minor
)/64], to_num_(minor
%64));
113 if (hd_id
) *hd_id
= 300 + (minor
)/64;
114 if (part_id
) *part_id
= minor
%64;
119 if (name
) sprintf(name
, "hd%c%s", "gh"[(minor
)/64], to_num_(minor
%64));
120 if (hd_id
) *hd_id
= 400 + (minor
)/64;
121 if (part_id
) *part_id
= minor
%64;
126 if (name
) sprintf(name
, "hd%c%s", "ij"[(minor
)/64], to_num_(minor
%64));
127 if (hd_id
) *hd_id
= 400 + (minor
)/64;
128 if (part_id
) *part_id
= minor
%64;
134 if (name
) sprintf(name
, "hd%c%s", "kl"[(minor
)/64], to_num_(minor
%64));
135 if (hd_id
) *hd_id
= 400 + (minor
)/64;
136 if (part_id
) *part_id
= minor
%64;
142 if (name
) sprintf(name
, "hd%c%s", "mn"[(minor
)/64], to_num_(minor
%64));
143 if (hd_id
) *hd_id
= 400 + (minor
)/64;
144 if (part_id
) *part_id
= minor
%64;
151 if (name
) sprintf(name
, "md%s", to_num_(minor
));
152 if (hd_id
) *hd_id
= 400 + minor
;
153 if (part_id
) *part_id
= 0;
158 if (hd_id
) *hd_id
= -1;
159 if (part_id
) *part_id
= -1;
163 int short_name_for_device(unsigned major
, unsigned minor
, char *name
) {
164 return device_info(major
,minor
,name
,NULL
,NULL
);
167 int is_partition(unsigned major
, unsigned minor
) {
169 if (!device_info(major
,minor
,NULL
,NULL
,&part_id
)) return 0;
170 return (part_id
!= 0);
173 int device_id_from_name(const char *devname__
, unsigned *pmajor
, unsigned *pminor
) {
174 if (strlen(devname__
)>=512) return -1;
175 char *devname_
, devname
[512];
177 devname_
= str_substitute(devname__
, "/dev/mapper", "/dev");
179 struct stat stat_buf
;
180 BLAHBLAH(1,printf("looking for %s in /dev..\n", devname_
));
182 if (devname_
[0] != '/') snprintf(devname
,512,"/dev/%s", devname_
);
183 else snprintf(devname
,512,"%s",devname_
);
185 free(devname_
); devname_
= 0;
187 if (lstat(devname
,&stat_buf
)) { BLAHBLAH(1,perror(devname
)); return -1; }
188 if (S_ISLNK(stat_buf
.st_mode
)) {
190 int n
= readlink(devname
, lname
, 511); lname
[n
] = 0;
191 snprintf(devname
,512,"/dev/%s",stripdev(lname
));
192 if (stat(devname
,&stat_buf
)) { BLAHBLAH(1,perror(devname
)); return -1; }
194 if (!S_ISBLK(stat_buf
.st_mode
)) {
195 fprintf(stderr
, "%s is not a block device..\n", devname
);
198 *pmajor
= major(stat_buf
.st_rdev
);
199 *pminor
= minor(stat_buf
.st_rdev
);
205 /* add a hard-drive if it is a regular ide/scsi/md disk/partition, or return NULL */
206 static DiskList
*create_device(unsigned major
, unsigned minor
, const char *mtab_name
) {
210 if (mtab_name
&& strlen(mtab_name
)) dl
->name
= strdup(mtab_name
);
212 char s
[512]; short_name_for_device(major
,minor
,s
); dl
->name
= strdup(s
);
214 BLAHBLAH(1, printf("create_device(major=%d, minor=%d, mtab_name=%s) : name=%s\n", major
,minor
,mtab_name
,dl
->name
));
215 dl
->major
= major
; dl
->minor
= minor
;
216 if (device_info(major
,minor
,dev_path
,&dl
->hd_id
,&dl
->part_id
) == 0) {
217 BLAHBLAH(1, printf("(%d,%d) is not a known disc type..\n", major
,minor
));
218 free(dl
); return NULL
;
220 dl
->dev_path
= malloc(strlen(dev_path
)+6); assert(dl
->dev_path
);
221 sprintf(dl
->dev_path
, "/dev/%s", dev_path
);
223 if (dl
->part_id
== 0)
224 dl
->enable_hddtemp
= 1;
228 /* add a device (after checking that it is a known device type) */
229 int add_device_by_name(const char *devname
, const char *mtab_name
) {
230 unsigned major
, minor
;
232 BLAHBLAH(1,printf("add_device_by_name(%s,%s)\n", devname
, mtab_name
));
233 if (device_id_from_name(devname
, &major
, &minor
) != 0) return -1;
235 return add_device_by_id(major
,minor
,mtab_name
);
238 /* add a device (after checking that it is a known device type) */
239 int add_device_by_id(unsigned major
, unsigned minor
, const char *mtab_name
) {
240 DiskList
*dl
, *next
, *prev
;
241 BLAHBLAH(1,printf("add_device_by_id(%d,%d,%s)\n", major
, minor
,mtab_name
));
242 /* already known ? */
243 if (find_dev(major
,minor
)) return -1;
244 /* check for known ide/scsi/md disks and then create */
245 dl
= create_device(major
, minor
, mtab_name
); if (!dl
) return -1;
247 for (next
= dlist
, prev
= NULL
; next
; next
=next
->next
) {
248 if (dl
->hd_id
> next
->hd_id
|| (dl
->hd_id
== next
->hd_id
&& dl
->part_id
> next
->part_id
)) break;
252 dl
->next
= dlist
; dlist
= dl
;
254 dl
->next
= prev
->next
; prev
->next
= dl
;
259 strlist
*swaplst
= NULL
;
260 void add_swap(const char *swapdev
) {
261 swaplst
= strlist_ins(swaplst
, swapdev
);
263 strlist
*swap_list() {