sw_cmp.c revision 8cd327d5cbf74ddf7659863fac9475546ccd58ce
/*
* 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"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#include <libintl.h>
#include <libzonecfg.h>
#include "zoneadm.h"
/*
* Find the specified package in the sw inventory on the handle and check
* if the version matches what is passed in.
* Return 0 if the packages match
* 1 if the package is found but we have a version mismatch
* -1 if the package is not found
*/
static int
char *return_vers, int vers_size)
{
int res = -1;
struct zone_pkgtab pkgtab;
gettext("unable to enumerate packages\n"));
return (Z_ERR);
}
continue;
res = 0;
break;
}
res = 1;
break;
}
(void) zonecfg_endpkgent(handle);
return (res);
}
/*
* Used in software comparisons to check the packages between the two zone
* handles. The packages have to match or we print a message telling the
* user what is out of sync. If flag has SW_CMP_SRC this tells us the first
* handle is the source machine global zone. This is used to enable the
* right messages to be printed and also to enable extra version checking
* that is not needed for the opposite comparison.
*/
static int
{
int err;
char other_vers[ZONE_PKG_VERSMAX];
struct zone_pkgtab pkgtab;
gettext("unable to enumerate packages\n"));
return (Z_ERR);
}
!= 0) {
if (flag & SW_CMP_SILENT)
break;
/* LINTED E_SEC_PRINTF_VAR_FMT */
}
if (err < 0)
(flag & SW_CMP_SRC) ?
gettext("\t%s: not installed\n\t\t(%s)\n") :
gettext("\t%s (%s)\n"),
else if (flag & SW_CMP_SRC)
"\t%s: version mismatch\n\t\t(%s)"
"\n\t\t(%s)\n"),
}
}
(void) zonecfg_endpkgent(handle1);
return (res);
}
/*
* Find the specified patch in the sw inventory on the handle and check
* if the version matches what is passed in.
* Return 0 if the patches match
* 1 if the patches is found but we have a version mismatch
* -1 if the patches is not found
*/
static int
char *return_vers, int vers_size)
{
int res = -1;
struct zone_patchtab patchtab;
gettext("unable to enumerate patches\n"));
return (Z_ERR);
}
char *p;
*p++ = '\0';
else
p = "";
continue;
if (strcmp(patch_vers, p) == 0) {
res = 0;
break;
}
/*
* Keep checking. This handles the case where multiple
* versions of the same patch is installed.
*/
res = 1;
}
(void) zonecfg_endpatchent(handle);
return (res);
}
/*
* Used in software comparisons to check the patches between the two zone
* handles. The patches have to match or we print a message telling the
* user what is out of sync. If flag has SW_CMP_SRC this tells us the first
* handle is the source machine global zone. This is used to enable the
* right messages to be printed. For patches we do need to compare the
* versions both ways and print the right header and error message. This
* is because it is possible to have multiple versions of a patch installed
* and we need to detect the case where the target has a newer version of
* a patch in addition to the version that was installed on the source.
*/
static int
{
int err;
char other_vers[MAXNAMELEN];
struct zone_patchtab patchtab;
gettext("unable to enumerate patches\n"));
return (Z_ERR);
}
char *patch_vers;
*patch_vers++ = '\0';
else
patch_vers = "";
if (flag & SW_CMP_SILENT)
break;
if (do_header) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
}
if (err < 0)
(flag & SW_CMP_SRC) ?
gettext("\t%s-%s: not installed\n") :
gettext("\t%s-%s\n"),
else
gettext("\t%s: version mismatch\n\t\t(%s) "
}
}
(void) zonecfg_endpatchent(handle1);
return (res);
}
/*
* Compare the software on the local global zone and source system global
* zone. Used when we are trying to attach a zone during migration or
* when checking if a ZFS snapshot is still usable for a ZFS clone.
* l_handle is for the local system and s_handle is for the source system.
* These have a snapshot of the appropriate packages and patches in the global
* zone for the two machines.
* The functions called here can print any messages that are needed to
* inform the user about package or patch problems.
* The flag parameter controls how the messages are printed. If the
* SW_CMP_SILENT bit is set in the flag then no messages will be printed
* but we still compare the sw and return an error if there is a mismatch.
*/
int
{
char *hdr;
/*
* Check the source host for pkgs (and versions) that are not on the
* local host.
*/
if (!(flag & SW_CMP_SILENT))
"are inconsistent with this system:\n");
/*
* Now check the local host for pkgs that were not on the source host.
* We already handled version mismatches in the loop above.
*/
if (!(flag & SW_CMP_SILENT))
"not installed on the source system:\n");
/*
* Check the source host for patches that are not on the local host.
*/
if (!(flag & SW_CMP_SILENT))
"are inconsistent with this system:\n");
/*
* Check the local host for patches that were not on the source host.
* We already handled version mismatches in the loop above.
*/
if (!(flag & SW_CMP_SILENT))
"not installed on the source system:\n");
return (res);
}