Browse Source

[LibOS] Cleanup of mprotect(PAL_PROT_READ) on checkpoint

During creation of the checkpoint, all memory regions must be marked as
readable (and after the creation reverted back to original permissions).
Previously, this was achieved in an ad-hoc manner (e.g., in VMA
preparation logic). This commit consolidates this logic in one place.
Isaku Yamahata 4 years ago
parent
commit
4843aa073c
2 changed files with 20 additions and 9 deletions
  1. 0 6
      LibOS/shim/src/bookkeep/shim_vma.c
  2. 20 3
      LibOS/shim/src/shim_checkpoint.c

+ 0 - 6
LibOS/shim/src/bookkeep/shim_vma.c

@@ -1124,12 +1124,6 @@ BEGIN_CP_FUNC(vma)
                 }
             }
             if (send_size > 0) {
-                if (!(pal_prot & PAL_PROT_READ)) {
-                    /* Make the area readable */
-                    DkVirtualMemoryProtect(send_addr, send_size,
-                                           pal_prot|PAL_PROT_READ);
-                }
-
                 struct shim_mem_entry * mem;
                 DO_CP_SIZE(memory, send_addr, send_size, &mem);
                 mem->prot = pal_prot;

+ 20 - 3
LibOS/shim/src/shim_checkpoint.c

@@ -383,7 +383,15 @@ static int send_checkpoint_on_stream (PAL_HANDLE stream,
     for (int i = 0 ; i < mem_nentries ; i++) {
         size_t mem_size = mem_entries[i]->size;
         void * mem_addr = mem_entries[i]->addr;
+
+        if (!(mem_entries[i]->prot & PAL_PROT_READ) && mem_size > 0) {
+            /* Make the area readable */
+            if (!DkVirtualMemoryProtect(mem_addr, mem_size, mem_entries[i]->prot | PAL_PROT_READ))
+                return -PAL_ERRNO;
+        }
+
         bytes = 0;
+        int error = 0;
         do {
             PAL_NUM ret = DkStreamWrite(stream, 0, mem_size - bytes,
                                        mem_addr + bytes, NULL);
@@ -391,14 +399,23 @@ static int send_checkpoint_on_stream (PAL_HANDLE stream,
                 if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN ||
                     PAL_ERRNO == EWOULDBLOCK)
                     continue;
-                return -PAL_ERRNO;
+                error = -PAL_ERRNO;
+                break;
             }
 
             bytes += ret;
         } while (bytes < mem_entries[i]->size);
 
-        if (!(mem_entries[i]->prot & PAL_PROT_READ))
-            DkVirtualMemoryProtect(mem_addr, mem_size, mem_entries[i]->prot);
+        if (!(mem_entries[i]->prot & PAL_PROT_READ) && mem_size > 0) {
+            /* the area was made readable above; revert to original permissions */
+            if (!DkVirtualMemoryProtect(mem_addr, mem_size, mem_entries[i]->prot)) {
+                if (!error) {
+                    error = -PAL_ERRNO;
+                }
+            }
+        }
+        if (error < 0)
+            return error;
 
         mem_entries[i]->size = mem_size;
         ADD_PROFILE_OCCURENCE(migrate_send_on_stream, mem_size);