summaryrefslogtreecommitdiff
path: root/usr/src/cmd/svc
diff options
context:
space:
mode:
authorTruong Q. Nguyen <Tony.Q.Nguyen@oracle.com>2010-08-15 15:24:34 -0700
committerTruong Q. Nguyen <Tony.Q.Nguyen@oracle.com>2010-08-15 15:24:34 -0700
commit293e3ab30a546cd932ee22f9d54b3979fcb52095 (patch)
treea509045412a652acdf3f37c300a1fbe5bd617783 /usr/src/cmd/svc
parentd996f1b8696f9ad4e65c250b117c690729ca40bf (diff)
downloadillumos-joyent-293e3ab30a546cd932ee22f9d54b3979fcb52095.tar.gz
6974613 manifest-import can be restructured to allow importing to alternate repository
6974718 svccfg core dump after upgrading to snv_145
Diffstat (limited to 'usr/src/cmd/svc')
-rw-r--r--usr/src/cmd/svc/common/manifest_find.c36
-rw-r--r--usr/src/cmd/svc/common/manifest_find.h3
-rw-r--r--usr/src/cmd/svc/mfstscan/mfstscan.c21
-rw-r--r--usr/src/cmd/svc/milestone/manifest-import82
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg_engine.c7
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg_libscf.c58
6 files changed, 127 insertions, 80 deletions
diff --git a/usr/src/cmd/svc/common/manifest_find.c b/usr/src/cmd/svc/common/manifest_find.c
index 4a47176d72..8933fb5807 100644
--- a/usr/src/cmd/svc/common/manifest_find.c
+++ b/usr/src/cmd/svc/common/manifest_find.c
@@ -240,9 +240,17 @@ process(const char *fn, const struct stat *sp, int ftw_type,
* Note, however, that *arrayp will be set to NULL if the selection is
* empty, and a count of 0 will be returned. In the case of failure, -1
* will be returned and errno will be set.
+ *
+ * This function takes a repository handle argument from the caller and saves
+ * that handle in a thread specific data structure. The thread specific
+ * repository handle is used in process() to communicate with the appropriate
+ * repository. Thus callers should take care of thread safety with respect to
+ * the repository handle. Currently, the two callers of find_manifests are both
+ * single threaded, i.e. svccfg and mfstscan, so thread safety not an issue.
*/
int
-find_manifests(const char *dir, manifest_info_t ***arrayp, int flags)
+find_manifests(scf_handle_t *hndl, const char *dir,
+ manifest_info_t ***arrayp, int flags)
{
mftsd_t *tsdp;
int status = -1;
@@ -254,28 +262,8 @@ find_manifests(const char *dir, manifest_info_t ***arrayp, int flags)
tsdp->tsd_flags = flags;
- /*
- * Create a handle for use by mhast_test_file() if
- * the flag is set to request hash checking be enabled.
- */
if (tsdp->tsd_flags & CHECKHASH) {
- tsdp->tsd_hndl = scf_handle_create(SCF_VERSION);
- if (tsdp->tsd_hndl == NULL) {
- if (scf_error() == SCF_ERROR_NO_MEMORY) {
- errno = ENOMEM;
- } else {
- errno = EINVAL;
- }
- goto out;
- }
- if (scf_handle_bind(tsdp->tsd_hndl) != SCF_SUCCESS) {
- if (scf_error() == SCF_ERROR_NO_RESOURCES) {
- errno = ENOMEM;
- } else {
- errno = EINVAL;
- }
- goto out;
- }
+ tsdp->tsd_hndl = hndl;
}
if (nftw(dir, process, MAX_DEPTH, FTW_MOUNT) == 0) {
@@ -283,10 +271,6 @@ find_manifests(const char *dir, manifest_info_t ***arrayp, int flags)
}
out:
- if (tsdp->tsd_hndl != NULL) {
- (void) scf_handle_unbind(tsdp->tsd_hndl);
- (void) scf_handle_destroy(tsdp->tsd_hndl);
- }
if (status == 0) {
*arrayp = tsdp->tsd_array;
count = tsdp->tsd_count;
diff --git a/usr/src/cmd/svc/common/manifest_find.h b/usr/src/cmd/svc/common/manifest_find.h
index 2f2ab434a9..87b269ca80 100644
--- a/usr/src/cmd/svc/common/manifest_find.h
+++ b/usr/src/cmd/svc/common/manifest_find.h
@@ -31,6 +31,7 @@ extern "C" {
#endif
#include <sys/types.h>
+#include <libscf.h>
#include "manifest_hash.h"
#define CHECKHASH 0x1
@@ -50,7 +51,7 @@ typedef struct manifest_info {
*/
-int find_manifests(const char *, manifest_info_t ***, int);
+int find_manifests(scf_handle_t *, const char *, manifest_info_t ***, int);
void free_manifest_array(manifest_info_t **);
#ifdef __cplusplus
diff --git a/usr/src/cmd/svc/mfstscan/mfstscan.c b/usr/src/cmd/svc/mfstscan/mfstscan.c
index 220bfb2624..70b21903d1 100644
--- a/usr/src/cmd/svc/mfstscan/mfstscan.c
+++ b/usr/src/cmd/svc/mfstscan/mfstscan.c
@@ -18,17 +18,17 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <libintl.h>
+#include <libscf.h>
#include <libuutil.h>
#include <locale.h>
#include <stdio.h>
@@ -63,6 +63,7 @@ main(int argc, char *argv[])
{
manifest_info_t **entry;
manifest_info_t **manifests;
+ scf_handle_t *hndl = NULL;
int i;
int paths_walked = 0;
struct stat sb;
@@ -87,6 +88,13 @@ main(int argc, char *argv[])
if (optind >= argc)
usage();
+ if ((hndl = scf_handle_create(SCF_VERSION)) == NULL)
+ uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"),
+ scf_strerror(scf_error()));
+
+ if (scf_handle_bind(hndl) != SCF_SUCCESS)
+ uu_die(gettext("Couldn't bind to svc.configd.\n"));
+
for (i = optind; i < argc; i++) {
if (tflag) {
char *pname = mhash_filename_to_propname(argv[i],
@@ -106,7 +114,7 @@ main(int argc, char *argv[])
continue;
}
- status = find_manifests(argv[i], &manifests,
+ status = find_manifests(hndl, argv[i], &manifests,
CHECKHASH|CHECKEXT);
if (status < 0) {
uu_warn(gettext("file tree walk of %s encountered "
@@ -129,5 +137,10 @@ main(int argc, char *argv[])
if (!paths_walked)
uu_die(gettext("no paths walked\n"));
+ if (hndl != NULL) {
+ (void) scf_handle_unbind(hndl);
+ (void) scf_handle_destroy(hndl);
+ }
+
return (0);
}
diff --git a/usr/src/cmd/svc/milestone/manifest-import b/usr/src/cmd/svc/milestone/manifest-import
index 705271f2a9..a9bf71ce7e 100644
--- a/usr/src/cmd/svc/milestone/manifest-import
+++ b/usr/src/cmd/svc/milestone/manifest-import
@@ -34,16 +34,37 @@ EMI_SERVICE="svc:/system/early-manifest-import:default"
PROFILE_DIR_SITE="/etc/svc/profile/site"
X=
+ALT_REPOSITORY=
+ALT_MFST_DIR=
early=false
[ "$SMF_FMRI" == "$EMI_SERVICE" ] && early=true
-while getopts "n" opt; do
+
+usage()
+{
+ echo "Usage: /lib/svc/method/manifest-import [-n]" \
+ "[-f repository-file -d manifest-directory]"
+ echo "\nOptions:"
+ echo "-n dryrun"
+ echo "-f and -d specify alternate repository and" \
+ "manifest directory for import\n"
+ exit 2
+}
+
+while getopts "nd:f:" opt; do
case $opt in
n) X=echo;;
- ?) echo "Usage: /lib/svc/method/manifest-import [-n]\n"
- exit 2;;
+ d) ALT_MFST_DIR=$OPTARG;;
+ f) ALT_REPOSITORY=$OPTARG;;
+ ?) usage;;
esac
done
+#
+# Both -f and -d options must be specified together or not specified at all
+#
+[ -n "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ] && usage
+[ -n "$ALT_MFST_DIR" -a -z "$ALT_REPOSITORY" ] && usage
+
function svccfg_apply {
$X /usr/sbin/svccfg apply $1
if [ $? -ne 0 ]; then
@@ -178,16 +199,17 @@ function preserve_system_profiles {
#
function import_manifests {
typeset basedir=$1
+ typeset console_print=$2
typeset logf="/etc/svc/volatile/manifest_import.$$"
rm -f $logf
- nonsite_dirs=`/usr/bin/find $basedir/svc/manifest/* -name site \
+ nonsite_dirs=`/usr/bin/find $basedir/* -name site \
-prune -o -type d -print -prune`
if [ -n "$_MFST_DEBUG" ]; then
nonsite_manifests=`/lib/svc/bin/mfstscan $nonsite_dirs`
- site_manifests=`/lib/svc/bin/mfstscan $basedir/svc/manifest/site`
+ site_manifests=`/lib/svc/bin/mfstscan $basedir/site`
manifests="$nonsite_manifests $site_manifests"
@@ -196,18 +218,24 @@ function import_manifests {
fi
#
- # Attempt of moving the repository to tmpfs. If that doesn't
- # work, reset doswitch so we don't attempt switching back.
+ # Upon boot, attempt to move the repository to tmpfs.
#
- /usr/sbin/svcadm _smf_repository_switch fast
- doswitch=$?
+ if [ -z "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ]; then
+ /usr/sbin/svcadm _smf_repository_switch fast
+ fi
#
# Import the manifests while giving a running display of imports on
# console, and a final count in the logfile.
#
- dirs="$nonsite_dirs $basedir/svc/manifest/site"
- $X /usr/sbin/svccfg import -p /dev/msglog $dirs > $logf 2>&1
+ dirs="$nonsite_dirs"
+ [ -d "$basedir/site" ] && dirs="$dirs $basedir/site"
+
+ if [ "$console_print" = "true" ]; then
+ $X /usr/sbin/svccfg import -p /dev/msglog $dirs > $logf 2>&1
+ else
+ $X /usr/sbin/svccfg import $dirs > $logf 2>&1
+ fi
grep "Loaded .*. smf(5) service descriptions" $logf > /dev/null 2>&1
if [ $? -eq 0 ]; then
@@ -222,7 +250,7 @@ function import_manifests {
fi
cat $logf
- if [ $failures -eq 0 ]; then
+ if [ $failures -eq 0 -a "$console_print" = "true" ]; then
msg="svccfg import warnings. See"
msg="$msg /var/svc/log/system-manifest-import:default.log ."
echo $msg > /dev/msglog
@@ -323,10 +351,10 @@ function handle_upgrade {
# under /etc/svc/profile/site directory.
#
function apply_site_profile {
- typeset prefix="$1/svc/profile"
+ typeset prefix="$1"
[ -f $prefix/site.xml ] && svccfg_apply $prefix/site.xml
- if [ -d $PROFILE_DIR_SITE -a "$1" = "/etc" ]; then
+ if [ -d $PROFILE_DIR_SITE -a "$1" = "/etc/svc/profile" ]; then
svccfg_apply $PROFILE_DIR_SITE
fi
}
@@ -401,33 +429,45 @@ if [ "$early" = "false" ]; then
fi
#
+# If the alternate repository and directory are specified, simply set
+# SVCCFG_REPOSITORY env, run svccfg import on the given directory, and
+# exit.
+#
+if [ -n "$ALT_REPOSITORY" -a -n "$ALT_MFST_DIR" ]; then
+ SVCCFG_REPOSITORY=$ALT_REPOSITORY export SVCCFG_REPOSITORY
+ import_manifests "$ALT_MFST_DIR" false
+ unset SVCCFG_REPOSITORY
+ exit 0
+fi
+
+#
# Call import and apply profiles here
#
if [ "$early" = "true" ]; then
- import_manifests "/lib"
+ import_manifests "/lib/svc/manifest" true
apply_profile
- apply_site_profile "/etc"
+ apply_site_profile "/etc/svc/profile"
else
#
- # Process both /lib/svc and /var/svc
+ # Process both /lib/svc/manifest and /var/svc/manifest
# during late manifest-import
#
# First import the manifests
#
- import_manifests "/lib"
- import_manifests "/var"
+ import_manifests "/lib/svc/manifest" true
+ import_manifests "/var/svc/manifest" true
#
# Apply profiles
#
apply_profile
- apply_site_profile "/etc"
+ apply_site_profile "/etc/svc/profile"
#
# Run the upgrade script
#
handle_upgrade
- apply_site_profile "/var"
+ apply_site_profile "/var/svc/profile"
fi
diff --git a/usr/src/cmd/svc/svccfg/svccfg_engine.c b/usr/src/cmd/svc/svccfg/svccfg_engine.c
index c05100a502..6d8e9d1c9b 100644
--- a/usr/src/cmd/svc/svccfg/svccfg_engine.c
+++ b/usr/src/cmd/svc/svccfg/svccfg_engine.c
@@ -725,7 +725,8 @@ engine_import(uu_list_t *args)
}
/* Get list of manifests that we should import for this path. */
- if ((count = find_manifests(file, &manifests, fm_flags)) < 0) {
+ if ((count = find_manifests(g_hndl, file, &manifests,
+ fm_flags)) < 0) {
if (isdir) {
semerr(gettext("Could not hash directory %s\n"),
file);
@@ -929,7 +930,9 @@ engine_apply(const char *file, int apply_changes)
}
/* Get list of profiles to be applied. */
- if ((profile_count = find_manifests(file, &profiles, fm_flags)) < 0) {
+ if ((profile_count = find_manifests(g_hndl, file, &profiles,
+ fm_flags)) < 0) {
+
if (isdir) {
semerr(gettext("Could not hash directory %s\n"), file);
} else {
diff --git a/usr/src/cmd/svc/svccfg/svccfg_libscf.c b/usr/src/cmd/svc/svccfg/svccfg_libscf.c
index 3c276c02ab..9b04203a07 100644
--- a/usr/src/cmd/svc/svccfg/svccfg_libscf.c
+++ b/usr/src/cmd/svc/svccfg/svccfg_libscf.c
@@ -16207,7 +16207,7 @@ create_manifest_tree(void)
* is supported by multiple manifest files.
*/
for (c = 0; dirs[c]; c++) {
- status = find_manifests(dirs[c], &manifests, CHECKEXT);
+ status = find_manifests(g_hndl, dirs[c], &manifests, CHECKEXT);
if (status < 0) {
uu_warn(gettext("file tree walk of %s encountered "
"error %s\n"), dirs[c], strerror(errno));
@@ -17054,8 +17054,8 @@ lscf_hash_cleanup()
scf_property_t *prop;
scf_value_t *val;
scf_iter_t *iter;
- char *pgname;
- char *mfile;
+ char *pgname = NULL;
+ char *mfile = NULL;
int r;
svc = scf_service_create(g_hndl);
@@ -17148,39 +17148,45 @@ lscf_hash_cleanup()
if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
uu_warn(gettext("Unable to get value from %s\n"),
pgname);
- goto error_handle;
+
+ switch (scf_error()) {
+ case SCF_ERROR_DELETED:
+ case SCF_ERROR_CONSTRAINT_VIOLATED:
+ case SCF_ERROR_NOT_FOUND:
+ case SCF_ERROR_NOT_SET:
+ continue;
+
+ case SCF_ERROR_CONNECTION_BROKEN:
+ r = scferror2errno(scf_error());
+ goto out;
+
+ case SCF_ERROR_HANDLE_MISMATCH:
+ case SCF_ERROR_NOT_BOUND:
+ default:
+ bad_error("scf_property_get_value",
+ scf_error());
+ }
}
- if (scf_value_get_astring(val, mfile, max_scf_value_len + 1) ==
- -1) {
+ if (scf_value_get_astring(val, mfile, max_scf_value_len + 1)
+ == -1) {
uu_warn(gettext("Unable to get astring from %s : %s\n"),
pgname, scf_strerror(scf_error()));
- goto error_handle;
+
+ switch (scf_error()) {
+ case SCF_ERROR_NOT_SET:
+ case SCF_ERROR_TYPE_MISMATCH:
+ continue;
+
+ default:
+ bad_error("scf_value_get_astring", scf_error());
+ }
}
if (access(mfile, F_OK) == 0)
continue;
(void) scf_pg_delete(pg);
-
-error_handle:
- switch (scf_error()) {
- case SCF_ERROR_DELETED:
- case SCF_ERROR_CONSTRAINT_VIOLATED:
- case SCF_ERROR_NOT_FOUND:
- case SCF_ERROR_NOT_SET:
- continue;
-
- case SCF_ERROR_CONNECTION_BROKEN:
- r = scferror2errno(scf_error());
- goto out;
-
- case SCF_ERROR_HANDLE_MISMATCH:
- case SCF_ERROR_NOT_BOUND:
- default:
- bad_error("scf_value_get_astring",
- scf_error());
- }
}
out: