remount_service.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (C) 2008 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <string.h>
  20. #include <fcntl.h>
  21. #include <sys/mount.h>
  22. #include <errno.h>
  23. #include "sysdeps.h"
  24. #define TRACE_TAG TRACE_ADB
  25. #include "adb.h"
  26. static int system_ro = 1;
  27. /* Returns the device used to mount a directory in /proc/mounts */
  28. static char *find_mount(const char *dir)
  29. {
  30. int fd;
  31. int res;
  32. int size;
  33. char *token = NULL;
  34. const char delims[] = "\n";
  35. char buf[4096];
  36. fd = unix_open("/proc/mounts", O_RDONLY);
  37. if (fd < 0)
  38. return NULL;
  39. buf[sizeof(buf) - 1] = '\0';
  40. size = adb_read(fd, buf, sizeof(buf) - 1);
  41. adb_close(fd);
  42. token = strtok(buf, delims);
  43. while (token) {
  44. char mount_dev[256];
  45. char mount_dir[256];
  46. int mount_freq;
  47. int mount_passno;
  48. res = sscanf(token, "%255s %255s %*s %*s %d %d\n",
  49. mount_dev, mount_dir, &mount_freq, &mount_passno);
  50. mount_dev[255] = 0;
  51. mount_dir[255] = 0;
  52. if (res == 4 && (strcmp(dir, mount_dir) == 0))
  53. return strdup(mount_dev);
  54. token = strtok(NULL, delims);
  55. }
  56. return NULL;
  57. }
  58. /* Init mounts /system as read only, remount to enable writes. */
  59. static int remount_system()
  60. {
  61. char *dev;
  62. if (system_ro == 0) {
  63. return 0;
  64. }
  65. dev = find_mount("/system");
  66. if (!dev)
  67. return -1;
  68. system_ro = mount(dev, "/system", "none", MS_REMOUNT, NULL);
  69. free(dev);
  70. return system_ro;
  71. }
  72. static void write_string(int fd, const char* str)
  73. {
  74. writex(fd, str, strlen(str));
  75. }
  76. void remount_service(int fd, void *cookie)
  77. {
  78. int ret = remount_system();
  79. if (!ret)
  80. write_string(fd, "remount succeeded\n");
  81. else {
  82. char buffer[200];
  83. snprintf(buffer, sizeof(buffer), "remount failed: %s\n", strerror(errno));
  84. write_string(fd, buffer);
  85. }
  86. adb_close(fd);
  87. }