< prev index next >

src/hotspot/os/windows/perfMemory_windows.cpp

Print this page
rev 50955 : [mq]: readdir


 301 static char* get_user_name_slow(int vmid) {
 302 
 303   // directory search
 304   char* latest_user = NULL;
 305   time_t latest_ctime = 0;
 306 
 307   const char* tmpdirname = os::get_temp_directory();
 308 
 309   DIR* tmpdirp = os::opendir(tmpdirname);
 310 
 311   if (tmpdirp == NULL) {
 312     return NULL;
 313   }
 314 
 315   // for each entry in the directory that matches the pattern hsperfdata_*,
 316   // open the directory and check if the file for the given vmid exists.
 317   // The file with the expected name and the latest creation date is used
 318   // to determine the user name for the process id.
 319   //
 320   struct dirent* dentry;
 321   char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
 322   errno = 0;
 323   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 324 
 325     // check if the directory entry is a hsperfdata file
 326     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 327       continue;
 328     }
 329 
 330     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 331         strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 332     strcpy(usrdir_name, tmpdirname);
 333     strcat(usrdir_name, "\\");
 334     strcat(usrdir_name, dentry->d_name);
 335 
 336     DIR* subdirp = os::opendir(usrdir_name);
 337 
 338     if (subdirp == NULL) {
 339       FREE_C_HEAP_ARRAY(char, usrdir_name);
 340       continue;
 341     }
 342 
 343     // Since we don't create the backing store files in directories
 344     // pointed to by symbolic links, we also don't follow them when
 345     // looking for the files. We check for a symbolic link after the
 346     // call to opendir in order to eliminate a small window where the
 347     // symlink can be exploited.
 348     //
 349     if (!is_directory_secure(usrdir_name)) {
 350       FREE_C_HEAP_ARRAY(char, usrdir_name);
 351       os::closedir(subdirp);
 352       continue;
 353     }
 354 
 355     struct dirent* udentry;
 356     char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
 357     errno = 0;
 358     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 359 
 360       if (filename_to_pid(udentry->d_name) == vmid) {
 361         struct stat statbuf;
 362 
 363         char* filename = NEW_C_HEAP_ARRAY(char,
 364            strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 365 
 366         strcpy(filename, usrdir_name);
 367         strcat(filename, "\\");
 368         strcat(filename, udentry->d_name);
 369 
 370         if (::stat(filename, &statbuf) == OS_ERR) {
 371            FREE_C_HEAP_ARRAY(char, filename);
 372            continue;
 373         }
 374 
 375         // skip over files that are not regular files.
 376         if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
 377           FREE_C_HEAP_ARRAY(char, filename);
 378           continue;


 390         // In this function, all we're trying to do is determine the
 391         // name of the user that owns the process associated with vmid
 392         // so the size doesn't matter. Very rarely, we have observed
 393         // hsperfdata files where (st_size == 0) and the st_size field
 394         // later becomes the expected value.
 395         //
 396         if (statbuf.st_ctime > latest_ctime) {
 397           char* user = strchr(dentry->d_name, '_') + 1;
 398 
 399           if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
 400           latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 401 
 402           strcpy(latest_user, user);
 403           latest_ctime = statbuf.st_ctime;
 404         }
 405 
 406         FREE_C_HEAP_ARRAY(char, filename);
 407       }
 408     }
 409     os::closedir(subdirp);
 410     FREE_C_HEAP_ARRAY(char, udbuf);
 411     FREE_C_HEAP_ARRAY(char, usrdir_name);
 412   }
 413   os::closedir(tmpdirp);
 414   FREE_C_HEAP_ARRAY(char, tdbuf);
 415 
 416   return(latest_user);
 417 }
 418 
 419 // return the name of the user that owns the process identified by vmid.
 420 //
 421 // note: this method should only be used via the Perf native methods.
 422 // There are various costs to this method and limiting its use to the
 423 // Perf native methods limits the impact to monitoring applications only.
 424 //
 425 static char* get_user_name(int vmid) {
 426 
 427   // A fast implementation is not provided at this time. It's possible
 428   // to provide a fast process id to user name mapping function using
 429   // the win32 apis, but the default ACL for the process object only
 430   // allows processes with the same owner SID to acquire the process
 431   // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
 432   // to have the JVM change the ACL for the process object to allow arbitrary
 433   // users to access the process handle and the process security token.
 434   // The security ramifications need to be studied before providing this


 625   if (dirp == NULL) {
 626     // directory doesn't exist, so there is nothing to cleanup
 627     return;
 628   }
 629 
 630   if (!is_directory_secure(dirname)) {
 631     // the directory is not secure, don't attempt any cleanup
 632     os::closedir(dirp);
 633     return;
 634   }
 635 
 636   // for each entry in the directory that matches the expected file
 637   // name pattern, determine if the file resources are stale and if
 638   // so, remove the file resources. Note, instrumented HotSpot processes
 639   // for this user may start and/or terminate during this search and
 640   // remove or create new files in this directory. The behavior of this
 641   // loop under these conditions is dependent upon the implementation of
 642   // opendir/readdir.
 643   //
 644   struct dirent* entry;
 645   char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
 646   errno = 0;
 647   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 648 
 649     int pid = filename_to_pid(entry->d_name);
 650 
 651     if (pid == 0) {
 652 
 653       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 654 
 655         // attempt to remove all unexpected files, except "." and ".."
 656         remove_file(dirname, entry->d_name);
 657       }
 658 
 659       errno = 0;
 660       continue;
 661     }
 662 
 663     // we now have a file name that converts to a valid integer
 664     // that could represent a process id . if this process id
 665     // matches the current process id or the process is not running,
 666     // then remove the stale file resources.
 667     //
 668     // process liveness is detected by checking the exit status
 669     // of the process. if the process id is valid and the exit status
 670     // indicates that it is still running, the file file resources
 671     // are not removed. If the process id is invalid, or if we don't
 672     // have permissions to check the process status, or if the process
 673     // id is valid and the process has terminated, the the file resources
 674     // are assumed to be stale and are removed.
 675     //
 676     if (pid == os::current_process_id() || !is_alive(pid)) {
 677 
 678       // we can only remove the file resources. Any mapped views
 679       // of the file can only be unmapped by the processes that
 680       // opened those views and the file mapping object will not
 681       // get removed until all views are unmapped.
 682       //
 683       remove_file(dirname, entry->d_name);
 684     }
 685     errno = 0;
 686   }
 687   os::closedir(dirp);
 688   FREE_C_HEAP_ARRAY(char, dbuf);
 689 }
 690 
 691 // create a file mapping object with the requested name, and size
 692 // from the file represented by the given Handle object
 693 //
 694 static HANDLE create_file_mapping(const char* name, HANDLE fh, LPSECURITY_ATTRIBUTES fsa, size_t size) {
 695 
 696   DWORD lowSize = (DWORD)size;
 697   DWORD highSize = 0;
 698   HANDLE fmh = NULL;
 699 
 700   // Create a file mapping object with the given name. This function
 701   // will grow the file to the specified size.
 702   //
 703   fmh = CreateFileMapping(
 704                fh,                 /* HANDLE file handle for backing store */
 705                fsa,                /* LPSECURITY_ATTRIBUTES Not inheritable */
 706                PAGE_READWRITE,     /* DWORD protections */
 707                highSize,           /* DWORD High word of max size */
 708                lowSize,            /* DWORD Low word of max size */




 301 static char* get_user_name_slow(int vmid) {
 302 
 303   // directory search
 304   char* latest_user = NULL;
 305   time_t latest_ctime = 0;
 306 
 307   const char* tmpdirname = os::get_temp_directory();
 308 
 309   DIR* tmpdirp = os::opendir(tmpdirname);
 310 
 311   if (tmpdirp == NULL) {
 312     return NULL;
 313   }
 314 
 315   // for each entry in the directory that matches the pattern hsperfdata_*,
 316   // open the directory and check if the file for the given vmid exists.
 317   // The file with the expected name and the latest creation date is used
 318   // to determine the user name for the process id.
 319   //
 320   struct dirent* dentry;

 321   errno = 0;
 322   while ((dentry = os::readdir(tmpdirp)) != NULL) {
 323 
 324     // check if the directory entry is a hsperfdata file
 325     if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
 326       continue;
 327     }
 328 
 329     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
 330         strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
 331     strcpy(usrdir_name, tmpdirname);
 332     strcat(usrdir_name, "\\");
 333     strcat(usrdir_name, dentry->d_name);
 334 
 335     DIR* subdirp = os::opendir(usrdir_name);
 336 
 337     if (subdirp == NULL) {
 338       FREE_C_HEAP_ARRAY(char, usrdir_name);
 339       continue;
 340     }
 341 
 342     // Since we don't create the backing store files in directories
 343     // pointed to by symbolic links, we also don't follow them when
 344     // looking for the files. We check for a symbolic link after the
 345     // call to opendir in order to eliminate a small window where the
 346     // symlink can be exploited.
 347     //
 348     if (!is_directory_secure(usrdir_name)) {
 349       FREE_C_HEAP_ARRAY(char, usrdir_name);
 350       os::closedir(subdirp);
 351       continue;
 352     }
 353 
 354     struct dirent* udentry;

 355     errno = 0;
 356     while ((udentry = os::readdir(subdirp)) != NULL) {
 357 
 358       if (filename_to_pid(udentry->d_name) == vmid) {
 359         struct stat statbuf;
 360 
 361         char* filename = NEW_C_HEAP_ARRAY(char,
 362            strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 363 
 364         strcpy(filename, usrdir_name);
 365         strcat(filename, "\\");
 366         strcat(filename, udentry->d_name);
 367 
 368         if (::stat(filename, &statbuf) == OS_ERR) {
 369            FREE_C_HEAP_ARRAY(char, filename);
 370            continue;
 371         }
 372 
 373         // skip over files that are not regular files.
 374         if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
 375           FREE_C_HEAP_ARRAY(char, filename);
 376           continue;


 388         // In this function, all we're trying to do is determine the
 389         // name of the user that owns the process associated with vmid
 390         // so the size doesn't matter. Very rarely, we have observed
 391         // hsperfdata files where (st_size == 0) and the st_size field
 392         // later becomes the expected value.
 393         //
 394         if (statbuf.st_ctime > latest_ctime) {
 395           char* user = strchr(dentry->d_name, '_') + 1;
 396 
 397           if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
 398           latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 399 
 400           strcpy(latest_user, user);
 401           latest_ctime = statbuf.st_ctime;
 402         }
 403 
 404         FREE_C_HEAP_ARRAY(char, filename);
 405       }
 406     }
 407     os::closedir(subdirp);

 408     FREE_C_HEAP_ARRAY(char, usrdir_name);
 409   }
 410   os::closedir(tmpdirp);

 411 
 412   return(latest_user);
 413 }
 414 
 415 // return the name of the user that owns the process identified by vmid.
 416 //
 417 // note: this method should only be used via the Perf native methods.
 418 // There are various costs to this method and limiting its use to the
 419 // Perf native methods limits the impact to monitoring applications only.
 420 //
 421 static char* get_user_name(int vmid) {
 422 
 423   // A fast implementation is not provided at this time. It's possible
 424   // to provide a fast process id to user name mapping function using
 425   // the win32 apis, but the default ACL for the process object only
 426   // allows processes with the same owner SID to acquire the process
 427   // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
 428   // to have the JVM change the ACL for the process object to allow arbitrary
 429   // users to access the process handle and the process security token.
 430   // The security ramifications need to be studied before providing this


 621   if (dirp == NULL) {
 622     // directory doesn't exist, so there is nothing to cleanup
 623     return;
 624   }
 625 
 626   if (!is_directory_secure(dirname)) {
 627     // the directory is not secure, don't attempt any cleanup
 628     os::closedir(dirp);
 629     return;
 630   }
 631 
 632   // for each entry in the directory that matches the expected file
 633   // name pattern, determine if the file resources are stale and if
 634   // so, remove the file resources. Note, instrumented HotSpot processes
 635   // for this user may start and/or terminate during this search and
 636   // remove or create new files in this directory. The behavior of this
 637   // loop under these conditions is dependent upon the implementation of
 638   // opendir/readdir.
 639   //
 640   struct dirent* entry;

 641   errno = 0;
 642   while ((entry = os::readdir(dirp)) != NULL) {
 643 
 644     int pid = filename_to_pid(entry->d_name);
 645 
 646     if (pid == 0) {
 647 
 648       if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
 649 
 650         // attempt to remove all unexpected files, except "." and ".."
 651         remove_file(dirname, entry->d_name);
 652       }
 653 
 654       errno = 0;
 655       continue;
 656     }
 657 
 658     // we now have a file name that converts to a valid integer
 659     // that could represent a process id . if this process id
 660     // matches the current process id or the process is not running,
 661     // then remove the stale file resources.
 662     //
 663     // process liveness is detected by checking the exit status
 664     // of the process. if the process id is valid and the exit status
 665     // indicates that it is still running, the file file resources
 666     // are not removed. If the process id is invalid, or if we don't
 667     // have permissions to check the process status, or if the process
 668     // id is valid and the process has terminated, the the file resources
 669     // are assumed to be stale and are removed.
 670     //
 671     if (pid == os::current_process_id() || !is_alive(pid)) {
 672 
 673       // we can only remove the file resources. Any mapped views
 674       // of the file can only be unmapped by the processes that
 675       // opened those views and the file mapping object will not
 676       // get removed until all views are unmapped.
 677       //
 678       remove_file(dirname, entry->d_name);
 679     }
 680     errno = 0;
 681   }
 682   os::closedir(dirp);

 683 }
 684 
 685 // create a file mapping object with the requested name, and size
 686 // from the file represented by the given Handle object
 687 //
 688 static HANDLE create_file_mapping(const char* name, HANDLE fh, LPSECURITY_ATTRIBUTES fsa, size_t size) {
 689 
 690   DWORD lowSize = (DWORD)size;
 691   DWORD highSize = 0;
 692   HANDLE fmh = NULL;
 693 
 694   // Create a file mapping object with the given name. This function
 695   // will grow the file to the specified size.
 696   //
 697   fmh = CreateFileMapping(
 698                fh,                 /* HANDLE file handle for backing store */
 699                fsa,                /* LPSECURITY_ATTRIBUTES Not inheritable */
 700                PAGE_READWRITE,     /* DWORD protections */
 701                highSize,           /* DWORD High word of max size */
 702                lowSize,            /* DWORD Low word of max size */


< prev index next >