Print this page
2831 svc.startd and svc.configd waste memory.


 356          * id shouldn't be -1 since we use the same dictionary as graph.c, but
 357          * just in case.
 358          */
 359         inst->ri_id = (id != -1 ? id : dict_insert(name));
 360 
 361         special_online_hooks_get(name, &inst->ri_pre_online_hook,
 362             &inst->ri_post_online_hook, &inst->ri_post_offline_hook);
 363 
 364         scf_svc = safe_scf_service_create(h);
 365         scf_inst = safe_scf_instance_create(h);
 366         pg = safe_scf_pg_create(h);
 367         svc_name = startd_alloc(max_scf_name_size);
 368         inst_name = startd_alloc(max_scf_name_size);
 369 
 370 rep_retry:
 371         if (snap != NULL)
 372                 scf_snapshot_destroy(snap);
 373         if (inst->ri_logstem != NULL)
 374                 startd_free(inst->ri_logstem, PATH_MAX);
 375         if (inst->ri_common_name != NULL)
 376                 startd_free(inst->ri_common_name, max_scf_value_size);

 377         if (inst->ri_C_common_name != NULL)
 378                 startd_free(inst->ri_C_common_name, max_scf_value_size);

 379         snap = NULL;
 380         inst->ri_logstem = NULL;
 381         inst->ri_common_name = NULL;
 382         inst->ri_C_common_name = NULL;
 383 
 384         if (scf_handle_decode_fmri(h, name, NULL, scf_svc, scf_inst, NULL,
 385             NULL, SCF_DECODE_FMRI_EXACT) != 0) {
 386                 switch (scf_error()) {
 387                 case SCF_ERROR_CONNECTION_BROKEN:
 388                         libscf_handle_rebind(h);
 389                         goto rep_retry;
 390 
 391                 case SCF_ERROR_NOT_FOUND:
 392                         goto deleted;
 393                 }
 394 
 395                 uu_die("Can't decode FMRI %s: %s\n", name,
 396                     scf_strerror(scf_error()));
 397         }
 398 


 512 
 513         case ECANCELED:
 514                 goto deleted;
 515 
 516         case ENOENT:
 517                 /*
 518                  * This is odd, because the graph engine should have required
 519                  * the general property group.  So we'll just use default
 520                  * flags in anticipation of the graph engine sending us
 521                  * REMOVE_INSTANCE when it finds out that the general property
 522                  * group has been deleted.
 523                  */
 524                 inst->ri_flags = RINST_CONTRACT;
 525                 break;
 526 
 527         default:
 528                 assert(0);
 529                 abort();
 530         }
 531 
 532         switch (libscf_get_template_values(scf_inst, snap,
 533             &inst->ri_common_name, &inst->ri_C_common_name)) {

















 534         case 0:
 535                 break;
 536 
 537         case ECONNABORTED:
 538                 libscf_handle_rebind(h);
 539                 goto rep_retry;
 540 
 541         case ECANCELED:
 542                 goto deleted;
 543 
 544         case ECHILD:
 545         case ENOENT:
 546                 break;
 547 
 548         default:
 549                 assert(0);
 550                 abort();
 551         }
 552 
 553         switch (libscf_read_method_ids(h, scf_inst, inst->ri_i.i_fmri,


 661 
 662         log_framework(LOG_DEBUG, "%s: inserted instance into restarter list\n",
 663             name);
 664 
 665         return (0);
 666 
 667 deleted:
 668         MUTEX_UNLOCK(&instance_list.ril_lock);
 669         startd_free(inst_name, max_scf_name_size);
 670         startd_free(svc_name, max_scf_name_size);
 671         if (snap != NULL)
 672                 scf_snapshot_destroy(snap);
 673         scf_pg_destroy(pg);
 674         scf_instance_destroy(scf_inst);
 675         scf_service_destroy(scf_svc);
 676         startd_free((void *)inst->ri_i.i_fmri, strlen(inst->ri_i.i_fmri) + 1);
 677         uu_list_destroy(inst->ri_queue);
 678         if (inst->ri_logstem != NULL)
 679                 startd_free(inst->ri_logstem, PATH_MAX);
 680         if (inst->ri_common_name != NULL)
 681                 startd_free(inst->ri_common_name, max_scf_value_size);

 682         if (inst->ri_C_common_name != NULL)
 683                 startd_free(inst->ri_C_common_name, max_scf_value_size);

 684         startd_free(inst->ri_utmpx_prefix, max_scf_value_size);
 685         startd_free(inst, sizeof (restarter_inst_t));
 686         return (ENOENT);
 687 }
 688 
 689 static void
 690 restarter_delete_inst(restarter_inst_t *ri)
 691 {
 692         int id;
 693         restarter_inst_t *rip;
 694         void *cookie = NULL;
 695         restarter_instance_qentry_t *e;
 696 
 697         assert(MUTEX_HELD(&ri->ri_lock));
 698 
 699         /*
 700          * Must drop the instance lock so we can pick up the instance_list
 701          * lock & remove the instance.
 702          */
 703         id = ri->ri_id;


 723         /*
 724          * We can lock the instance without holding the instance_list lock
 725          * since we removed the instance from the list.
 726          */
 727         MUTEX_LOCK(&ri->ri_lock);
 728         MUTEX_LOCK(&ri->ri_queue_lock);
 729 
 730         if (ri->ri_i.i_primary_ctid >= 1)
 731                 contract_hash_remove(ri->ri_i.i_primary_ctid);
 732 
 733         while (ri->ri_method_thread != 0 || ri->ri_method_waiters > 0)
 734                 (void) pthread_cond_wait(&ri->ri_method_cv, &ri->ri_lock);
 735 
 736         while ((e = uu_list_teardown(ri->ri_queue, &cookie)) != NULL)
 737                 startd_free(e, sizeof (*e));
 738         uu_list_destroy(ri->ri_queue);
 739 
 740         startd_free((void *)ri->ri_i.i_fmri, strlen(ri->ri_i.i_fmri) + 1);
 741         startd_free(ri->ri_logstem, PATH_MAX);
 742         if (ri->ri_common_name != NULL)
 743                 startd_free(ri->ri_common_name, max_scf_value_size);

 744         if (ri->ri_C_common_name != NULL)
 745                 startd_free(ri->ri_C_common_name, max_scf_value_size);

 746         startd_free(ri->ri_utmpx_prefix, max_scf_value_size);
 747         (void) pthread_mutex_destroy(&ri->ri_lock);
 748         (void) pthread_mutex_destroy(&ri->ri_queue_lock);
 749         startd_free(ri, sizeof (restarter_inst_t));
 750 }
 751 
 752 /*
 753  * instance_is_wait_style()
 754  *
 755  *   Returns 1 if the given instance is a "wait-style" service instance.
 756  */
 757 int
 758 instance_is_wait_style(restarter_inst_t *inst)
 759 {
 760         assert(MUTEX_HELD(&inst->ri_lock));
 761         return ((inst->ri_flags & RINST_STYLE_MASK) == RINST_WAIT);
 762 }
 763 
 764 /*
 765  * instance_is_transient_style()


1824                 /* delete the event */
1825                 uu_list_remove(rip->ri_queue, event);
1826                 startd_free(event, sizeof (restarter_instance_qentry_t));
1827         }
1828 
1829         assert(rip != NULL);
1830 
1831         /*
1832          * Try to preserve the thread for a little while for future use.
1833          */
1834         to.tv_sec = 3;
1835         to.tv_nsec = 0;
1836         (void) pthread_cond_reltimedwait_np(&rip->ri_queue_cv,
1837             &rip->ri_queue_lock, &to);
1838 
1839         if (uu_list_first(rip->ri_queue) != NULL)
1840                 goto again;
1841 
1842         rip->ri_queue_thread = 0;
1843         MUTEX_UNLOCK(&rip->ri_queue_lock);

