mount.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/stat.h>
  6. #include <sys/types.h>
  7. #include <fcntl.h>
  8. #include <sys/ioctl.h>
  9. #include <linux/hdreg.h>
  10. #include <scsi/sg.h>
  11. #include <dirent.h>
  12. #include <sys/wait.h>
  13. #include <sys/inotify.h>
  14. #include <sys/stat.h>
  15. #include <sys/types.h>
  16. #include <glob.h>
  17. #include <libgen.h>
  18. #include <poll.h>
  19. #include <dirent.h>
  20. #include <syslog.h>
  21. #include "include/log.h"
  22. #include "include/list.h"
  23. #include "include/sys.h"
  24. #include "include/signal.h"
  25. #include "include/timer.h"
  26. #include "include/autofs.h"
  27. #include "include/ucix.h"
  28. #include "include/fs.h"
  29. #include "include/mount.h"
  30. int mount_new(char *path, char *dev);
  31. struct list_head mounts;
  32. struct mount {
  33. struct list_head list;
  34. char name[64];
  35. char dev[64];
  36. char serial[64];
  37. char vendor[64];
  38. char model[64];
  39. char rev[64];
  40. int mounted;
  41. int ignore;
  42. char size[64];
  43. char sector_size[64];
  44. int fs;
  45. };
  46. char *fs_names[] = {
  47. "",
  48. "",
  49. "MBR",
  50. "EXT2",
  51. "EXT3",
  52. "FAT",
  53. "HFSPLUS",
  54. "",
  55. "NTFS",
  56. "",
  57. "EXFAT",
  58. "EXT4"
  59. };
  60. #define MAX_MOUNTED 32
  61. #define MAX_MOUNT_NAME 32
  62. char mounted[MAX_MOUNTED][3][MAX_MOUNT_NAME];
  63. int mounted_count = 0;
  64. extern char uci_path[32];
  65. static void mount_dump_uci_state(void)
  66. {
  67. struct uci_context *ctx;
  68. struct list_head *p;
  69. char mountd[] = {"mountd"};
  70. char type[] = {"mountd_disc"};
  71. int mounted = 0;
  72. unsigned long long int size = 0;
  73. unlink("/var/state/mountd");
  74. ctx = ucix_init("mountd");
  75. uci_set_savedir(ctx, "/var/state/");
  76. ucix_add_option_int(ctx, mountd, mountd, "count", list_count(&mounts));
  77. list_for_each(p, &mounts)
  78. {
  79. struct mount *q = container_of(p, struct mount, list);
  80. char t[64];
  81. if(q->fs == EXTENDED)
  82. continue;
  83. ucix_add_section(ctx, mountd, q->serial, type);
  84. strcpy(t, q->dev);
  85. t[3] = '\0';
  86. ucix_add_option(ctx, mountd, q->serial, "disc", t);
  87. ucix_add_option(ctx, mountd, q->serial, "sector_size", q->sector_size);
  88. snprintf(t, 64, "part%dmounted", atoi(&q->dev[3]));
  89. ucix_add_option(ctx, mountd, q->serial, t, (q->mounted)?("1"):("0"));
  90. ucix_add_option(ctx, mountd, q->serial, "vendor", q->vendor);
  91. ucix_add_option(ctx, mountd, q->serial, "model", q->model);
  92. ucix_add_option(ctx, mountd, q->serial, "rev", q->rev);
  93. snprintf(t, 64, "size%d", atoi(&q->dev[3]));
  94. ucix_add_option(ctx, mountd, q->serial, t, q->size);
  95. if(q->fs > MBR && q->fs <= EXT4)
  96. {
  97. snprintf(t, 64, "fs%d", atoi(&q->dev[3]));
  98. ucix_add_option(ctx, mountd, q->serial, t, fs_names[q->fs]);
  99. }
  100. if(q->mounted)
  101. mounted++;
  102. if((!q->ignore) && q->size && q->sector_size)
  103. size = size + (((unsigned long long int)atoi(q->size)) * ((unsigned long long int)atoi(q->sector_size)));
  104. }
  105. ucix_add_option_int(ctx, mountd, mountd, "mounted", mounted);
  106. ucix_add_option_int(ctx, mountd, mountd, "total", size);
  107. system_printf("echo -n %llu > /tmp/run/mountd_size", size);
  108. ucix_save_state(ctx, "mountd");
  109. ucix_cleanup(ctx);
  110. }
  111. static struct mount* mount_find(char *name, char *dev)
  112. {
  113. struct list_head *p;
  114. list_for_each(p, &mounts)
  115. {
  116. struct mount *q = container_of(p, struct mount, list);
  117. if(name)
  118. if(!strcmp(q->name, name))
  119. return q;
  120. if(dev)
  121. if(!strcmp(q->dev, dev))
  122. return q;
  123. }
  124. return 0;
  125. }
  126. static void mount_add_list(char *name, char *dev, char *serial,
  127. char *vendor, char *model, char *rev, int ignore, char *size, char *sector_size, int fs)
  128. {
  129. struct mount *mount;
  130. char tmp[64], tmp2[64];
  131. if(fs <= MBR || fs > EXT4)
  132. return;
  133. mount = malloc(sizeof(struct mount));
  134. INIT_LIST_HEAD(&mount->list);
  135. strncpy(mount->vendor, vendor, 64);
  136. strncpy(mount->model, model, 64);
  137. strncpy(mount->rev, rev, 64);
  138. strncpy(mount->name, name, 64);
  139. strncpy(mount->dev, dev, 64);
  140. strncpy(mount->serial, serial, 64);
  141. strncpy(mount->size, size, 64);
  142. strncpy(mount->sector_size, sector_size, 64);
  143. mount->ignore = ignore;
  144. mount->mounted = 0;
  145. mount->fs = fs;
  146. list_add(&mount->list, &mounts);
  147. if((!mount->ignore) && (mount->fs > MBR) && (mount->fs <= EXT4))
  148. {
  149. log_printf("new mount : %s -> %s (%s)\n", name, dev, fs_names[mount->fs]);
  150. snprintf(tmp, 64, "%s%s", uci_path, name);
  151. snprintf(tmp2, 64, "/tmp/run/mountd/%s", dev);
  152. symlink(tmp2, tmp);
  153. mount_new("/tmp/run/mountd/", dev);
  154. }
  155. }
  156. static int mount_check_disc(char *disc)
  157. {
  158. FILE *fp = fopen("/proc/mounts", "r");
  159. char tmp[256];
  160. int avail = -1;
  161. if(!fp)
  162. {
  163. log_printf("error reading /proc/mounts");
  164. fclose(fp);
  165. return avail;
  166. }
  167. while((fgets(tmp, 256, fp) > 0) && (avail == -1))
  168. {
  169. char *t;
  170. char tmp2[32];
  171. t = strstr(tmp, " ");
  172. if(t)
  173. {
  174. int l;
  175. *t = '\0';
  176. l = snprintf(tmp2, 31, "/dev/%s", disc);
  177. if(!strncmp(tmp, tmp2, l))
  178. avail = 0;
  179. }
  180. }
  181. fclose(fp);
  182. return avail;
  183. }
  184. static int mount_wait_for_disc(char *disc)
  185. {
  186. int i = 10;
  187. while(i--)
  188. {
  189. int ret = mount_check_disc(disc);
  190. if(!ret)
  191. return ret;
  192. poll(0, 0, 100);
  193. }
  194. return -1;
  195. }
  196. int mount_new(char *path, char *dev)
  197. {
  198. struct mount *mount;
  199. char tmp[256];
  200. int ret = 1;
  201. pid_t pid;
  202. mount = mount_find(0, dev);
  203. if(!mount)
  204. {
  205. log_printf("request for invalid path %s%s\n", path, dev);
  206. return -1;
  207. }
  208. if(mount->ignore || mount->mounted || mount->fs == EXTENDED)
  209. return -1;
  210. snprintf(tmp, 256, "%s%s", path, mount->dev);
  211. log_printf("mounting %s\n", tmp);
  212. mkdir(tmp, 777);
  213. pid = autofs_safe_fork();
  214. if(!pid)
  215. {
  216. if(mount->fs == EXFAT)
  217. {
  218. log_printf("mount -t exfat -o rw,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  219. ret = system_printf("mount -t exfat -o rw,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  220. }
  221. if(mount->fs == FAT)
  222. {
  223. log_printf("mount -t vfat -o rw,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  224. ret = system_printf("mount -t vfat -o rw,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  225. }
  226. if(mount->fs == EXT4)
  227. {
  228. log_printf("mount -t ext4 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  229. ret = system_printf("mount -t ext4 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  230. }
  231. if(mount->fs == EXT3)
  232. {
  233. log_printf("mount -t ext3 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  234. ret = system_printf("mount -t ext3 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  235. }
  236. if(mount->fs == EXT2)
  237. {
  238. log_printf("mount -t ext2 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  239. ret = system_printf("mount -t ext2 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  240. }
  241. if(mount->fs == HFSPLUS)
  242. {
  243. log_printf("mount -t hfsplus -o rw,defaults,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  244. ret = system_printf("mount -t hfsplus -o rw,defaults,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  245. }
  246. if(mount->fs == NTFS)
  247. {
  248. log_printf("ntfs-3g /dev/%s %s -o force", mount->dev, tmp);
  249. ret = system_printf("ntfs-3g /dev/%s %s -o force", mount->dev, tmp);
  250. }
  251. exit(WEXITSTATUS(ret));
  252. }
  253. pid = waitpid(pid, &ret, 0);
  254. ret = WEXITSTATUS(ret);
  255. log_printf("----------> mount ret = %d\n", ret);
  256. if(ret && (ret != 0xff))
  257. return -1;
  258. if(mount_wait_for_disc(mount->dev) == 0)
  259. {
  260. mount->mounted = 1;
  261. mount_dump_uci_state();
  262. } else return -1;
  263. return 0;
  264. }
  265. int mount_remove(char *path, char *dev)
  266. {
  267. struct mount *mount;
  268. char tmp[256];
  269. int ret;
  270. snprintf(tmp, 256, "%s%s", path, dev);
  271. log_printf("%s has expired... unmounting\n", tmp);
  272. ret = system_printf("/bin/umount %s", tmp);
  273. if(ret != 0)
  274. return 0;
  275. rmdir(tmp);
  276. mount = mount_find(0, dev);
  277. if(mount)
  278. mount->mounted = 0;
  279. log_printf("finished unmounting\n");
  280. mount_dump_uci_state();
  281. return 0;
  282. }
  283. static int dir_sort(const struct dirent **a, const struct dirent **b)
  284. {
  285. return 0;
  286. }
  287. static int dir_filter(const struct dirent *a)
  288. {
  289. if(strstr(a->d_name, ":"))
  290. return 1;
  291. return 0;
  292. }
  293. static char* mount_get_serial(char *dev)
  294. {
  295. static char tmp[64];
  296. static char tmp2[64];
  297. int disc;
  298. static struct hd_driveid hd;
  299. int i;
  300. static char *serial;
  301. static char disc_id[13];
  302. snprintf(tmp, 64, "/dev/%s", dev);
  303. disc = open(tmp, O_RDONLY);
  304. if(!disc)
  305. {
  306. log_printf("Trying to open unknown disc\n");
  307. return 0;
  308. }
  309. i = ioctl(disc, HDIO_GET_IDENTITY, &hd);
  310. close(disc);
  311. if(!i)
  312. serial = (char*)hd.serial_no;
  313. /* if we failed, it probably a usb storage device */
  314. /* there must be a better way for this */
  315. if(i)
  316. {
  317. struct dirent **namelist;
  318. int n = scandir("/sys/bus/scsi/devices/", &namelist, dir_filter, dir_sort);
  319. if(n > 0)
  320. {
  321. while(n--)
  322. {
  323. char *t = strstr(namelist[n]->d_name, ":");
  324. if(t)
  325. {
  326. int id;
  327. struct stat buf;
  328. char tmp3[64];
  329. int ret;
  330. *t = 0;
  331. id = atoi(namelist[n]->d_name);
  332. *t = ':';
  333. sprintf(tmp3, "/sys/bus/scsi/devices/%s/block:%s/", namelist[n]->d_name, dev);
  334. ret = stat(tmp3, &buf);
  335. if(ret)
  336. {
  337. sprintf(tmp3, "/sys/bus/scsi/devices/%s/block/%s/", namelist[n]->d_name, dev);
  338. ret = stat(tmp3, &buf);
  339. }
  340. if(!ret)
  341. {
  342. FILE *fp;
  343. snprintf(tmp2, 64, "/proc/scsi/usb-storage/%d", id);
  344. fp = fopen(tmp2, "r");
  345. if(fp)
  346. {
  347. while(fgets(tmp2, 64, fp) > 0)
  348. {
  349. serial = strstr(tmp2, "Serial Number:");
  350. if(serial)
  351. {
  352. serial += strlen("Serial Number: ");
  353. serial[strlen(serial) - 1] = '\0';
  354. i = 0;
  355. break;
  356. }
  357. }
  358. fclose(fp);
  359. }
  360. }
  361. }
  362. free(namelist[n]);
  363. }
  364. free(namelist);
  365. }
  366. }
  367. if(i)
  368. {
  369. log_printf("could not find a serial number for the device %s\n", dev);
  370. } else {
  371. /* serial string id is cheap, but makes the discs anonymous */
  372. unsigned char uniq[6];
  373. unsigned int *u = (unsigned int*) uniq;
  374. int l = strlen(serial);
  375. int i;
  376. memset(disc_id, 0, 13);
  377. memset(uniq, 0, 6);
  378. for(i = 0; i < l; i++)
  379. {
  380. uniq[i%6] += serial[i];
  381. }
  382. sprintf(disc_id, "%08X%02X%02X", *u, uniq[4], uniq[5]);
  383. //log_printf("Serial number - %s %s\n", serial, disc_id);
  384. return disc_id;
  385. }
  386. sprintf(disc_id, "000000000000");
  387. return disc_id;
  388. }
  389. static void mount_dev_add(char *dev)
  390. {
  391. struct mount *mount = mount_find(0, dev);
  392. if(!mount)
  393. {
  394. char node[64];
  395. char name[64];
  396. int ignore = 0;
  397. char *s;
  398. char tmp[64];
  399. char tmp2[64];
  400. char *p;
  401. struct uci_context *ctx;
  402. char vendor[64];
  403. char model[64];
  404. char rev[64];
  405. char size[64];
  406. char sector_size[64];
  407. FILE *fp;
  408. int offset = 3;
  409. strcpy(name, dev);
  410. if (!strncmp(name, "mmcblk", 6))
  411. offset = 7;
  412. name[offset] = '\0';
  413. s = mount_get_serial(name);
  414. if(!s) {
  415. return;
  416. }
  417. if (!strncmp(name, "mmcblk", 6)) {
  418. snprintf(tmp, 64, "part%s", &dev[8]);
  419. snprintf(node, 64, "SD-P%s", &dev[8]);
  420. } else {
  421. snprintf(tmp, 64, "part%s", &dev[3]);
  422. snprintf(node, 64, "USB-%s", &dev[2]);
  423. }
  424. if(node[4] >= 'a' && node[4] <= 'z')
  425. {
  426. node[4] -= 'a';
  427. node[4] += 'A';
  428. }
  429. ctx = ucix_init("mountd");
  430. p = ucix_get_option(ctx, "mountd", s, tmp);
  431. ucix_cleanup(ctx);
  432. if(p)
  433. {
  434. if(strlen(p) == 1)
  435. {
  436. if(*p == '0')
  437. ignore = 1;
  438. } else {
  439. snprintf(node, 64, "%s", p);
  440. }
  441. }
  442. strcpy(name, dev);
  443. name[3] = '\0';
  444. snprintf(tmp, 64, "/sys/class/block/%s/device/model", name);
  445. fp = fopen(tmp, "r");
  446. if(!fp)
  447. {
  448. snprintf(tmp, 64, "/sys/block/%s/device/model", name);
  449. fp = fopen(tmp, "r");
  450. }
  451. if(!fp)
  452. snprintf(model, 64, "unknown");
  453. else {
  454. fgets(model, 64, fp);
  455. model[strlen(model) - 1] = '\0';;
  456. fclose(fp);
  457. }
  458. snprintf(tmp, 64, "/sys/class/block/%s/device/vendor", name);
  459. fp = fopen(tmp, "r");
  460. if(!fp)
  461. {
  462. snprintf(tmp, 64, "/sys/block/%s/device/vendor", name);
  463. fp = fopen(tmp, "r");
  464. }
  465. if(!fp)
  466. snprintf(vendor, 64, "unknown");
  467. else {
  468. fgets(vendor, 64, fp);
  469. vendor[strlen(vendor) - 1] = '\0';
  470. fclose(fp);
  471. }
  472. snprintf(tmp, 64, "/sys/class/block/%s/device/rev", name);
  473. fp = fopen(tmp, "r");
  474. if(!fp)
  475. {
  476. snprintf(tmp, 64, "/sys/block/%s/device/rev", name);
  477. fp = fopen(tmp, "r");
  478. }
  479. if(!fp)
  480. snprintf(rev, 64, "unknown");
  481. else {
  482. fgets(rev, 64, fp);
  483. rev[strlen(rev) - 1] = '\0';
  484. fclose(fp);
  485. }
  486. snprintf(tmp, 64, "/sys/class/block/%s/size", dev);
  487. fp = fopen(tmp, "r");
  488. if(!fp)
  489. {
  490. snprintf(tmp, 64, "/sys/block/%s/%s/size", name, dev);
  491. fp = fopen(tmp, "r");
  492. }
  493. if(!fp)
  494. snprintf(size, 64, "unknown");
  495. else {
  496. fgets(size, 64, fp);
  497. size[strlen(size) - 1] = '\0';
  498. fclose(fp);
  499. }
  500. strcpy(tmp2, dev);
  501. tmp2[3] = '\0';
  502. snprintf(tmp, 64, "/sys/block/%s/queue/hw_sector_size", tmp2);
  503. fp = fopen(tmp, "r");
  504. if(!fp)
  505. snprintf(sector_size, 64, "unknown");
  506. else {
  507. fgets(sector_size, 64, fp);
  508. sector_size[strlen(sector_size) - 1] = '\0';
  509. fclose(fp);
  510. }
  511. snprintf(tmp, 64, "/dev/%s", dev);
  512. mount_add_list(node, dev, s, vendor, model, rev, ignore, size, sector_size, detect_fs(tmp));
  513. mount_dump_uci_state();
  514. }
  515. }
  516. static void mount_dev_del(char *dev)
  517. {
  518. struct mount *mount = mount_find(0, dev);
  519. char tmp[256];
  520. if(mount)
  521. {
  522. if(mount->mounted)
  523. {
  524. snprintf(tmp, 256, "%s%s", "/tmp/run/mountd/", mount->name);
  525. log_printf("%s has dissappeared ... unmounting\n", tmp);
  526. snprintf(tmp, 256, "%s%s", "/tmp/run/mountd/", mount->dev);
  527. system_printf("/bin/umount %s", tmp);
  528. rmdir(tmp);
  529. snprintf(tmp, 64, "%s%s", uci_path, mount->name);
  530. unlink(tmp);
  531. mount_dump_uci_state();
  532. }
  533. }
  534. }
  535. void mount_dump_list(void)
  536. {
  537. struct list_head *p;
  538. list_for_each(p, &mounts)
  539. {
  540. struct mount *q = container_of(p, struct mount, list);
  541. log_printf("* %s %s %d\n", q->name, q->dev, q->mounted);
  542. }
  543. }
  544. char* is_mounted(char *block, char *path)
  545. {
  546. int i;
  547. for(i = 0; i < mounted_count; i++)
  548. {
  549. if(block)
  550. if(!strncmp(&mounted[i][0][0], block, strlen(&mounted[i][0][0])))
  551. return &mounted[i][0][0];
  552. if(path)
  553. if(!strncmp(&mounted[i][1][1], &path[1], strlen(&mounted[i][1][0])))
  554. return &mounted[i][0][0];
  555. }
  556. return 0;
  557. }
  558. static void mount_check_mount_list(void)
  559. {
  560. FILE *fp = fopen("/proc/mounts", "r");
  561. char tmp[256];
  562. if(!fp)
  563. {
  564. log_printf("error reading /proc/mounts");
  565. fclose(fp);
  566. return;
  567. }
  568. mounted_count = 0;
  569. while(fgets(tmp, 256, fp) > 0)
  570. {
  571. char *t, *t2;
  572. t = strstr(tmp, " ");
  573. if(t)
  574. {
  575. *t = '\0';
  576. t++;
  577. } else t = tmp;
  578. strncpy(&mounted[mounted_count][0][0], tmp, MAX_MOUNT_NAME);
  579. t2 = strstr(t, " ");
  580. if(t2)
  581. {
  582. *t2 = '\0';
  583. t2++;
  584. } else t2 = t;
  585. strncpy(&mounted[mounted_count][1][0], t, MAX_MOUNT_NAME);
  586. t = strstr(t2, " ");
  587. if(t)
  588. {
  589. *t = '\0';
  590. t++;
  591. } else t = tmp;
  592. strncpy(&mounted[mounted_count][2][0], t2, MAX_MOUNT_NAME);
  593. /* printf("%s %s %s\n",
  594. mounted[mounted_count][0],
  595. mounted[mounted_count][1],
  596. mounted[mounted_count][2]);*/
  597. if(mounted_count < MAX_MOUNTED - 1)
  598. mounted_count++;
  599. else
  600. log_printf("found more than %d mounts \n", MAX_MOUNTED);
  601. }
  602. fclose(fp);
  603. }
  604. /* FIXME: we need more intelligence here */
  605. static int dir_filter2(const struct dirent *a)
  606. {
  607. if(!strncmp(a->d_name, "mmcblk", 6) || !strncmp(a->d_name, "sd", 2))
  608. return 1;
  609. return 0;
  610. }
  611. #define MAX_BLOCK 64
  612. char block[MAX_BLOCK][MAX_BLOCK];
  613. int blk_cnt = 0;
  614. static int check_block(char *b)
  615. {
  616. int i;
  617. for(i = 0; i < blk_cnt; i++)
  618. {
  619. if(!strcmp(block[i], b))
  620. return 1;
  621. }
  622. return 0;
  623. }
  624. static void mount_enum_drives(void)
  625. {
  626. struct dirent **namelist, **namelist2;
  627. int i, n = scandir("/sys/block/", &namelist, dir_filter2, dir_sort);
  628. struct list_head *p;
  629. blk_cnt = 0;
  630. if(n > 0)
  631. {
  632. while(n--)
  633. {
  634. if(blk_cnt < MAX_BLOCK)
  635. {
  636. int m;
  637. char tmp[64];
  638. snprintf(tmp, 64, "/sys/block/%s/", namelist[n]->d_name);
  639. m = scandir(tmp, &namelist2, dir_filter2, dir_sort);
  640. while(m--)
  641. {
  642. strncpy(&block[blk_cnt][0], namelist2[m]->d_name, MAX_BLOCK);
  643. blk_cnt++;
  644. free(namelist2[m]);
  645. }
  646. free(namelist2);
  647. }
  648. free(namelist[n]);
  649. }
  650. free(namelist);
  651. }
  652. p = mounts.next;
  653. while(p != &mounts)
  654. {
  655. struct mount *q = container_of(p, struct mount, list);
  656. char tmp[64];
  657. struct uci_context *ctx;
  658. int del = 0;
  659. char *t;
  660. snprintf(tmp, 64, "part%s", &q->dev[3]);
  661. ctx = ucix_init("mountd");
  662. t = ucix_get_option(ctx, "mountd", q->serial, tmp);
  663. ucix_cleanup(ctx);
  664. if(t && !q->mounted)
  665. {
  666. if(!strcmp(t, "0"))
  667. {
  668. if(!q->ignore)
  669. del = 1;
  670. } else if(!strcmp(t, "1"))
  671. {
  672. if(strncmp(q->name, "Disc-", 5))
  673. del = 1;
  674. } else if(strcmp(q->name, t))
  675. {
  676. del = 1;
  677. }
  678. }
  679. if(!check_block(q->dev)||del)
  680. {
  681. mount_dev_del(q->dev);
  682. p->prev->next = p->next;
  683. p->next->prev = p->prev;
  684. p = p->next;
  685. log_printf("removing %s\n", q->dev);
  686. snprintf(tmp, 64, "%s%s", uci_path, q->name);
  687. unlink(tmp);
  688. system_printf("/etc/mountd/event remove %s %s", q->dev, q->name);
  689. free(q);
  690. mount_dump_uci_state();
  691. system_printf("/etc/fonstated/ReloadSamba");
  692. } else p = p->next;
  693. }
  694. for(i = 0; i < blk_cnt; i++)
  695. mount_dev_add(block[i]);
  696. }
  697. static void mount_check_enum(void)
  698. {
  699. waitpid(-1, 0, WNOHANG);
  700. mount_enum_drives();
  701. }
  702. void mount_init(void)
  703. {
  704. INIT_LIST_HEAD(&mounts);
  705. timer_add(mount_check_mount_list, 2);
  706. timer_add(mount_check_enum, 1);
  707. mount_check_mount_list();
  708. }