diff options
| author | Sean Wilcox <Sean.Wilcox@Sun.COM> | 2009-01-08 15:26:25 -0700 |
|---|---|---|
| committer | Sean Wilcox <Sean.Wilcox@Sun.COM> | 2009-01-08 15:26:25 -0700 |
| commit | 67b54fb64138aa0cc33ebb72f670b0956d2ba53d (patch) | |
| tree | fd63c445ec9c46745e342959f2877adaeb1395f2 /usr/src/cmd | |
| parent | ed9c9f974daf230167107f22b896206a90ae2390 (diff) | |
| download | illumos-joyent-67b54fb64138aa0cc33ebb72f670b0956d2ba53d.tar.gz | |
6790135 WOS images go into maintenance mode post-6765907
Diffstat (limited to 'usr/src/cmd')
| -rw-r--r-- | usr/src/cmd/svc/svccfg/svccfg_libscf.c | 412 |
1 files changed, 267 insertions, 145 deletions
diff --git a/usr/src/cmd/svc/svccfg/svccfg_libscf.c b/usr/src/cmd/svc/svccfg/svccfg_libscf.c index 2440306534..b31f76314e 100644 --- a/usr/src/cmd/svc/svccfg/svccfg_libscf.c +++ b/usr/src/cmd/svc/svccfg/svccfg_libscf.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1384,6 +1384,93 @@ out: } /* + * Create or update a snapshot of inst. snap is a required scratch object. + * + * Returns + * 0 - success + * ECONNABORTED - repository connection broken + * EPERM - permission denied + * ENOSPC - configd is out of resources + * ECANCELED - inst was deleted + * -1 - unknown libscf error (message printed) + */ +static int +take_snap(scf_instance_t *inst, const char *name, scf_snapshot_t *snap) +{ +again: + if (scf_instance_get_snapshot(inst, name, snap) == 0) { + if (_scf_snapshot_take_attach(inst, snap) != 0) { + switch (scf_error()) { + case SCF_ERROR_CONNECTION_BROKEN: + case SCF_ERROR_PERMISSION_DENIED: + case SCF_ERROR_NO_RESOURCES: + return (scferror2errno(scf_error())); + + case SCF_ERROR_NOT_SET: + case SCF_ERROR_INVALID_ARGUMENT: + default: + bad_error("_scf_snapshot_take_attach", + scf_error()); + } + } + } else { + switch (scf_error()) { + case SCF_ERROR_NOT_FOUND: + break; + + case SCF_ERROR_DELETED: + case SCF_ERROR_CONNECTION_BROKEN: + return (scferror2errno(scf_error())); + + case SCF_ERROR_HANDLE_MISMATCH: + case SCF_ERROR_NOT_BOUND: + case SCF_ERROR_INVALID_ARGUMENT: + case SCF_ERROR_NOT_SET: + default: + bad_error("scf_instance_get_snapshot", scf_error()); + } + + if (_scf_snapshot_take_new(inst, name, snap) != 0) { + switch (scf_error()) { + case SCF_ERROR_EXISTS: + goto again; + + case SCF_ERROR_CONNECTION_BROKEN: + case SCF_ERROR_NO_RESOURCES: + case SCF_ERROR_PERMISSION_DENIED: + return (scferror2errno(scf_error())); + + default: + scfwarn(); + return (-1); + + case SCF_ERROR_NOT_SET: + case SCF_ERROR_INTERNAL: + case SCF_ERROR_INVALID_ARGUMENT: + case SCF_ERROR_HANDLE_MISMATCH: + bad_error("_scf_snapshot_take_new", + scf_error()); + } + } + } + + return (0); +} + +static int +refresh_running_snapshot(void *entity) { + scf_snapshot_t *snap; + int r; + + if ((snap = scf_snapshot_create(g_hndl)) == NULL) + scfdie(); + r = take_snap(entity, snap_running, snap); + scf_snapshot_destroy(snap); + + return (r); +} + +/* * Refresh entity. If isservice is zero, take entity to be an scf_instance_t *. * Otherwise take entity to be an scf_service_t * and refresh all of its child * instances. fmri is used for messages. inst, iter, and name_buf are used @@ -1393,6 +1480,7 @@ out: * ECANCELED - entity was deleted * EACCES - backend denied access * EPERM - permission denied + * ENOSPC - repository server out of resources * -1 - _smf_refresh_instance_i() failed. scf_error() should be set. */ static int @@ -1403,21 +1491,41 @@ refresh_entity(int isservice, void *entity, const char *fmri, int r; if (!isservice) { - if (_smf_refresh_instance_i(entity) == 0) { - if (g_verbose) - warn(gettext("Refreshed %s.\n"), fmri); - return (0); - } + if (est->sc_repo_filename == NULL) { + if (_smf_refresh_instance_i(entity) == 0) { + if (g_verbose) + warn(gettext("Refreshed %s.\n"), fmri); + return (0); + } - switch (scf_error()) { - case SCF_ERROR_BACKEND_ACCESS: - return (EACCES); + switch (scf_error()) { + case SCF_ERROR_BACKEND_ACCESS: + return (EACCES); - case SCF_ERROR_PERMISSION_DENIED: - return (EPERM); + case SCF_ERROR_PERMISSION_DENIED: + return (EPERM); - default: - return (-1); + default: + return (-1); + } + } else { + r = refresh_running_snapshot(entity); + switch (r) { + case 0: + break; + + case ECONNABORTED: + case ECANCELED: + case EPERM: + case ENOSPC: + break; + + default: + bad_error("refresh_running_snapshot", + scf_error()); + } + + return (r); } } @@ -1459,6 +1567,26 @@ refresh_entity(int isservice, void *entity, const char *fmri, } } + if (est->sc_repo_filename != NULL) { + r = refresh_running_snapshot(inst); + switch (r) { + case 0: + continue; + + case ECONNABORTED: + case ECANCELED: + case EPERM: + case ENOSPC: + break; + default: + bad_error("refresh_running_snapshot", + scf_error()); + } + + return (r); + + } + if (_smf_refresh_instance_i(inst) == 0) { if (g_verbose) { if (scf_instance_get_name(inst, name_buf, @@ -1487,91 +1615,99 @@ refresh_entity(int isservice, void *entity, const char *fmri, return (0); } -static int -stash_scferror_err(scf_callback_t *cbp, scf_error_t err) +static void +private_refresh(void) { - cbp->sc_err = scferror2errno(err); - return (UU_WALK_ERROR); -} + scf_instance_t *pinst = NULL; + scf_iter_t *piter = NULL; + ssize_t fmrilen; + size_t bufsz; + char *fmribuf; + void *ent; + int issvc; + int r; -static int -stash_scferror(scf_callback_t *cbp) -{ - return (stash_scferror_err(cbp, scf_error())); -} + if (est->sc_repo_filename == NULL) + return; -/* - * Create or update a snapshot of inst. snap is a required scratch object. - * - * Returns - * 0 - success - * ECONNABORTED - repository connection broken - * EPERM - permission denied - * ENOSPC - configd is out of resources - * ECANCELED - inst was deleted - * -1 - unknown libscf error (message printed) - */ -static int -take_snap(scf_instance_t *inst, const char *name, scf_snapshot_t *snap) -{ -again: - if (scf_instance_get_snapshot(inst, name, snap) == 0) { - if (_scf_snapshot_take_attach(inst, snap) != 0) { - switch (scf_error()) { - case SCF_ERROR_CONNECTION_BROKEN: - case SCF_ERROR_PERMISSION_DENIED: - case SCF_ERROR_NO_RESOURCES: - return (scferror2errno(scf_error())); + assert(cur_svc != NULL); - case SCF_ERROR_NOT_SET: - case SCF_ERROR_INVALID_ARGUMENT: - default: - bad_error("_scf_snapshot_take_attach", - scf_error()); - } - } + bufsz = max_scf_fmri_len + 1; + fmribuf = safe_malloc(bufsz); + if (cur_inst) { + issvc = 0; + ent = cur_inst; + fmrilen = scf_instance_to_fmri(ent, fmribuf, bufsz); } else { - switch (scf_error()) { - case SCF_ERROR_NOT_FOUND: - break; + issvc = 1; + ent = cur_svc; + fmrilen = scf_service_to_fmri(ent, fmribuf, bufsz); + if ((pinst = scf_instance_create(g_hndl)) == NULL) + scfdie(); - case SCF_ERROR_DELETED: - case SCF_ERROR_CONNECTION_BROKEN: - return (scferror2errno(scf_error())); + if ((piter = scf_iter_create(g_hndl)) == NULL) + scfdie(); + } + if (fmrilen < 0) { + free(fmribuf); + if (scf_error() != SCF_ERROR_DELETED) + scfdie(); - case SCF_ERROR_HANDLE_MISMATCH: - case SCF_ERROR_NOT_BOUND: - case SCF_ERROR_INVALID_ARGUMENT: - case SCF_ERROR_NOT_SET: - default: - bad_error("scf_instance_get_snapshot", scf_error()); - } + warn(emsg_deleted); + return; + } + assert(fmrilen < bufsz); - if (_scf_snapshot_take_new(inst, name, snap) != 0) { - switch (scf_error()) { - case SCF_ERROR_EXISTS: - goto again; + r = refresh_entity(issvc, ent, fmribuf, pinst, piter, NULL); + switch (r) { + case 0: + break; - case SCF_ERROR_CONNECTION_BROKEN: - case SCF_ERROR_NO_RESOURCES: - case SCF_ERROR_PERMISSION_DENIED: - return (scferror2errno(scf_error())); + case ECONNABORTED: + warn(gettext("Could not refresh %s " + "(repository connection broken).\n"), fmribuf); + break; - default: - scfwarn(); - return (-1); + case ECANCELED: + warn(emsg_deleted); + break; - case SCF_ERROR_NOT_SET: - case SCF_ERROR_INTERNAL: - case SCF_ERROR_INVALID_ARGUMENT: - case SCF_ERROR_HANDLE_MISMATCH: - bad_error("_scf_snapshot_take_new", - scf_error()); - } - } + case EPERM: + warn(gettext("Could not refresh %s " + "(permission denied).\n"), fmribuf); + break; + + case ENOSPC: + warn(gettext("Could not refresh %s " + "(repository server out of resources).\n"), + fmribuf); + break; + + case EACCES: + default: + bad_error("refresh_entity", scf_error()); } - return (0); + if (issvc) { + scf_instance_destroy(pinst); + scf_iter_destroy(piter); + } + + free(fmribuf); +} + + +static int +stash_scferror_err(scf_callback_t *cbp, scf_error_t err) +{ + cbp->sc_err = scferror2errno(err); + return (UU_WALK_ERROR); +} + +static int +stash_scferror(scf_callback_t *cbp) +{ + return (stash_scferror_err(cbp, scf_error())); } /* @@ -6782,6 +6918,18 @@ imp_refresh_fmri(const char *fmri, const char *name, const char *d_fmri) "(permission denied).\n"), fmri, name, d_fmri); return (r); + case ENOSPC: + if (name == NULL) + warn(gettext("Could not refresh %s " + "(repository server out of resources).\n"), + fmri); + else + warn(gettext("Could not refresh %s " + "(dependent \"%s\" of %s) " + "(repository server out of resources).\n"), + fmri, name, d_fmri); + return (r); + case -1: scfwarn(); return (r); @@ -11914,6 +12062,8 @@ lscf_addpg(const char *name, const char *type, const char *flags) } scf_pg_destroy(pg); + + private_refresh(); } void @@ -12173,6 +12323,9 @@ lscf_setprop(const char *pgname, const char *type, const char *value, } ret = 0; + + private_refresh(); + goto cleanup; fail: @@ -12256,6 +12409,8 @@ lscf_delprop(char *pgn) scfdie(); semerr(emsg_permission_denied); + } else { + private_refresh(); } scf_pg_destroy(pg); @@ -12300,6 +12455,8 @@ lscf_delprop(char *pgn) scfdie(); semerr(emsg_permission_denied); + } else { + private_refresh(); } scf_transaction_destroy(tx); @@ -12851,6 +13008,8 @@ lscf_setpropvalue(const char *pgname, const char *type, result = 0; + private_refresh(); + out: scf_transaction_destroy(tx); scf_entry_destroy(e); @@ -13670,7 +13829,6 @@ lscf_refresh(void) size_t bufsz; char *fmribuf; int r; - scf_snapshot_t *snap; lscf_prep_hndl(); @@ -13693,70 +13851,34 @@ lscf_refresh(void) } assert(fmrilen < bufsz); - /* - * If the repository is the active one, a refresh of the instance is - * requested. For alternate repositories, the refresh command simply - * takes a new 'running' snapshot, so the refresh method is not run. - */ - if (est->sc_repo_filename == NULL) { - r = refresh_entity(0, cur_inst, fmribuf, NULL, NULL, NULL); - - switch (r) { - case 0: - break; - - case ECONNABORTED: - warn(gettext("Could not refresh %s " - "(repository connection broken).\n"), fmribuf); - break; - - case ECANCELED: - warn(emsg_deleted); - break; - - case EPERM: - warn(gettext("Could not refresh %s " - "(permission denied).\n"), fmribuf); - break; - - case EACCES: - default: - bad_error("refresh_entity", scf_error()); - } - - } else { - if ((snap = scf_snapshot_create(g_hndl)) == NULL) - scfdie(); - r = take_snap(cur_inst, snap_running, snap); - scf_snapshot_destroy(snap); - - switch (r) { - case 0: - break; + r = refresh_entity(0, cur_inst, fmribuf, NULL, NULL, NULL); + switch (r) { + case 0: + break; - case ECONNABORTED: - warn(gettext("Could not refresh %s " - "(repository connection broken).\n"), fmribuf); - break; + case ECONNABORTED: + warn(gettext("Could not refresh %s " + "(repository connection broken).\n"), fmribuf); + break; - case ECANCELED: - warn(emsg_deleted); - break; + case ECANCELED: + warn(emsg_deleted); + break; - case EPERM: - warn(gettext("Could not refresh %s " - "(permission denied).\n"), fmribuf); - break; + case EPERM: + warn(gettext("Could not refresh %s " + "(permission denied).\n"), fmribuf); + break; - case ENOSPC: - warn(gettext("Could not refresh %s " - "(repository server out of resources).\n"), - fmribuf); - break; + case ENOSPC: + warn(gettext("Could not refresh %s " + "(repository server out of resources).\n"), + fmribuf); + break; - default: - bad_error("take_snap", scf_error()); - } + case EACCES: + default: + bad_error("refresh_entity", scf_error()); } free(fmribuf); |