1844 out:
1845         (void) scf_handle_unbind(h);
1846         scf_handle_destroy(h);
1847         free(fmri);
1848         return (NULL);
1849 }
1850 
1851 static int
1852 is_admin_event(restarter_event_type_t t) {
1853 
1854         switch (t) {
1855         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1856         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1857         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1858         case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1859         case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1860         case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1861                 return (1);
1862         default:
1863                 return (0);




 356          * id shouldn't be -1 since we use the same dictionary as graph.c, but
 357          * just in case.
 358          */
 359         inst->ri_id = (id != -1 ? id : dict_insert(name));
 360 
 361         special_online_hooks_get(name, &inst->ri_pre_online_hook,
 362             &inst->ri_post_online_hook, &inst->ri_post_offline_hook);
 363 
 364         scf_svc = safe_scf_service_create(h);
 365         scf_inst = safe_scf_instance_create(h);
 366         pg = safe_scf_pg_create(h);
 367         svc_name = startd_alloc(max_scf_name_size);
 368         inst_name = startd_alloc(max_scf_name_size);
 369 
 370 rep_retry:
 371         if (snap != NULL)
 372                 scf_snapshot_destroy(snap);
 373         if (inst->ri_logstem != NULL)
 374                 startd_free(inst->ri_logstem, PATH_MAX);
 375         if (inst->ri_common_name != NULL)
 376                 startd_free(inst->ri_common_name,
 377                     strlen(inst->ri_common_name) + 1);
 378         if (inst->ri_C_common_name != NULL)
 379                 startd_free(inst->ri_C_common_name,
 380                     strlen(inst->ri_C_common_name) + 1);
 381         snap = NULL;
 382         inst->ri_logstem = NULL;
 383         inst->ri_common_name = NULL;
 384         inst->ri_C_common_name = NULL;
 385 
 386         if (scf_handle_decode_fmri(h, name, NULL, scf_svc, scf_inst, NULL,
 387             NULL, SCF_DECODE_FMRI_EXACT) != 0) {
 388                 switch (scf_error()) {
 389                 case SCF_ERROR_CONNECTION_BROKEN:
 390                         libscf_handle_rebind(h);
 391                         goto rep_retry;
 392 
 393                 case SCF_ERROR_NOT_FOUND:
 394                         goto deleted;
 395                 }
 396 
 397                 uu_die("Can't decode FMRI %s: %s\n", name,
 398                     scf_strerror(scf_error()));
 399         }
 400 


 514 
 515         case ECANCELED:
 516                 goto deleted;
 517 
 518         case ENOENT:
 519                 /*
 520                  * This is odd, because the graph engine should have required
 521                  * the general property group.  So we'll just use default
 522                  * flags in anticipation of the graph engine sending us
 523                  * REMOVE_INSTANCE when it finds out that the general property
 524                  * group has been deleted.
 525                  */
 526                 inst->ri_flags = RINST_CONTRACT;
 527                 break;
 528 
 529         default:
 530                 assert(0);
 531                 abort();
 532         }
 533 
 534         r = libscf_get_template_values(scf_inst, snap,
 535             &inst->ri_common_name, &inst->ri_C_common_name);
 536 
 537         /*
 538          * Copy our names to smaller buffers to reduce our memory footprint.
 539          */
 540         if (inst->ri_common_name != NULL) {
 541                 char *tmp = safe_strdup(inst->ri_common_name);
 542                 startd_free(inst->ri_common_name, max_scf_value_size);
 543                 inst->ri_common_name = tmp;
 544         }
 545 
 546         if (inst->ri_C_common_name != NULL) {
 547                 char *tmp = safe_strdup(inst->ri_C_common_name);
 548                 startd_free(inst->ri_C_common_name, max_scf_value_size);
 549                 inst->ri_C_common_name = tmp;
 550         }
 551 
 552         switch (r) {
 553         case 0:
 554                 break;
 555 
 556         case ECONNABORTED:
 557                 libscf_handle_rebind(h);
 558                 goto rep_retry;
 559 
 560         case ECANCELED:
 561                 goto deleted;
 562 
 563         case ECHILD:
 564         case ENOENT:
 565                 break;
 566 
 567         default:
 568                 assert(0);
 569                 abort();
 570         }
 571 
 572         switch (libscf_read_method_ids(h, scf_inst, inst->ri_i.i_fmri,


 680 
 681         log_framework(LOG_DEBUG, "%s: inserted instance into restarter list\n",
 682             name);
 683 
 684         return (0);
 685 
 686 deleted:
 687         MUTEX_UNLOCK(&instance_list.ril_lock);
 688         startd_free(inst_name, max_scf_name_size);
 689         startd_free(svc_name, max_scf_name_size);
 690         if (snap != NULL)
 691                 scf_snapshot_destroy(snap);
 692         scf_pg_destroy(pg);
 693         scf_instance_destroy(scf_inst);
 694         scf_service_destroy(scf_svc);
 695         startd_free((void *)inst->ri_i.i_fmri, strlen(inst->ri_i.i_fmri) + 1);
 696         uu_list_destroy(inst->ri_queue);
 697         if (inst->ri_logstem != NULL)
 698                 startd_free(inst->ri_logstem, PATH_MAX);
 699         if (inst->ri_common_name != NULL)
 700                 startd_free(inst->ri_common_name,
 701                     strlen(inst->ri_common_name) + 1);
 702         if (inst->ri_C_common_name != NULL)
 703                 startd_free(inst->ri_C_common_name,
 704                     strlen(inst->ri_C_common_name) + 1);
 705         startd_free(inst->ri_utmpx_prefix, max_scf_value_size);
 706         startd_free(inst, sizeof (restarter_inst_t));
 707         return (ENOENT);
 708 }
 709 
 710 static void
 711 restarter_delete_inst(restarter_inst_t *ri)
 712 {
 713         int id;
 714         restarter_inst_t *rip;
 715         void *cookie = NULL;
 716         restarter_instance_qentry_t *e;
 717 
 718         assert(MUTEX_HELD(&ri->ri_lock));
 719 
 720         /*
 721          * Must drop the instance lock so we can pick up the instance_list
 722          * lock & remove the instance.
 723          */
 724         id = ri->ri_id;


 744         /*
 745          * We can lock the instance without holding the instance_list lock
 746          * since we removed the instance from the list.
 747          */
 748         MUTEX_LOCK(&ri->ri_lock);
 749         MUTEX_LOCK(&ri->ri_queue_lock);
 750 
 751         if (ri->ri_i.i_primary_ctid >= 1)
 752                 contract_hash_remove(ri->ri_i.i_primary_ctid);
 753 
 754         while (ri->ri_method_thread != 0 || ri->ri_method_waiters > 0)
 755                 (void) pthread_cond_wait(&ri->ri_method_cv, &ri->ri_lock);
 756 
 757         while ((e = uu_list_teardown(ri->ri_queue, &cookie)) != NULL)
 758                 startd_free(e, sizeof (*e));
 759         uu_list_destroy(ri->ri_queue);
 760 
 761         startd_free((void *)ri->ri_i.i_fmri, strlen(ri->ri_i.i_fmri) + 1);
 762         startd_free(ri->ri_logstem, PATH_MAX);
 763         if (ri->ri_common_name != NULL)
 764                 startd_free(ri->ri_common_name,
 765                     strlen(ri->ri_common_name) + 1);
 766         if (ri->ri_C_common_name != NULL)
 767                 startd_free(ri->ri_C_common_name,
 768                     strlen(ri->ri_C_common_name) + 1);
 769         startd_free(ri->ri_utmpx_prefix, max_scf_value_size);
 770         (void) pthread_mutex_destroy(&ri->ri_lock);
 771         (void) pthread_mutex_destroy(&ri->ri_queue_lock);
 772         startd_free(ri, sizeof (restarter_inst_t));
 773 }
 774 
 775 /*
 776  * instance_is_wait_style()
 777  *
 778  *   Returns 1 if the given instance is a "wait-style" service instance.
 779  */
 780 int
 781 instance_is_wait_style(restarter_inst_t *inst)
 782 {
 783         assert(MUTEX_HELD(&inst->ri_lock));
 784         return ((inst->ri_flags & RINST_STYLE_MASK) == RINST_WAIT);
 785 }
 786 
 787 /*
 788  * instance_is_transient_style()


1847                 /* delete the event */
1848                 uu_list_remove(rip->ri_queue, event);
1849                 startd_free(event, sizeof (restarter_instance_qentry_t));
1850         }
1851 
1852         assert(rip != NULL);
1853 
1854         /*
1855          * Try to preserve the thread for a little while for future use.
1856          */
1857         to.tv_sec = 3;
1858         to.tv_nsec = 0;
1859         (void) pthread_cond_reltimedwait_np(&rip->ri_queue_cv,
1860             &rip->ri_queue_lock, &to);
1861 
1862         if (uu_list_first(rip->ri_queue) != NULL)
1863                 goto again;
1864 
1865         rip->ri_queue_thread = 0;
1866         MUTEX_UNLOCK(&rip->ri_queue_lock);
1867 
1868 out:
1869         (void) scf_handle_unbind(h);
1870         scf_handle_destroy(h);
1871         free(fmri);
1872         return (NULL);
1873 }
1874 
1875 static int
1876 is_admin_event(restarter_event_type_t t) {
1877 
1878         switch (t) {
1879         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1880         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1881         case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1882         case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1883         case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1884         case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1885                 return (1);
1886         default:
1887                 return (0);