prophist.c revision 449975fd500a154ec93bafe3fc6a5913c5bb82a5
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* prophist - property history utility
*
* 1. Description
*
* During the development of smf(5), a set of service manifests were delivered
* that required subsequent changes. The bulk of these changes are in ON,
* although additional consolidations may possess one or two manifests that are
* affected. These incorrect values need to be smoothed into a correct
* configuration surface for subsequent automatic merge technology to be
* introduced safely. The mechanism is the combination of this utility with a
* set of "property history" files.
*
* /var/svc/profile/prophist.SUNWcsr is delivered as an immutable file by the
* SUNWcsr packages. prophist.SUNWcsr covers the entire ON consolidation, for
* the purposes of collecting in one place what is essentially a temporary
* files.
*
* The processing of the property history files occurs in
* svc:/system/manifest-import:default. Each prophist.* file is checked against
* detected, the prophist.* file is sourced. These operations are carried out
* prior to any manifest being imported.
*
* 2. Interface
*
* prophist presents a subcommand style interface, with various suboptions to
* each subcommand:
*
* prophist delete -e FMRI -g pg [-p prop]
* prophist upgrade -e FMRI -g pg -p prop -n newval oldval ...
* prophist overwrite -e FMRI -g pg -p prop -n newval
* prophist hash file
*
* The hash subcommand signals that a file requires processing using an exit
* status of 3. Otherwise, exit statuses of 0, 1, and 2 have their conventional
* meaning.
*
* 3. Limitations
*
* The present implementation has no support for multiply-valued properties.
* Manipulation of such properties should be done using a svccfg(1M) invocation
* in the appropriate prophist.* file.
*/
#include <assert.h>
#include <libintl.h>
#include <libscf.h>
#include <libscf_priv.h>
#include <libuutil.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <manifest_hash.h>
#define OPTIONS_STR "e:g:n:p:"
static int o_delete;
static int o_hash;
static int o_overwrite;
static char *entity;
static char *pgrp_name;
static char *prop_name;
static char *new_value;
static scf_handle_t *hndl;
static scf_service_t *svc;
static scf_instance_t *inst;
static scf_snapshot_t *snap;
static scf_snaplevel_t *level;
static scf_propertygroup_t *pg;
static scf_property_t *prop;
static scf_value_t *value;
static scf_iter_t *iter;
static scf_transaction_t *tx;
static scf_transaction_entry_t *entry;
static scf_type_t ptype;
static char *valbuf;
static void
usage()
{
"Usage:"
"\tprophist hash file\n"
"\tprophist delete -e FMRI -g pg [-p prop]\n"
"\tprophist overwrite -e FMRI -g pg -p prop -n newval\n"
"\tprophist upgrade -e FMRI -g pg -p prop -n newval oldval "
"...\n"));
}
static void
{
scf_strerror(scf_error()));
if (scf_handle_bind(hndl) != 0)
scf_strerror(scf_error()));
scf_strerror(scf_error()));
valbuf_sz = 4096;
}
static int
{
char *pname;
char *errstr;
int ret;
case MHASH_RECONCILED:
/* Equivalent hash already stored. */
return (0);
case MHASH_NEWFILE:
/* Hash differs. */
break;
case MHASH_FAILURE:
default:
"mhash_test_file()"), ret);
}
if (errstr)
else
"mhash_store_entry()\n"));
}
return (3);
}
static int
{
scf_strerror(scf_error()));
scf_strerror(scf_error()));
return (1);
return (0);
}
/*
* Returns 1 if target property group or property not found.
*/
static int
{
continue;
continue;
if (scf_pg_delete(pg) != 0)
scf_strerror(scf_error()));
return (0);
}
return (1);
}
/*
* Remove property group or property from both service and instance.
*/
static int
{
SCF_DECODE_FMRI_EXACT) == 0) {
}
NULL, SCF_DECODE_FMRI_EXACT) == 0) {
}
scf_strerror(scf_error()));
/*NOTREACHED*/
}
static void
{
int result;
int ret;
do {
scf_strerror(scf_error()));
if (scf_error() == SCF_ERROR_PERMISSION_DENIED)
scf_strerror(scf_error()));
}
if (ret == SCF_SUCCESS) {
} else if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) {
} else {
}
(const char *)new_value) != 0) {
}
if (ret != SCF_SUCCESS)
scf_strerror(scf_error()));
} while (result == 0);
if (result < 0) {
if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
scf_strerror(scf_error()));
}
}
static scf_propertygroup_t *
{
SCF_DECODE_FMRI_EXACT) == 0) {
/*
* 1. Working at the instance level. The instance level
* current version, and its value in snapshots is not relevant.
* Otherwise, pull from running snapshot.
*/
return (pg);
}
return (pg);
}
scf_strerror(scf_error()));
return (targetpg);
}
NULL, SCF_DECODE_FMRI_EXACT) == 0) {
/*
* 2. Working at the service level.
*/
return (pg);
}
/*
* 3. Cannot decode either instance or service exactly.
*/
scf_strerror(scf_error()));
/*NOTREACHED*/
}
static int
{
int replace = 0;
int vals = 0;
scf_strerror(scf_error()));
scf_strerror(scf_error()));
replace = 1;
break;
}
vals++;
if (vals > 1)
}
if (replace)
return (0);
}
static int
{
return (0);
}
int
{
int c;
if (argc < 2)
usage();
o_hash = 1;
o_delete = 1;
o_overwrite = 1;
usage();
(void) uu_setpname(argv[0]);
argv++;
argc--;
switch (c) {
case 'e':
break;
case 'g':
break;
case 'n':
break;
case 'p':
break;
case '?':
default:
usage();
break;
}
}
if (o_hash) {
usage();
}
usage();
if (o_delete) {
usage();
}
usage();
if (o_overwrite)
usage();
optind));
}