summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authoramaguire <none@none>2008-01-15 02:43:28 -0800
committeramaguire <none@none>2008-01-15 02:43:28 -0800
commit347a77f277285a2c589b756c918c3f40eefbbb8b (patch)
tree5c23fa61fc5cfc4401e2ab073a1526804a49721e /usr/src
parent29680e551a97367a1d58ec0c94a967aa81fac54a (diff)
downloadillumos-gate-347a77f277285a2c589b756c918c3f40eefbbb8b.tar.gz
PSARC/2008/015 svccfg refresh subcommand
5087504 svccfg should allow 'refresh' of services on an alternate repository
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg.h1
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg.l3
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg.y8
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg_engine.c2
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg_help.c9
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg_libscf.c115
6 files changed, 126 insertions, 12 deletions
diff --git a/usr/src/cmd/svc/svccfg/svccfg.h b/usr/src/cmd/svc/svccfg/svccfg.h
index ee26bc6dcf..971f4175f2 100644
--- a/usr/src/cmd/svc/svccfg/svccfg.h
+++ b/usr/src/cmd/svc/svccfg/svccfg.h
@@ -343,6 +343,7 @@ void lscf_delprop(char *);
void lscf_listsnap();
void lscf_selectsnap(const char *);
void lscf_revert(const char *);
+void lscf_refresh();
char *filename_to_propname(const char *);
int lscf_retrieve_hash(const char *, unsigned char *);
int lscf_store_hash(const char *, unsigned char *);
diff --git a/usr/src/cmd/svc/svccfg/svccfg.l b/usr/src/cmd/svc/svccfg/svccfg.l
index 47055f80a9..9ecff499e4 100644
--- a/usr/src/cmd/svc/svccfg/svccfg.l
+++ b/usr/src/cmd/svc/svccfg/svccfg.l
@@ -21,7 +21,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -112,6 +112,7 @@ extern int yyerror(const char *);
<INITIAL>listsnap { BEGIN WORD; return (SCC_LISTSNAP); }
<INITIAL>selectsnap { BEGIN WORD; return (SCC_SELECTSNAP); }
<INITIAL>revert { BEGIN WORD; return (SCC_REVERT); }
+<INITIAL>refresh { BEGIN WORD; return (SCC_REFRESH); }
[^ \t\n">=()]+ {
if ((yylval.str = strdup(yytext)) == NULL) {
diff --git a/usr/src/cmd/svc/svccfg/svccfg.y b/usr/src/cmd/svc/svccfg/svccfg.y
index 311a2d6de1..53c92b49c7 100644
--- a/usr/src/cmd/svc/svccfg/svccfg.y
+++ b/usr/src/cmd/svc/svccfg/svccfg.y
@@ -21,7 +21,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,7 +49,7 @@ uu_list_pool_t *string_pool;
%token SCC_LISTPG SCC_ADDPG SCC_DELPG
%token SCC_LISTPROP SCC_SETPROP SCC_DELPROP SCC_EDITPROP
%token SCC_ADDPROPVALUE SCC_DELPROPVALUE SCC_SETENV SCC_UNSETENV
-%token SCC_LISTSNAP SCC_SELECTSNAP SCC_REVERT
+%token SCC_LISTSNAP SCC_SELECTSNAP SCC_REVERT SCC_REFRESH
%token SCS_REDIRECT SCS_NEWLINE SCS_EQUALS SCS_LPAREN SCS_RPAREN
%token SCV_WORD SCV_STRING
@@ -103,6 +103,7 @@ command : terminator
| listsnap_cmd
| selectsnap_cmd
| revert_cmd
+ | refresh_cmd
| unknown_cmd
| error terminator { semerr(gettext("Syntax error.\n")); }
@@ -462,6 +463,8 @@ selectsnap_cmd : SCC_SELECTSNAP opt_word terminator
revert_cmd: SCC_REVERT opt_word terminator { lscf_revert($2); free ($2); }
| SCC_REVERT error terminator { synerr(SCC_REVERT); return(0); }
+refresh_cmd: SCC_REFRESH terminator { lscf_refresh(); }
+ | SCC_REFRESH error terminator { synerr(SCC_REFRESH); return(0); }
terminator : SCS_NEWLINE
@@ -535,3 +538,4 @@ command_token : SCC_VALIDATE { $$ = SCC_VALIDATE; }
| SCC_LISTSNAP { $$ = SCC_LISTSNAP; }
| SCC_SELECTSNAP { $$ = SCC_SELECTSNAP; }
| SCC_REVERT { $$ = SCC_REVERT; }
+ | SCC_REFRESH { $$ = SCC_REFRESH; }
diff --git a/usr/src/cmd/svc/svccfg/svccfg_engine.c b/usr/src/cmd/svc/svccfg/svccfg_engine.c
index cf7ba71437..105c166778 100644
--- a/usr/src/cmd/svc/svccfg/svccfg_engine.c
+++ b/usr/src/cmd/svc/svccfg/svccfg_engine.c
@@ -223,6 +223,7 @@ static struct cmd_info {
{ "listsnap", CS_INST | CS_SNAP, NULL },
{ "selectsnap", CS_INST | CS_SNAP, NULL },
{ "revert", CS_INST | CS_SNAP, NULL },
+ { "refresh", CS_INST, NULL },
{ NULL }
};
@@ -732,6 +733,7 @@ help(int com)
"Profile commands: apply extract\n"
"Entity commands: list select unselect add delete\n"
"Snapshot commands: listsnap selectsnap revert\n"
+ "Instance commands: refresh\n"
"Property group commands: listpg addpg delpg\n"
"Property commands: listprop setprop delprop editprop\n"
"Property value commands: addpropvalue delpropvalue "
diff --git a/usr/src/cmd/svc/svccfg/svccfg_help.c b/usr/src/cmd/svc/svccfg/svccfg_help.c
index 67ba47d9f4..a9b8713fb8 100644
--- a/usr/src/cmd/svc/svccfg/svccfg_help.c
+++ b/usr/src/cmd/svc/svccfg/svccfg_help.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -120,5 +120,12 @@ struct help_message help_messages[] = {
"Change the properties of the currently selected instance and its ancestors\n"
"to those in a snapshot, or the currently selected snapshot by default."
},
+ { SCC_REFRESH, "refresh\n\n"
+"Commit the values from the current configuration to the running\n"
+"snapshot, making them available for use by the currently selected\n"
+"instance. If the repository subcommand has not been used to select\n"
+"a repository, inform the instance's restarter to re-read the updated\n"
+"configuration."
+ },
{ 0, NULL }
};
diff --git a/usr/src/cmd/svc/svccfg/svccfg_libscf.c b/usr/src/cmd/svc/svccfg/svccfg_libscf.c
index 8463b26331..a8c47b6962 100644
--- a/usr/src/cmd/svc/svccfg/svccfg_libscf.c
+++ b/usr/src/cmd/svc/svccfg/svccfg_libscf.c
@@ -4983,7 +4983,7 @@ upgrade_props(void *ent, scf_snaplevel_t *running, scf_snaplevel_t *snpl,
}
/*
- * Create or update a snapshot of inst. Uses imp_snap.
+ * Create or update a snapshot of inst. snap is a required scratch object.
*
* Returns
* 0 - success
@@ -4994,11 +4994,11 @@ upgrade_props(void *ent, scf_snaplevel_t *running, scf_snaplevel_t *snpl,
* -1 - unknown libscf error (message printed)
*/
static int
-take_snap(scf_instance_t *inst, const char *name)
+take_snap(scf_instance_t *inst, const char *name, scf_snapshot_t *snap)
{
again:
- if (scf_instance_get_snapshot(inst, name, imp_snap) == 0) {
- if (_scf_snapshot_take_attach(inst, imp_snap) != 0) {
+ 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:
@@ -5029,7 +5029,7 @@ again:
bad_error("scf_instance_get_snapshot", scf_error());
}
- if (_scf_snapshot_take_new(inst, name, imp_snap) != 0) {
+ if (_scf_snapshot_take_new(inst, name, snap) != 0) {
switch (scf_error()) {
case SCF_ERROR_EXISTS:
goto again;
@@ -5592,7 +5592,7 @@ nosnap:
if (g_verbose)
warn(gettext("Taking \"%s\" snapshot for %s.\n"),
snap_initial, inst->sc_fmri);
- r = take_snap(imp_inst, snap_initial);
+ r = take_snap(imp_inst, snap_initial, imp_snap);
switch (r) {
case 0:
break;
@@ -6090,7 +6090,7 @@ lscf_service_import(void *v, void *pvt)
"Taking \"%s\" snapshot for svc:/%s:%s.\n"),
snap_previous, s->sc_name, imp_str);
- r = take_snap(imp_inst, snap_previous);
+ r = take_snap(imp_inst, snap_previous, imp_snap);
switch (r) {
case 0:
break;
@@ -6184,7 +6184,7 @@ lscf_service_import(void *v, void *pvt)
if (g_verbose)
warn(gettext("Taking \"%s\" snapshot for "
"new service %s.\n"), snap_previous, inst->sc_fmri);
- r = take_snap(imp_inst, snap_previous);
+ r = take_snap(imp_inst, snap_previous, imp_snap);
switch (r) {
case 0:
break;
@@ -12323,6 +12323,105 @@ out:
scf_snapshot_destroy(snap);
}
+void
+lscf_refresh(void)
+{
+ ssize_t fmrilen;
+ size_t bufsz;
+ char *fmribuf;
+ int r;
+ scf_snapshot_t *snap;
+
+ lscf_prep_hndl();
+
+ if (cur_inst == NULL) {
+ semerr(gettext("Instance not selected.\n"));
+ return;
+ }
+
+ bufsz = max_scf_fmri_len + 1;
+ fmribuf = safe_malloc(bufsz);
+ fmrilen = scf_instance_to_fmri(cur_inst, fmribuf, bufsz);
+ if (fmrilen < 0) {
+ free(fmribuf);
+ if (scf_error() != SCF_ERROR_DELETED)
+ scfdie();
+ scf_instance_destroy(cur_inst);
+ cur_inst = NULL;
+ warn(emsg_deleted);
+ return;
+ }
+ 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;
+
+ 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 ENOSPC:
+ warn(gettext("Could not refresh %s "
+ "(repository server out of resources).\n"),
+ fmribuf);
+ break;
+
+ default:
+ bad_error("take_snap", scf_error());
+ }
+ }
+
+ free(fmribuf);
+}
+
#ifndef NATIVE_BUILD
/* ARGSUSED */
CPL_MATCH_FN(complete_select)