1/* Copyright libuv project contributors. All rights reserved. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 */ 21 22#include "uv.h" 23#include "internal.h" 24#include <sys/ioctl.h> 25#include <net/if.h> 26#include <utmpx.h> 27#include <unistd.h> 28#include <sys/ps.h> 29#include <builtins.h> 30#include <termios.h> 31#include <sys/msg.h> 32#include <sys/resource.h> 33#include "zos-base.h" 34#include "zos-sys-info.h" 35#if defined(__clang__) 36#include "csrsic.h" 37#else 38#include "//'SYS1.SAMPLIB(CSRSIC)'" 39#endif 40 41#define CVT_PTR 0x10 42#define PSA_PTR 0x00 43#define CSD_OFFSET 0x294 44 45/* 46 Long-term average CPU service used by this logical partition, 47 in millions of service units per hour. If this value is above 48 the partition's defined capacity, the partition will be capped. 49 It is calculated using the physical CPU adjustment factor 50 (RCTPCPUA) so it may not match other measures of service which 51 are based on the logical CPU adjustment factor. It is available 52 if the hardware supports LPAR cluster. 53*/ 54#define RCTLACS_OFFSET 0xC4 55 56/* 32-bit count of alive CPUs. This includes both CPs and IFAs */ 57#define CSD_NUMBER_ONLINE_CPUS 0xD4 58 59/* Address of system resources manager (SRM) control table */ 60#define CVTOPCTP_OFFSET 0x25C 61 62/* Address of the RCT table */ 63#define RMCTRCT_OFFSET 0xE4 64 65/* Address of the rsm control and enumeration area. */ 66#define CVTRCEP_OFFSET 0x490 67 68/* Total number of frames currently on all available frame queues. */ 69#define RCEAFC_OFFSET 0x088 70 71/* Pointer to the home (current) ASCB. */ 72#define PSAAOLD 0x224 73 74/* Pointer to rsm address space block extension. */ 75#define ASCBRSME 0x16C 76 77/* 78 NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE. 79 It does not include 2G frames. 80*/ 81#define RAXFMCT 0x2C 82 83/* Thread Entry constants */ 84#define PGTH_CURRENT 1 85#define PGTH_LEN 26 86#define PGTHAPATH 0x20 87#pragma linkage(BPX4GTH, OS) 88#pragma linkage(BPX1GTH, OS) 89 90/* TOD Clock resolution in nanoseconds */ 91#define TOD_RES 4.096 92 93typedef unsigned data_area_ptr_assign_type; 94 95typedef union { 96 struct { 97#if defined(_LP64) 98 data_area_ptr_assign_type lower; 99#endif 100 data_area_ptr_assign_type assign; 101 }; 102 char* deref; 103} data_area_ptr; 104 105 106void uv_loadavg(double avg[3]) { 107 /* TODO: implement the following */ 108 avg[0] = 0; 109 avg[1] = 0; 110 avg[2] = 0; 111} 112 113 114int uv__platform_loop_init(uv_loop_t* loop) { 115 uv__os390_epoll* ep; 116 117 ep = epoll_create1(0); 118 loop->ep = ep; 119 if (ep == NULL) 120 return UV__ERR(errno); 121 122 return 0; 123} 124 125 126void uv__platform_loop_delete(uv_loop_t* loop) { 127 if (loop->ep != NULL) { 128 epoll_queue_close(loop->ep); 129 loop->ep = NULL; 130 } 131} 132 133 134uint64_t uv__hrtime(uv_clocktype_t type) { 135 unsigned long long timestamp; 136 __stckf(×tamp); 137 /* Convert to nanoseconds */ 138 return timestamp / TOD_RES; 139} 140 141 142static int getexe(char* buf, size_t len) { 143 return uv__strscpy(buf, __getargv()[0], len); 144} 145 146 147/* 148 * We could use a static buffer for the path manipulations that we need outside 149 * of the function, but this function could be called by multiple consumers and 150 * we don't want to potentially create a race condition in the use of snprintf. 151 * There is no direct way of getting the exe path in zOS - either through /procfs 152 * or through some libc APIs. The below approach is to parse the argv[0]'s pattern 153 * and use it in conjunction with PATH environment variable to craft one. 154 */ 155int uv_exepath(char* buffer, size_t* size) { 156 int res; 157 char args[PATH_MAX]; 158 int pid; 159 160 if (buffer == NULL || size == NULL || *size == 0) 161 return UV_EINVAL; 162 163 res = getexe(args, sizeof(args)); 164 if (res < 0) 165 return UV_EINVAL; 166 167 return uv__search_path(args, buffer, size); 168} 169 170 171uint64_t uv_get_free_memory(void) { 172 uint64_t freeram; 173 174 data_area_ptr cvt = {0}; 175 data_area_ptr rcep = {0}; 176 cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR); 177 rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET); 178 freeram = (uint64_t)*((uint32_t*)(rcep.deref + RCEAFC_OFFSET)) * 4096; 179 return freeram; 180} 181 182 183uint64_t uv_get_total_memory(void) { 184 /* Use CVTRLSTG to get the size of actual real storage online at IPL in K. */ 185 return (uint64_t)((int)((char *__ptr32 *__ptr32 *)0)[4][214]) * 1024; 186} 187 188 189uint64_t uv_get_constrained_memory(void) { 190 struct rlimit rl; 191 192 /* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */ 193 if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0) 194 return rl.rlim_cur * 1024 * 1024; 195 196 return 0; /* There is no memory limit set. */ 197} 198 199 200uint64_t uv_get_available_memory(void) { 201 return uv_get_free_memory(); 202} 203 204 205int uv_resident_set_memory(size_t* rss) { 206 char* ascb; 207 char* rax; 208 size_t nframes; 209 210 ascb = *(char* __ptr32 *)(PSA_PTR + PSAAOLD); 211 rax = *(char* __ptr32 *)(ascb + ASCBRSME); 212 nframes = *(unsigned int*)(rax + RAXFMCT); 213 214 *rss = nframes * sysconf(_SC_PAGESIZE); 215 return 0; 216} 217 218 219int uv_uptime(double* uptime) { 220 struct utmpx u ; 221 struct utmpx *v; 222 time64_t t; 223 224 u.ut_type = BOOT_TIME; 225 v = getutxid(&u); 226 if (v == NULL) 227 return -1; 228 *uptime = difftime64(time64(&t), v->ut_tv.tv_sec); 229 return 0; 230} 231 232 233int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 234 uv_cpu_info_t* cpu_info; 235 int idx; 236 siv1v2 info; 237 data_area_ptr cvt = {0}; 238 data_area_ptr csd = {0}; 239 data_area_ptr rmctrct = {0}; 240 data_area_ptr cvtopctp = {0}; 241 int cpu_usage_avg; 242 243 cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR); 244 245 csd.assign = *((data_area_ptr_assign_type *) (cvt.deref + CSD_OFFSET)); 246 cvtopctp.assign = *((data_area_ptr_assign_type *) (cvt.deref + CVTOPCTP_OFFSET)); 247 rmctrct.assign = *((data_area_ptr_assign_type *) (cvtopctp.deref + RMCTRCT_OFFSET)); 248 249 *count = *((int*) (csd.deref + CSD_NUMBER_ONLINE_CPUS)); 250 cpu_usage_avg = *((unsigned short int*) (rmctrct.deref + RCTLACS_OFFSET)); 251 252 *cpu_infos = uv__malloc(*count * sizeof(uv_cpu_info_t)); 253 if (!*cpu_infos) 254 return UV_ENOMEM; 255 256 cpu_info = *cpu_infos; 257 idx = 0; 258 while (idx < *count) { 259 cpu_info->speed = *(int*)(info.siv1v2si22v1.si22v1cpucapability); 260 cpu_info->model = uv__malloc(ZOSCPU_MODEL_LENGTH + 1); 261 if (cpu_info->model == NULL) { 262 uv_free_cpu_info(*cpu_infos, idx); 263 return UV_ENOMEM; 264 } 265 __get_cpu_model(cpu_info->model, ZOSCPU_MODEL_LENGTH + 1); 266 cpu_info->cpu_times.user = cpu_usage_avg; 267 /* TODO: implement the following */ 268 cpu_info->cpu_times.sys = 0; 269 cpu_info->cpu_times.idle = 0; 270 cpu_info->cpu_times.irq = 0; 271 cpu_info->cpu_times.nice = 0; 272 ++cpu_info; 273 ++idx; 274 } 275 276 return 0; 277} 278 279 280static int uv__interface_addresses_v6(uv_interface_address_t** addresses, 281 int* count) { 282 uv_interface_address_t* address; 283 int sockfd; 284 int maxsize; 285 __net_ifconf6header_t ifc; 286 __net_ifconf6entry_t* ifr; 287 __net_ifconf6entry_t* p; 288 unsigned int i; 289 int count_names; 290 unsigned char netmask[16] = {0}; 291 292 *count = 0; 293 /* Assume maximum buffer size allowable */ 294 maxsize = 16384; 295 296 if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) 297 return UV__ERR(errno); 298 299 ifc.__nif6h_buffer = uv__calloc(1, maxsize); 300 301 if (ifc.__nif6h_buffer == NULL) { 302 uv__close(sockfd); 303 return UV_ENOMEM; 304 } 305 306 ifc.__nif6h_version = 1; 307 ifc.__nif6h_buflen = maxsize; 308 309 if (ioctl(sockfd, SIOCGIFCONF6, &ifc) == -1) { 310 /* This will error on a system that does not support IPv6. However, we want 311 * to treat this as there being 0 interfaces so we can continue to get IPv4 312 * interfaces in uv_interface_addresses(). So return 0 instead of the error. 313 */ 314 uv__free(ifc.__nif6h_buffer); 315 uv__close(sockfd); 316 errno = 0; 317 return 0; 318 } 319 320 ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer); 321 while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) { 322 p = ifr; 323 ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen); 324 325 if (!(p->__nif6e_addr.sin6_family == AF_INET6)) 326 continue; 327 328 if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE)) 329 continue; 330 331 ++(*count); 332 } 333 334 if ((*count) == 0) { 335 uv__free(ifc.__nif6h_buffer); 336 uv__close(sockfd); 337 return 0; 338 } 339 340 /* Alloc the return interface structs */ 341 *addresses = uv__calloc(1, *count * sizeof(uv_interface_address_t)); 342 if (!(*addresses)) { 343 uv__free(ifc.__nif6h_buffer); 344 uv__close(sockfd); 345 return UV_ENOMEM; 346 } 347 address = *addresses; 348 349 count_names = 0; 350 ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer); 351 while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) { 352 p = ifr; 353 ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen); 354 355 if (!(p->__nif6e_addr.sin6_family == AF_INET6)) 356 continue; 357 358 if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE)) 359 continue; 360 361 /* All conditions above must match count loop */ 362 363 i = 0; 364 /* Ignore EBCDIC space (0x40) padding in name */ 365 while (i < ARRAY_SIZE(p->__nif6e_name) && 366 p->__nif6e_name[i] != 0x40 && 367 p->__nif6e_name[i] != 0) 368 ++i; 369 address->name = uv__malloc(i + 1); 370 if (address->name == NULL) { 371 uv_free_interface_addresses(*addresses, count_names); 372 uv__free(ifc.__nif6h_buffer); 373 uv__close(sockfd); 374 return UV_ENOMEM; 375 } 376 memcpy(address->name, p->__nif6e_name, i); 377 address->name[i] = '\0'; 378 __e2a_s(address->name); 379 count_names++; 380 381 address->address.address6 = *((struct sockaddr_in6*) &p->__nif6e_addr); 382 383 for (i = 0; i < (p->__nif6e_prefixlen / 8); i++) 384 netmask[i] = 0xFF; 385 386 if (p->__nif6e_prefixlen % 8) 387 netmask[i] = 0xFF << (8 - (p->__nif6e_prefixlen % 8)); 388 389 address->netmask.netmask6.sin6_len = p->__nif6e_prefixlen; 390 memcpy(&(address->netmask.netmask6.sin6_addr), netmask, 16); 391 address->netmask.netmask6.sin6_family = AF_INET6; 392 393 address->is_internal = p->__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0; 394 address++; 395 } 396 397 uv__free(ifc.__nif6h_buffer); 398 uv__close(sockfd); 399 return 0; 400} 401 402 403int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { 404 uv_interface_address_t* address; 405 int sockfd; 406 int maxsize; 407 struct ifconf ifc; 408 struct ifreq flg; 409 struct ifreq* ifr; 410 struct ifreq* p; 411 uv_interface_address_t* addresses_v6; 412 int count_v6; 413 unsigned int i; 414 int rc; 415 int count_names; 416 417 *count = 0; 418 *addresses = NULL; 419 420 /* get the ipv6 addresses first */ 421 if ((rc = uv__interface_addresses_v6(&addresses_v6, &count_v6)) != 0) 422 return rc; 423 424 /* now get the ipv4 addresses */ 425 426 /* Assume maximum buffer size allowable */ 427 maxsize = 16384; 428 429 sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 430 if (0 > sockfd) { 431 if (count_v6) 432 uv_free_interface_addresses(addresses_v6, count_v6); 433 return UV__ERR(errno); 434 } 435 436 ifc.ifc_req = uv__calloc(1, maxsize); 437 438 if (ifc.ifc_req == NULL) { 439 if (count_v6) 440 uv_free_interface_addresses(addresses_v6, count_v6); 441 uv__close(sockfd); 442 return UV_ENOMEM; 443 } 444 445 ifc.ifc_len = maxsize; 446 447 if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { 448 if (count_v6) 449 uv_free_interface_addresses(addresses_v6, count_v6); 450 uv__free(ifc.ifc_req); 451 uv__close(sockfd); 452 return UV__ERR(errno); 453 } 454 455#define MAX(a,b) (((a)>(b))?(a):(b)) 456#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) 457 458 /* Count all up and running ipv4/ipv6 addresses */ 459 ifr = ifc.ifc_req; 460 while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { 461 p = ifr; 462 ifr = (struct ifreq*) 463 ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); 464 465 if (!(p->ifr_addr.sa_family == AF_INET6 || 466 p->ifr_addr.sa_family == AF_INET)) 467 continue; 468 469 memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); 470 if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { 471 if (count_v6) 472 uv_free_interface_addresses(addresses_v6, count_v6); 473 uv__free(ifc.ifc_req); 474 uv__close(sockfd); 475 return UV__ERR(errno); 476 } 477 478 if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) 479 continue; 480 481 (*count)++; 482 } 483 484 if (*count == 0 && count_v6 == 0) { 485 uv__free(ifc.ifc_req); 486 uv__close(sockfd); 487 return 0; 488 } 489 490 /* Alloc the return interface structs */ 491 *addresses = uv__calloc(1, (*count + count_v6) * 492 sizeof(uv_interface_address_t)); 493 494 if (!(*addresses)) { 495 if (count_v6) 496 uv_free_interface_addresses(addresses_v6, count_v6); 497 uv__free(ifc.ifc_req); 498 uv__close(sockfd); 499 return UV_ENOMEM; 500 } 501 address = *addresses; 502 503 /* copy over the ipv6 addresses if any are found */ 504 if (count_v6) { 505 memcpy(address, addresses_v6, count_v6 * sizeof(uv_interface_address_t)); 506 address += count_v6; 507 *count += count_v6; 508 /* free ipv6 addresses, but keep address names */ 509 uv__free(addresses_v6); 510 } 511 512 count_names = *count; 513 ifr = ifc.ifc_req; 514 while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { 515 p = ifr; 516 ifr = (struct ifreq*) 517 ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); 518 519 if (!(p->ifr_addr.sa_family == AF_INET6 || 520 p->ifr_addr.sa_family == AF_INET)) 521 continue; 522 523 memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); 524 if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { 525 uv_free_interface_addresses(*addresses, count_names); 526 uv__free(ifc.ifc_req); 527 uv__close(sockfd); 528 return UV_ENOSYS; 529 } 530 531 if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) 532 continue; 533 534 /* All conditions above must match count loop */ 535 536 i = 0; 537 /* Ignore EBCDIC space (0x40) padding in name */ 538 while (i < ARRAY_SIZE(p->ifr_name) && 539 p->ifr_name[i] != 0x40 && 540 p->ifr_name[i] != 0) 541 ++i; 542 address->name = uv__malloc(i + 1); 543 if (address->name == NULL) { 544 uv_free_interface_addresses(*addresses, count_names); 545 uv__free(ifc.ifc_req); 546 uv__close(sockfd); 547 return UV_ENOMEM; 548 } 549 memcpy(address->name, p->ifr_name, i); 550 address->name[i] = '\0'; 551 __e2a_s(address->name); 552 count_names++; 553 554 address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); 555 556 if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) { 557 uv_free_interface_addresses(*addresses, count_names); 558 uv__free(ifc.ifc_req); 559 uv__close(sockfd); 560 return UV__ERR(errno); 561 } 562 563 address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr); 564 address->netmask.netmask4.sin_family = AF_INET; 565 address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; 566 address++; 567 } 568 569#undef ADDR_SIZE 570#undef MAX 571 572 uv__free(ifc.ifc_req); 573 uv__close(sockfd); 574 return 0; 575} 576 577 578void uv_free_interface_addresses(uv_interface_address_t* addresses, 579 int count) { 580 int i; 581 for (i = 0; i < count; ++i) 582 uv__free(addresses[i].name); 583 uv__free(addresses); 584} 585 586 587void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { 588 struct epoll_event* events; 589 struct epoll_event dummy; 590 uintptr_t i; 591 uintptr_t nfds; 592 593 assert(loop->watchers != NULL); 594 assert(fd >= 0); 595 596 events = (struct epoll_event*) loop->watchers[loop->nwatchers]; 597 nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; 598 if (events != NULL) 599 /* Invalidate events with same file descriptor */ 600 for (i = 0; i < nfds; i++) 601 if ((int) events[i].fd == fd) 602 events[i].fd = -1; 603 604 /* Remove the file descriptor from the epoll. */ 605 if (loop->ep != NULL) 606 epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, &dummy); 607} 608 609 610int uv__io_check_fd(uv_loop_t* loop, int fd) { 611 struct pollfd p[1]; 612 int rv; 613 614 p[0].fd = fd; 615 p[0].events = POLLIN; 616 617 do 618 rv = poll(p, 1, 0); 619 while (rv == -1 && errno == EINTR); 620 621 if (rv == -1) 622 abort(); 623 624 if (p[0].revents & POLLNVAL) 625 return -1; 626 627 return 0; 628} 629 630 631int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { 632 uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); 633 return 0; 634} 635 636 637static int os390_regfileint(uv_fs_event_t* handle, char* path) { 638 uv__os390_epoll* ep; 639 _RFIS reg_struct; 640 int rc; 641 642 ep = handle->loop->ep; 643 assert(ep->msg_queue != -1); 644 645 reg_struct.__rfis_cmd = _RFIS_REG; 646 reg_struct.__rfis_qid = ep->msg_queue; 647 reg_struct.__rfis_type = 1; 648 memcpy(reg_struct.__rfis_utok, &handle, sizeof(handle)); 649 650 rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), ®_struct); 651 if (rc != 0) 652 return UV__ERR(errno); 653 654 memcpy(handle->rfis_rftok, reg_struct.__rfis_rftok, 655 sizeof(handle->rfis_rftok)); 656 657 return 0; 658} 659 660 661int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, 662 const char* filename, unsigned int flags) { 663 char* path; 664 int rc; 665 666 if (uv__is_active(handle)) 667 return UV_EINVAL; 668 669 path = uv__strdup(filename); 670 if (path == NULL) 671 return UV_ENOMEM; 672 673 rc = os390_regfileint(handle, path); 674 if (rc != 0) { 675 uv__free(path); 676 return rc; 677 } 678 679 uv__handle_start(handle); 680 handle->path = path; 681 handle->cb = cb; 682 683 return 0; 684} 685 686 687int uv__fs_event_stop(uv_fs_event_t* handle) { 688 uv__os390_epoll* ep; 689 _RFIS reg_struct; 690 int rc; 691 692 if (!uv__is_active(handle)) 693 return 0; 694 695 ep = handle->loop->ep; 696 assert(ep->msg_queue != -1); 697 698 reg_struct.__rfis_cmd = _RFIS_UNREG; 699 reg_struct.__rfis_qid = ep->msg_queue; 700 reg_struct.__rfis_type = 1; 701 memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok, 702 sizeof(handle->rfis_rftok)); 703 704 /* 705 * This call will take "/" as the path argument in case we 706 * don't care to supply the correct path. The system will simply 707 * ignore it. 708 */ 709 rc = __w_pioctl("/", _IOCC_REGFILEINT, sizeof(reg_struct), ®_struct); 710 if (rc != 0 && errno != EALREADY && errno != ENOENT) 711 abort(); 712 713 if (handle->path != NULL) { 714 uv__free(handle->path); 715 handle->path = NULL; 716 } 717 718 if (rc != 0 && errno == EALREADY) 719 return -1; 720 721 uv__handle_stop(handle); 722 723 return 0; 724} 725 726 727int uv_fs_event_stop(uv_fs_event_t* handle) { 728 uv__fs_event_stop(handle); 729 return 0; 730} 731 732 733void uv__fs_event_close(uv_fs_event_t* handle) { 734 /* 735 * If we were unable to unregister file interest here, then it is most likely 736 * that there is a pending queued change notification. When this happens, we 737 * don't want to complete the close as it will free the underlying memory for 738 * the handle, causing a use-after-free problem when the event is processed. 739 * We defer the final cleanup until after the event is consumed in 740 * os390_message_queue_handler(). 741 */ 742 if (uv__fs_event_stop(handle) == 0) 743 uv__make_close_pending((uv_handle_t*) handle); 744} 745 746 747static int os390_message_queue_handler(uv__os390_epoll* ep) { 748 uv_fs_event_t* handle; 749 int msglen; 750 int events; 751 _RFIM msg; 752 753 if (ep->msg_queue == -1) 754 return 0; 755 756 msglen = msgrcv(ep->msg_queue, &msg, sizeof(msg), 0, IPC_NOWAIT); 757 758 if (msglen == -1 && errno == ENOMSG) 759 return 0; 760 761 if (msglen == -1) 762 abort(); 763 764 events = 0; 765 if (msg.__rfim_event == _RFIM_ATTR || msg.__rfim_event == _RFIM_WRITE) 766 events = UV_CHANGE; 767 else if (msg.__rfim_event == _RFIM_RENAME || msg.__rfim_event == _RFIM_UNLINK) 768 events = UV_RENAME; 769 else if (msg.__rfim_event == 156) 770 /* TODO(gabylb): zos - this event should not happen, need to investigate. 771 * 772 * This event seems to occur when the watched file is [re]moved, or an 773 * editor (like vim) renames then creates the file on save (for vim, that's 774 * when backupcopy=no|auto). 775 */ 776 events = UV_RENAME; 777 else 778 /* Some event that we are not interested in. */ 779 return 0; 780 781 /* `__rfim_utok` is treated as text when it should be treated as binary while 782 * running in ASCII mode, resulting in an unwanted autoconversion. 783 */ 784 __a2e_l(msg.__rfim_utok, sizeof(msg.__rfim_utok)); 785 handle = *(uv_fs_event_t**)(msg.__rfim_utok); 786 assert(handle != NULL); 787 788 assert((handle->flags & UV_HANDLE_CLOSED) == 0); 789 if (uv__is_closing(handle)) { 790 uv__handle_stop(handle); 791 uv__make_close_pending((uv_handle_t*) handle); 792 return 0; 793 } else if (handle->path == NULL) { 794 /* _RFIS_UNREG returned EALREADY. */ 795 uv__handle_stop(handle); 796 return 0; 797 } 798 799 /* The file is implicitly unregistered when the change notification is 800 * sent, only one notification is sent per registration. So we need to 801 * re-register interest in a file after each change notification we 802 * receive. 803 */ 804 assert(handle->path != NULL); 805 os390_regfileint(handle, handle->path); 806 handle->cb(handle, uv__basename_r(handle->path), events, 0); 807 return 1; 808} 809 810 811void uv__io_poll(uv_loop_t* loop, int timeout) { 812 static const int max_safe_timeout = 1789569; 813 uv__loop_internal_fields_t* lfields; 814 struct epoll_event events[1024]; 815 struct epoll_event* pe; 816 struct epoll_event e; 817 uv__os390_epoll* ep; 818 int have_signals; 819 int real_timeout; 820 struct uv__queue* q; 821 uv__io_t* w; 822 uint64_t base; 823 int count; 824 int nfds; 825 int fd; 826 int op; 827 int i; 828 int user_timeout; 829 int reset_timeout; 830 831 if (loop->nfds == 0) { 832 assert(uv__queue_empty(&loop->watcher_queue)); 833 return; 834 } 835 836 lfields = uv__get_internal_fields(loop); 837 838 while (!uv__queue_empty(&loop->watcher_queue)) { 839 uv_stream_t* stream; 840 841 q = uv__queue_head(&loop->watcher_queue); 842 uv__queue_remove(q); 843 uv__queue_init(q); 844 w = uv__queue_data(q, uv__io_t, watcher_queue); 845 846 assert(w->pevents != 0); 847 assert(w->fd >= 0); 848 849 stream= container_of(w, uv_stream_t, io_watcher); 850 851 assert(w->fd < (int) loop->nwatchers); 852 853 e.events = w->pevents; 854 e.fd = w->fd; 855 856 if (w->events == 0) 857 op = EPOLL_CTL_ADD; 858 else 859 op = EPOLL_CTL_MOD; 860 861 /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching 862 * events, skip the syscall and squelch the events after epoll_wait(). 863 */ 864 if (epoll_ctl(loop->ep, op, w->fd, &e)) { 865 if (errno != EEXIST) 866 abort(); 867 868 assert(op == EPOLL_CTL_ADD); 869 870 /* We've reactivated a file descriptor that's been watched before. */ 871 if (epoll_ctl(loop->ep, EPOLL_CTL_MOD, w->fd, &e)) 872 abort(); 873 } 874 875 w->events = w->pevents; 876 } 877 878 assert(timeout >= -1); 879 base = loop->time; 880 count = 48; /* Benchmarks suggest this gives the best throughput. */ 881 real_timeout = timeout; 882 int nevents = 0; 883 have_signals = 0; 884 885 if (lfields->flags & UV_METRICS_IDLE_TIME) { 886 reset_timeout = 1; 887 user_timeout = timeout; 888 timeout = 0; 889 } else { 890 reset_timeout = 0; 891 } 892 893 nfds = 0; 894 for (;;) { 895 /* Only need to set the provider_entry_time if timeout != 0. The function 896 * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. 897 */ 898 if (timeout != 0) 899 uv__metrics_set_provider_entry_time(loop); 900 901 if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) 902 timeout = max_safe_timeout; 903 904 /* Store the current timeout in a location that's globally accessible so 905 * other locations like uv__work_done() can determine whether the queue 906 * of events in the callback were waiting when poll was called. 907 */ 908 lfields->current_timeout = timeout; 909 910 nfds = epoll_wait(loop->ep, events, 911 ARRAY_SIZE(events), timeout); 912 913 /* Update loop->time unconditionally. It's tempting to skip the update when 914 * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the 915 * operating system didn't reschedule our process while in the syscall. 916 */ 917 base = loop->time; 918 SAVE_ERRNO(uv__update_time(loop)); 919 if (nfds == 0) { 920 assert(timeout != -1); 921 922 if (reset_timeout != 0) { 923 timeout = user_timeout; 924 reset_timeout = 0; 925 } 926 927 if (timeout == -1) 928 continue; 929 930 if (timeout == 0) 931 return; 932 933 /* We may have been inside the system call for longer than |timeout| 934 * milliseconds so we need to update the timestamp to avoid drift. 935 */ 936 goto update_timeout; 937 } 938 939 if (nfds == -1) { 940 941 if (errno != EINTR) 942 abort(); 943 944 if (reset_timeout != 0) { 945 timeout = user_timeout; 946 reset_timeout = 0; 947 } 948 949 if (timeout == -1) 950 continue; 951 952 if (timeout == 0) 953 return; 954 955 /* Interrupted by a signal. Update timeout and poll again. */ 956 goto update_timeout; 957 } 958 959 960 assert(loop->watchers != NULL); 961 loop->watchers[loop->nwatchers] = (void*) events; 962 loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; 963 for (i = 0; i < nfds; i++) { 964 pe = events + i; 965 fd = pe->fd; 966 967 /* Skip invalidated events, see uv__platform_invalidate_fd */ 968 if (fd == -1) 969 continue; 970 971 ep = loop->ep; 972 if (pe->is_msg) { 973 os390_message_queue_handler(ep); 974 nevents++; 975 continue; 976 } 977 978 assert(fd >= 0); 979 assert((unsigned) fd < loop->nwatchers); 980 981 w = loop->watchers[fd]; 982 983 if (w == NULL) { 984 /* File descriptor that we've stopped watching, disarm it. 985 * 986 * Ignore all errors because we may be racing with another thread 987 * when the file descriptor is closed. 988 */ 989 epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, pe); 990 continue; 991 } 992 993 /* Give users only events they're interested in. Prevents spurious 994 * callbacks when previous callback invocation in this loop has stopped 995 * the current watcher. Also, filters out events that users has not 996 * requested us to watch. 997 */ 998 pe->events &= w->pevents | POLLERR | POLLHUP; 999 1000 if (pe->events == POLLERR || pe->events == POLLHUP) 1001 pe->events |= w->pevents & (POLLIN | POLLOUT); 1002 1003 if (pe->events != 0) { 1004 /* Run signal watchers last. This also affects child process watchers 1005 * because those are implemented in terms of signal watchers. 1006 */ 1007 if (w == &loop->signal_io_watcher) { 1008 have_signals = 1; 1009 } else { 1010 uv__metrics_update_idle_time(loop); 1011 w->cb(loop, w, pe->events); 1012 } 1013 nevents++; 1014 } 1015 } 1016 1017 uv__metrics_inc_events(loop, nevents); 1018 if (reset_timeout != 0) { 1019 timeout = user_timeout; 1020 reset_timeout = 0; 1021 uv__metrics_inc_events_waiting(loop, nevents); 1022 } 1023 1024 if (have_signals != 0) { 1025 uv__metrics_update_idle_time(loop); 1026 loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); 1027 } 1028 1029 loop->watchers[loop->nwatchers] = NULL; 1030 loop->watchers[loop->nwatchers + 1] = NULL; 1031 1032 if (have_signals != 0) 1033 return; /* Event loop should cycle now so don't poll again. */ 1034 1035 if (nevents != 0) { 1036 if (nfds == ARRAY_SIZE(events) && --count != 0) { 1037 /* Poll for more events but don't block this time. */ 1038 timeout = 0; 1039 continue; 1040 } 1041 return; 1042 } 1043 1044 if (timeout == 0) 1045 return; 1046 1047 if (timeout == -1) 1048 continue; 1049 1050update_timeout: 1051 assert(timeout > 0); 1052 1053 real_timeout -= (loop->time - base); 1054 if (real_timeout <= 0) 1055 return; 1056 1057 timeout = real_timeout; 1058 } 1059} 1060 1061 1062int uv__io_fork(uv_loop_t* loop) { 1063 /* 1064 Nullify the msg queue but don't close it because 1065 it is still being used by the parent. 1066 */ 1067 loop->ep = NULL; 1068 1069 return uv__platform_loop_init(loop); 1070} 1071