< prev index next >

src/hotspot/os/bsd/perfMemory_bsd.cpp

Print this page
rev 50955 : [mq]: readdir


 518   // directory search
 519   char* oldest_user = NULL;
 520   time_t oldest_ctime = 0;
 521 
 522   const char* tmpdirname = os::get_temp_directory();
 523 
 524   // open the temp directory
 525   DIR* tmpdirp = os::opendir(tmpdirname);
 526 
 527   if (tmpdirp == NULL) {
 528     // Cannot open the directory to get the user name, return.
 529     return NULL;
 530   }
 531 
 532   // for each entry in the directory that matches the pattern hsperfdata_*,
 533   // open the directory and check if the file for the given vmid exists.
 534   // The file with the expected name and the latest creation date is used
 535   // to determine the user name for the process id.
 536   //
 537   struct dirent* dentry;
 538   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 539   errno = 0;
 540   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 541 
 542     // check if the directory entry is a hsperfdata file
 543     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 544       continue;
 545     }
 546 
 547     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 548                  strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 549     strcpy(usrdir_name, tmpdirname);
 550     strcat(usrdir_name, "/");
 551     strcat(usrdir_name, dentry->d_name);
 552 
 553     // open the user directory
 554     DIR* subdirp = open_directory_secure(usrdir_name);
 555 
 556     if (subdirp == NULL) {
 557       FREE_C_HEAP_ARRAY(char, usrdir_name);
 558       continue;
 559     }
 560 
 561     struct dirent* udentry;
 562     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 563     errno = 0;
 564     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 565 
 566       if (filename_to_pid(udentry->d_name) == vmid) {
 567         struct stat statbuf;
 568         int result;
 569 
 570         char* filename = NEW_C_HEAP_ARRAY(char,
 571                  strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 572 
 573         strcpy(filename, usrdir_name);
 574         strcat(filename, "/");
 575         strcat(filename, udentry->d_name);
 576 
 577         // don't follow symbolic links for the file
 578         RESTARTABLE(::lstat(filename, &statbuf), result);
 579         if (result == OS_ERR) {
 580            FREE_C_HEAP_ARRAY(char, filename);
 581            continue;
 582         }
 583 
 584         // skip over files that are not regular files.


 588         }
 589 
 590         // compare and save filename with latest creation time
 591         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 592 
 593           if (statbuf.st_ctime > oldest_ctime) {
 594             char* user = strchr(dentry->d_name, '_') + 1;
 595 
 596             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
 597             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 598 
 599             strcpy(oldest_user, user);
 600             oldest_ctime = statbuf.st_ctime;
 601           }
 602         }
 603 
 604         FREE_C_HEAP_ARRAY(char, filename);
 605       }
 606     }
 607     os::closedir(subdirp);
 608     FREE_C_HEAP_ARRAY(char, udbuf);
 609     FREE_C_HEAP_ARRAY(char, usrdir_name);
 610   }
 611   os::closedir(tmpdirp);
 612   FREE_C_HEAP_ARRAY(char, tdbuf);
 613 
 614   return(oldest_user);
 615 }
 616 
 617 // return the name of the user that owns the JVM indicated by the given vmid.
 618 //
 619 static char* get_user_name(int vmid, TRAPS) {
 620   return get_user_name_slow(vmid, THREAD);
 621 }
 622 
 623 // return the file name of the backing store file for the named
 624 // shared memory region for the given user name and vmid.
 625 //
 626 // the caller is expected to free the allocated memory.
 627 //
 628 static char* get_sharedmem_filename(const char* dirname, int vmid) {
 629 
 630   // add 2 for the file separator and a null terminator.
 631   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 632 


 671 //
 672 static void cleanup_sharedmem_resources(const char* dirname) {
 673 
 674   int saved_cwd_fd;
 675   // open the directory and set the current working directory to it
 676   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 677   if (dirp == NULL) {
 678     // directory doesn't exist or is insecure, so there is nothing to cleanup
 679     return;
 680   }
 681 
 682   // for each entry in the directory that matches the expected file
 683   // name pattern, determine if the file resources are stale and if
 684   // so, remove the file resources. Note, instrumented HotSpot processes
 685   // for this user may start and/or terminate during this search and
 686   // remove or create new files in this directory. The behavior of this
 687   // loop under these conditions is dependent upon the implementation of
 688   // opendir/readdir.
 689   //
 690   struct dirent* entry;
 691   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
 692 
 693   errno = 0;
 694   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 695 
 696     pid_t pid = filename_to_pid(entry->d_name);
 697 
 698     if (pid == 0) {
 699 
 700       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 701 
 702         // attempt to remove all unexpected files, except "." and ".."
 703         unlink(entry->d_name);
 704       }
 705 
 706       errno = 0;
 707       continue;
 708     }
 709 
 710     // we now have a file name that converts to a valid integer
 711     // that could represent a process id . if this process id
 712     // matches the current process id or the process is not running,
 713     // then remove the stale file resources.
 714     //
 715     // process liveness is detected by sending signal number 0 to
 716     // the process id (see kill(2)). if kill determines that the
 717     // process does not exist, then the file resources are removed.
 718     // if kill determines that that we don't have permission to
 719     // signal the process, then the file resources are assumed to
 720     // be stale and are removed because the resources for such a
 721     // process should be in a different user specific directory.
 722     //
 723     if ((pid == os::current_process_id()) ||
 724         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 725 
 726         unlink(entry->d_name);
 727     }
 728     errno = 0;
 729   }
 730 
 731   // close the directory and reset the current working directory
 732   close_directory_secure_cwd(dirp, saved_cwd_fd);
 733 
 734   FREE_C_HEAP_ARRAY(char, dbuf);
 735 }
 736 
 737 // make the user specific temporary directory. Returns true if
 738 // the directory exists and is secure upon return. Returns false
 739 // if the directory exists but is either a symlink, is otherwise
 740 // insecure, or if an error occurred.
 741 //
 742 static bool make_user_tmp_dir(const char* dirname) {
 743 
 744   // create the directory with 0755 permissions. note that the directory
 745   // will be owned by euid::egid, which may not be the same as uid::gid.
 746   //
 747   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
 748     if (errno == EEXIST) {
 749       // The directory already exists and was probably created by another
 750       // JVM instance. However, this could also be the result of a
 751       // deliberate symlink. Verify that the existing directory is safe.
 752       //
 753       if (!is_directory_secure(dirname)) {
 754         // directory is not secure




 518   // directory search
 519   char* oldest_user = NULL;
 520   time_t oldest_ctime = 0;
 521 
 522   const char* tmpdirname = os::get_temp_directory();
 523 
 524   // open the temp directory
 525   DIR* tmpdirp = os::opendir(tmpdirname);
 526 
 527   if (tmpdirp == NULL) {
 528     // Cannot open the directory to get the user name, return.
 529     return NULL;
 530   }
 531 
 532   // for each entry in the directory that matches the pattern hsperfdata_*,
 533   // open the directory and check if the file for the given vmid exists.
 534   // The file with the expected name and the latest creation date is used
 535   // to determine the user name for the process id.
 536   //
 537   struct dirent* dentry;

 538   errno = 0;
 539   while ((dentry = os::readdir(tmpdirp)) != NULL) {
 540 
 541     // check if the directory entry is a hsperfdata file
 542     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 543       continue;
 544     }
 545 
 546     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 547                  strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 548     strcpy(usrdir_name, tmpdirname);
 549     strcat(usrdir_name, "/");
 550     strcat(usrdir_name, dentry->d_name);
 551 
 552     // open the user directory
 553     DIR* subdirp = open_directory_secure(usrdir_name);
 554 
 555     if (subdirp == NULL) {
 556       FREE_C_HEAP_ARRAY(char, usrdir_name);
 557       continue;
 558     }
 559 
 560     struct dirent* udentry;

 561     errno = 0;
 562     while ((udentry = os::readdir(subdirp)) != NULL) {
 563 
 564       if (filename_to_pid(udentry->d_name) == vmid) {
 565         struct stat statbuf;
 566         int result;
 567 
 568         char* filename = NEW_C_HEAP_ARRAY(char,
 569                  strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 570 
 571         strcpy(filename, usrdir_name);
 572         strcat(filename, "/");
 573         strcat(filename, udentry->d_name);
 574 
 575         // don't follow symbolic links for the file
 576         RESTARTABLE(::lstat(filename, &statbuf), result);
 577         if (result == OS_ERR) {
 578            FREE_C_HEAP_ARRAY(char, filename);
 579            continue;
 580         }
 581 
 582         // skip over files that are not regular files.


 586         }
 587 
 588         // compare and save filename with latest creation time
 589         if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
 590 
 591           if (statbuf.st_ctime > oldest_ctime) {
 592             char* user = strchr(dentry->d_name, '_') + 1;
 593 
 594             if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
 595             oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 596 
 597             strcpy(oldest_user, user);
 598             oldest_ctime = statbuf.st_ctime;
 599           }
 600         }
 601 
 602         FREE_C_HEAP_ARRAY(char, filename);
 603       }
 604     }
 605     os::closedir(subdirp);

 606     FREE_C_HEAP_ARRAY(char, usrdir_name);
 607   }
 608   os::closedir(tmpdirp);

 609 
 610   return(oldest_user);
 611 }
 612 
 613 // return the name of the user that owns the JVM indicated by the given vmid.
 614 //
 615 static char* get_user_name(int vmid, TRAPS) {
 616   return get_user_name_slow(vmid, THREAD);
 617 }
 618 
 619 // return the file name of the backing store file for the named
 620 // shared memory region for the given user name and vmid.
 621 //
 622 // the caller is expected to free the allocated memory.
 623 //
 624 static char* get_sharedmem_filename(const char* dirname, int vmid) {
 625 
 626   // add 2 for the file separator and a null terminator.
 627   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 628 


 667 //
 668 static void cleanup_sharedmem_resources(const char* dirname) {
 669 
 670   int saved_cwd_fd;
 671   // open the directory and set the current working directory to it
 672   DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
 673   if (dirp == NULL) {
 674     // directory doesn't exist or is insecure, so there is nothing to cleanup
 675     return;
 676   }
 677 
 678   // for each entry in the directory that matches the expected file
 679   // name pattern, determine if the file resources are stale and if
 680   // so, remove the file resources. Note, instrumented HotSpot processes
 681   // for this user may start and/or terminate during this search and
 682   // remove or create new files in this directory. The behavior of this
 683   // loop under these conditions is dependent upon the implementation of
 684   // opendir/readdir.
 685   //
 686   struct dirent* entry;


 687   errno = 0;
 688   while ((entry = os::readdir(dirp)) != NULL) {
 689 
 690     pid_t pid = filename_to_pid(entry->d_name);
 691 
 692     if (pid == 0) {
 693 
 694       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 695 
 696         // attempt to remove all unexpected files, except "." and ".."
 697         unlink(entry->d_name);
 698       }
 699 
 700       errno = 0;
 701       continue;
 702     }
 703 
 704     // we now have a file name that converts to a valid integer
 705     // that could represent a process id . if this process id
 706     // matches the current process id or the process is not running,
 707     // then remove the stale file resources.
 708     //
 709     // process liveness is detected by sending signal number 0 to
 710     // the process id (see kill(2)). if kill determines that the
 711     // process does not exist, then the file resources are removed.
 712     // if kill determines that that we don't have permission to
 713     // signal the process, then the file resources are assumed to
 714     // be stale and are removed because the resources for such a
 715     // process should be in a different user specific directory.
 716     //
 717     if ((pid == os::current_process_id()) ||
 718         (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
 719 
 720         unlink(entry->d_name);
 721     }
 722     errno = 0;
 723   }
 724 
 725   // close the directory and reset the current working directory
 726   close_directory_secure_cwd(dirp, saved_cwd_fd);


 727 }
 728 
 729 // make the user specific temporary directory. Returns true if
 730 // the directory exists and is secure upon return. Returns false
 731 // if the directory exists but is either a symlink, is otherwise
 732 // insecure, or if an error occurred.
 733 //
 734 static bool make_user_tmp_dir(const char* dirname) {
 735 
 736   // create the directory with 0755 permissions. note that the directory
 737   // will be owned by euid::egid, which may not be the same as uid::gid.
 738   //
 739   if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
 740     if (errno == EEXIST) {
 741       // The directory already exists and was probably created by another
 742       // JVM instance. However, this could also be the result of a
 743       // deliberate symlink. Verify that the existing directory is safe.
 744       //
 745       if (!is_directory_secure(dirname)) {
 746         // directory is not secure


< prev index next >