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;
157 #ifdef BLOCK_EXT_MAJOR
158 case (BLOCK_EXT_MAJOR
):
159 if (name
) sprintf(name
, "nvme0n%cp%s", "0123456789"[(minor
/16)], to_num_(minor
));
160 if (hd_id
) *hd_id
= 400 + minor
;
161 if (part_id
) *part_id
= 0;
166 if (hd_id
) *hd_id
= -1;
167 if (part_id
) *part_id
= -1;
171 int short_name_for_device(unsigned major
, unsigned minor
, char *name
) {
172 return device_info(major
,minor
,name
,NULL
,NULL
);
175 int is_partition(unsigned major
, unsigned minor
) {
177 if (!device_info(major
,minor
,NULL
,NULL
,&part_id
)) return 0;
178 return (part_id
!= 0);
181 int device_id_from_name(const char *devname__
, unsigned *pmajor
, unsigned *pminor
) {
182 if (strlen(devname__
)>=512) return -1;
183 char *devname_
, devname
[512];
185 devname_
= str_substitute(devname__
, "/dev/mapper", "/dev");
187 struct stat stat_buf
;
188 BLAHBLAH(1,printf("looking for %s in /dev..\n", devname_
));
190 if (devname_
[0] != '/') snprintf(devname
,512,"/dev/%s", devname_
);
191 else snprintf(devname
,512,"%s",devname_
);
193 free(devname_
); devname_
= 0;
195 if (lstat(devname
,&stat_buf
)) { BLAHBLAH(1,perror(devname
)); return -1; }
196 if (S_ISLNK(stat_buf
.st_mode
)) {
197 devname_
= realpath(devname
, NULL
);
198 if(!devname_
) { BLAHBLAH(1,perror(devname
)); return -1; }
199 strncpy(devname
, devname_
, 512); devname
[511] = 0;
201 if (stat(devname
,&stat_buf
)) { BLAHBLAH(1,perror(devname
)); return -1; }
203 if (!S_ISBLK(stat_buf
.st_mode
)) {
204 fprintf(stderr
, "%s is not a block device..\n", devname
);
207 *pmajor
= major(stat_buf
.st_rdev
);
208 *pminor
= minor(stat_buf
.st_rdev
);
214 /* add a hard-drive if it is a regular ide/scsi/md disk/partition, or return NULL */
215 static DiskList
*create_device(unsigned major
, unsigned minor
, const char *mtab_name
) {
219 if (mtab_name
&& strlen(mtab_name
)) dl
->name
= strdup(mtab_name
);
221 char s
[512]; short_name_for_device(major
,minor
,s
); dl
->name
= strdup(s
);
223 BLAHBLAH(1, printf("create_device(major=%d, minor=%d, mtab_name=%s) : name=%s\n", major
,minor
,mtab_name
,dl
->name
));
224 dl
->major
= major
; dl
->minor
= minor
;
225 if (device_info(major
,minor
,dev_path
,&dl
->hd_id
,&dl
->part_id
) == 0) {
226 BLAHBLAH(1, printf("(%d,%d) is not a known disc type..\n", major
,minor
));
227 free(dl
); return NULL
;
229 dl
->dev_path
= malloc(strlen(dev_path
)+6); assert(dl
->dev_path
);
230 sprintf(dl
->dev_path
, "/dev/%s", dev_path
);
232 if (dl
->part_id
== 0)
233 dl
->enable_hddtemp
= 1;
237 /* add a device (after checking that it is a known device type) */
238 int add_device_by_name(const char *devname
, const char *mtab_name
) {
239 unsigned major
, minor
;
241 BLAHBLAH(1,printf("add_device_by_name(%s,%s)\n", devname
, mtab_name
));
242 if (device_id_from_name(devname
, &major
, &minor
) != 0) return -1;
244 return add_device_by_id(major
,minor
,mtab_name
);
247 /* add a device (after checking that it is a known device type) */
248 int add_device_by_id(unsigned major
, unsigned minor
, const char *mtab_name
) {
249 DiskList
*dl
, *next
, *prev
;
250 BLAHBLAH(1,printf("add_device_by_id(%d,%d,%s)\n", major
, minor
,mtab_name
));
251 /* already known ? */
252 if (find_dev(major
,minor
)) return -1;
253 /* check for known ide/scsi/md disks and then create */
254 dl
= create_device(major
, minor
, mtab_name
); if (!dl
) return -1;
256 for (next
= dlist
, prev
= NULL
; next
; next
=next
->next
) {
257 if (dl
->hd_id
> next
->hd_id
|| (dl
->hd_id
== next
->hd_id
&& dl
->part_id
> next
->part_id
)) break;
261 dl
->next
= dlist
; dlist
= dl
;
263 dl
->next
= prev
->next
; prev
->next
= dl
;
268 strlist
*swaplst
= NULL
;
269 void add_swap(const char *swapdev
) {
270 swaplst
= strlist_ins(swaplst
, swapdev
);
272 strlist
*swap_list() {