7 #include <sys/sysmacros.h>
9 #include <linux/major.h>
14 static DiskList
*dlist
= NULL
;
16 const char *stripdev(const char *s
) {
17 if (strncmp(s
,"/dev",4) == 0) s
+= 4;
22 DiskList
*find_dev(unsigned major
, unsigned minor
) {
24 for (dl
= dlist
; dl
; dl
= dl
->next
) {
25 if (dl
->major
== major
&& dl
->minor
== minor
) return dl
;
30 DiskList
*find_id(int hd_id
, int part_id
) {
32 for (dl
= dlist
; dl
; dl
= dl
->next
) {
33 if (((dl
->hd_id
== hd_id
) || hd_id
== -1) &&
34 ((dl
->part_id
== part_id
) || part_id
== -1)) return dl
;
39 DiskList *find_dev_by_name(const char *name) {
41 const char *sname = stripdev(name);
42 for (dl = dlist; dl; dl = dl->next) {
43 if (strcmp(sname, dl->name)==0) return dl;
48 DiskList
*next_hd_in_list(DiskList
*prev
) {
49 DiskList
*dl
= (prev
? prev
->next
: dlist
);
50 while (dl
&& IS_PARTITION(dl
)) dl
= dl
->next
;
54 DiskList
*first_hd_in_list() {
55 return next_hd_in_list(NULL
);
58 DiskList
*first_dev_in_list() {
65 for (dl
= first_hd_in_list(); dl
; dl
= next_hd_in_list(dl
)) ++i
;
69 int nb_dev_in_list() {
72 for (dl
= dlist
; dl
; dl
= dl
->next
) ++i
;
76 /*int is_partition_name(const char *name) {
78 if (l && name[l-1] >= '0' && name[l-1] <= '9') return 1;
83 static const char *to_num_(unsigned minor
) {
85 if (minor
== 0) return "";
86 else snprintf(id
,16,"%d",minor
);
90 int device_info(unsigned major
, unsigned minor
, char *name
, int *hd_id
, int *part_id
) {
92 #ifdef SCSI_DISK0_MAJOR
93 case (SCSI_DISK0_MAJOR
):
95 case (SCSI_DISK_MAJOR
):
97 if (name
) sprintf(name
, "sd%c%s", "abcdefghijklmnop"[(minor
)/16], to_num_(minor
%16));
98 if (hd_id
) *hd_id
= (minor
)/16;
99 if (part_id
) *part_id
= minor
%16;
102 if (name
) sprintf(name
, "hd%c%s", "ab"[(minor
)/64], to_num_(minor
%64));
103 if (hd_id
) *hd_id
= 100 + (minor
)/64;
104 if (part_id
) *part_id
= minor
%64;
107 if (name
) sprintf(name
, "hd%c%s", "cd"[(minor
)/64], to_num_(minor
%64));
108 if (hd_id
) *hd_id
= 200 + (minor
)/64;
109 if (part_id
) *part_id
= minor
%64;
113 if (name
) sprintf(name
, "hd%c%s", "ef"[(minor
)/64], to_num_(minor
%64));
114 if (hd_id
) *hd_id
= 300 + (minor
)/64;
115 if (part_id
) *part_id
= minor
%64;
120 if (name
) sprintf(name
, "hd%c%s", "gh"[(minor
)/64], to_num_(minor
%64));
121 if (hd_id
) *hd_id
= 400 + (minor
)/64;
122 if (part_id
) *part_id
= minor
%64;
127 if (name
) sprintf(name
, "hd%c%s", "ij"[(minor
)/64], to_num_(minor
%64));
128 if (hd_id
) *hd_id
= 400 + (minor
)/64;
129 if (part_id
) *part_id
= minor
%64;
135 if (name
) sprintf(name
, "hd%c%s", "kl"[(minor
)/64], to_num_(minor
%64));
136 if (hd_id
) *hd_id
= 400 + (minor
)/64;
137 if (part_id
) *part_id
= minor
%64;
143 if (name
) sprintf(name
, "hd%c%s", "mn"[(minor
)/64], to_num_(minor
%64));
144 if (hd_id
) *hd_id
= 400 + (minor
)/64;
145 if (part_id
) *part_id
= minor
%64;
152 if (name
) sprintf(name
, "md%s", to_num_(minor
));
153 if (hd_id
) *hd_id
= 400 + minor
;
154 if (part_id
) *part_id
= 0;
158 #ifdef BLOCK_EXT_MAJOR
159 case (BLOCK_EXT_MAJOR
):
160 if (name
) sprintf(name
, "nvme0n%cp%s", "0123456789"[(minor
/16)], to_num_(minor
));
161 if (hd_id
) *hd_id
= 400 + minor
;
162 if (part_id
) *part_id
= 0;
167 if (hd_id
) *hd_id
= -1;
168 if (part_id
) *part_id
= -1;
172 int short_name_for_device(unsigned major
, unsigned minor
, char *name
) {
173 return device_info(major
,minor
,name
,NULL
,NULL
);
176 int is_partition(unsigned major
, unsigned minor
) {
178 if (!device_info(major
,minor
,NULL
,NULL
,&part_id
)) return 0;
179 return (part_id
!= 0);
182 int device_id_from_name(const char *devname__
, unsigned *pmajor
, unsigned *pminor
) {
183 if (strlen(devname__
)>=512) return -1;
184 char *devname_
, devname
[512];
186 devname_
= str_substitute(devname__
, "/dev/mapper", "/dev");
188 struct stat stat_buf
;
189 BLAHBLAH(1,printf("looking for %s in /dev..\n", devname_
));
191 if (devname_
[0] != '/') snprintf(devname
,512,"/dev/%s", devname_
);
192 else snprintf(devname
,512,"%s",devname_
);
194 free(devname_
); devname_
= 0;
196 if (lstat(devname
,&stat_buf
)) { BLAHBLAH(1,perror(devname
)); return -1; }
197 if (S_ISLNK(stat_buf
.st_mode
)) {
198 devname_
= realpath(devname
, NULL
);
199 if(!devname_
) { BLAHBLAH(1,perror(devname
)); return -1; }
200 strncpy(devname
, devname_
, 512); devname
[511] = 0;
202 if (stat(devname
,&stat_buf
)) { BLAHBLAH(1,perror(devname
)); return -1; }
204 if (!S_ISBLK(stat_buf
.st_mode
)) {
205 fprintf(stderr
, "%s is not a block device..\n", devname
);
208 *pmajor
= major(stat_buf
.st_rdev
);
209 *pminor
= minor(stat_buf
.st_rdev
);
215 /* add a hard-drive if it is a regular ide/scsi/md disk/partition, or return NULL */
216 static DiskList
*create_device(unsigned major
, unsigned minor
, const char *mtab_name
) {
220 if (mtab_name
&& strlen(mtab_name
)) dl
->name
= strdup(mtab_name
);
222 char s
[512]; short_name_for_device(major
,minor
,s
); dl
->name
= strdup(s
);
224 BLAHBLAH(1, printf("create_device(major=%d, minor=%d, mtab_name=%s) : name=%s\n", major
,minor
,mtab_name
,dl
->name
));
225 dl
->major
= major
; dl
->minor
= minor
;
226 if (device_info(major
,minor
,dev_path
,&dl
->hd_id
,&dl
->part_id
) == 0) {
227 BLAHBLAH(1, printf("(%d,%d) is not a known disc type..\n", major
,minor
));
228 free(dl
); return NULL
;
230 dl
->dev_path
= malloc(strlen(dev_path
)+6); assert(dl
->dev_path
);
231 sprintf(dl
->dev_path
, "/dev/%s", dev_path
);
233 if (dl
->part_id
== 0)
234 dl
->enable_hddtemp
= 1;
238 /* add a device (after checking that it is a known device type) */
239 int add_device_by_name(const char *devname
, const char *mtab_name
) {
240 unsigned major
, minor
;
242 BLAHBLAH(1,printf("add_device_by_name(%s,%s)\n", devname
, mtab_name
));
243 if (device_id_from_name(devname
, &major
, &minor
) != 0) return -1;
245 return add_device_by_id(major
,minor
,mtab_name
);
248 /* add a device (after checking that it is a known device type) */
249 int add_device_by_id(unsigned major
, unsigned minor
, const char *mtab_name
) {
250 DiskList
*dl
, *next
, *prev
;
251 BLAHBLAH(1,printf("add_device_by_id(%d,%d,%s)\n", major
, minor
,mtab_name
));
252 /* already known ? */
253 if (find_dev(major
,minor
)) return -1;
254 /* check for known ide/scsi/md disks and then create */
255 dl
= create_device(major
, minor
, mtab_name
); if (!dl
) return -1;
257 for (next
= dlist
, prev
= NULL
; next
; next
=next
->next
) {
258 if (dl
->hd_id
> next
->hd_id
|| (dl
->hd_id
== next
->hd_id
&& dl
->part_id
> next
->part_id
)) break;
262 dl
->next
= dlist
; dlist
= dl
;
264 dl
->next
= prev
->next
; prev
->next
= dl
;
269 strlist
*swaplst
= NULL
;
270 void add_swap(const char *swapdev
) {
271 swaplst
= strlist_ins(swaplst
, swapdev
);
273 strlist
*swap_list() {