diff options
author | Christopher Tate <ctate@google.com> | 2011-06-10 11:38:37 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2011-06-20 16:19:42 -0700 |
commit | 5b811fa5dd00288954f15209a56aea03d5e4a004 (patch) | |
tree | a6ddbb81a410ed3d1a6f185b4d7a0b2be13e3585 /adb/backup_service.c | |
parent | 352dfdfaea55601f2c36fe7286a158e84028bcf3 (diff) | |
download | system_core-5b811fa5dd00288954f15209a56aea03d5e4a004.zip system_core-5b811fa5dd00288954f15209a56aea03d5e4a004.tar.gz system_core-5b811fa5dd00288954f15209a56aea03d5e4a004.tar.bz2 |
Tidy up the end-of-data handling in backup
* Increase transfer buffer size to 32K
* Add logging about error conditions and fd teardown
* Pass the fd number as a command line option to the 'bu' subprocess
* Properly harvest the 'bu' subprocess after it's done
Change-Id: Id44dde25778ecf43c5604fd9d01d726ba58861e5
Diffstat (limited to 'adb/backup_service.c')
-rw-r--r-- | adb/backup_service.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/adb/backup_service.c b/adb/backup_service.c index 2e6e754..4f0c8ac 100644 --- a/adb/backup_service.c +++ b/adb/backup_service.c @@ -22,6 +22,23 @@ #define TRACE_TAG TRACE_ADB #include "adb.h" +// socketpair but do *not* mark as close_on_exec +static int backup_socketpair(int sv[2]) { + int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv ); + if (rc < 0) + return -1; + + return 0; +} + +static void* backup_child_waiter(void* pid_cookie) { + int status; + + waitpid((pid_t) pid_cookie, &status, 0); + D("harvested backup/restore child, status=%d\n", status); + return NULL; +} + /* returns the data socket passing the backup data here for forwarding */ int backup_service(BackupOperation op, char* args) { pid_t pid; @@ -42,12 +59,15 @@ int backup_service(BackupOperation op, char* args) { // set up the pipe from the subprocess to here // parent will read s[0]; child will write s[1] - if (adb_socketpair(s)) { + if (backup_socketpair(s)) { D("can't create backup/restore socketpair\n"); fprintf(stderr, "unable to create backup/restore socketpair\n"); return -1; } + D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]); + close_on_exec(s[0]); // only the side we hold on to + // spin off the child process to run the backup command pid = fork(); if (pid < 0) { @@ -61,12 +81,14 @@ int backup_service(BackupOperation op, char* args) { // Great, we're off and running. if (pid == 0) { + // child -- actually run the backup here char* p; int argc; + char portnum[16]; char** bu_args; - // child -- actually run the backup here - argc = 2; // room for the basic 'bu' argv[0] and '[operation]' argv[1] + // fixed args: [0] is 'bu', [1] is the port number, [2] is the 'operation' string + argc = 3; for (p = (char*)args; p && *p; ) { argc++; while (*p && *p != ':') p++; @@ -74,9 +96,13 @@ int backup_service(BackupOperation op, char* args) { } bu_args = (char**) alloca(argc*sizeof(char*) + 1); - bu_args[0] = "bu"; - bu_args[1] = operation; - argc = 2; // run through again to build the argv array + + // run through again to build the argv array + argc = 0; + bu_args[argc++] = "bu"; + snprintf(portnum, sizeof(portnum), "%d", s[1]); + bu_args[argc++] = portnum; + bu_args[argc++] = operation; for (p = (char*)args; p && *p; ) { bu_args[argc++] = p; while (*p && *p != ':') p++; @@ -90,7 +116,6 @@ int backup_service(BackupOperation op, char* args) { // Close the half of the socket that we don't care about, route 'bu's console // to the output socket, and off we go adb_close(s[0]); - dup2(s[1], socketnum); // off we go execvp("/system/bin/bu", (char * const *)bu_args); @@ -98,8 +123,18 @@ int backup_service(BackupOperation op, char* args) { fprintf(stderr, "Unable to exec 'bu', bailing\n"); exit(-1); } else { + adb_thread_t t; + // parent, i.e. adbd -- close the sending half of the socket + D("fork() returned pid %d\n", pid); adb_close(s[1]); + + // spin a thread to harvest the child process + if (adb_thread_create(&t, backup_child_waiter, (void*)pid)) { + adb_close(s[0]); + D("Unable to create child harvester\n"); + return -1; + } } // we'll be reading from s[0] as the data is sent by the child process |