blob: b115eb846656b17b49c960d7f55a359dcb280f7d [file] [log] [blame]
/*
* Copyright (c) 2000-2001 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <xfs/xfs.h>
#include <xfs/jdm.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/dir.h>
#include <assert.h>
#include <string.h>
#include <uuid/uuid.h>
#include "config.h"
#include "types.h"
#include "mlog.h"
#include "inv_priv.h"
/*----------------------------------------------------------------------*/
/* */
/* */
/* */
/*----------------------------------------------------------------------*/
int
fstab_getall(invt_fstab_t **arr, invt_counter_t **cnt, int *numfs,
inv_oflag_t forwhat)
{
int fd;
fd = open (INV_FSTAB, INV_OFLAG(forwhat));
if (fd < 0)
return -1; /* if ENOENT, fstab_put_entry will CREAT */
INVLOCK(fd, LOCK_EX);
if ((*numfs = GET_ALLHDRS_N_CNTS_NOLOCK(fd, (void**) arr,
(void **)cnt,
sizeof(invt_fstab_t),
sizeof(invt_counter_t))
) < 0) {
mlog(MLOG_NORMAL | MLOG_INV, _(
"INV: couldn't get fstab headers\n"));
}
#ifdef INVT_DEBUG
mlog(MLOG_NITTY | MLOG_INV, "INV: number of filesystems in fstab %d\n",
*numfs);
#endif
/* fstab is left locked EX on exit. The caller takes does
the unlocking */
return fd;
}
/*----------------------------------------------------------------------*/
/* */
/* */
/* caller takes the responsibility of calling this only when the FSTAB_ */
/* UPDATED flag in the inv_idbtoken is off, and also of updating the */
/* flag upon successful return from put_fstab_entry. */
/*----------------------------------------------------------------------*/
int
fstab_put_entry(uuid_t *fsidp, char *mntpt, char *dev, inv_oflag_t forwhat)
{
int numfs, i, fd;
invt_counter_t *cnt;
invt_fstab_t *arr;
int rval = 1;
assert(forwhat != INV_SEARCH_ONLY);
/* fd is locked on succesful return */
fd = fstab_getall(&arr, &cnt, &numfs, forwhat);
if (fd < 0) {
if (errno != ENOENT) {
return -1;
}
if ((fd = open(INV_FSTAB, INV_OFLAG(forwhat) | O_CREAT, S_IRUSR|S_IWUSR))
< 0) {
INV_PERROR (INV_FSTAB);
return -1;
}
INVLOCK(fd, LOCK_EX);
fchmod(fd, INV_PERMS);
cnt = (invt_counter_t *) malloc(sizeof (invt_counter_t));
cnt->ic_maxnum = -1;
cnt->ic_curnum = 0;
cnt->ic_vernum = INV_VERSION;
} else if (numfs > 0) {
for (i = 0; i < numfs; i++) {
if (uuid_compare(*fsidp, arr[i].ft_uuid) == 0) {
/* if ((STREQL(arr[i].ft_mountpt, mntpt)) &&
(STREQL(arr[i].ft_devpath, dev)))
*/
free (arr);
free (cnt);
close(fd);
return 1;
}
}
/* entry not found. just follow thru to create a new one */
free (arr);
}
/* make a new fstab entry and insert it at the end. the table
is locked EXclusively at this point */
{
invt_fstab_t ent;
off64_t hoff;
memcpy(&ent.ft_uuid, fsidp, sizeof(uuid_t));
strcpy(ent.ft_mountpt, mntpt);
strcpy(ent.ft_devpath, dev);
/* increase the number of entries first */
#ifdef INVT_DEBUG
mlog(MLOG_NITTY | MLOG_INV,"INV: putting new fstab entry for %s ....\n",
mntpt);
#endif
cnt->ic_curnum++;
hoff = (off64_t) (sizeof(invt_counter_t) +
(size_t)(cnt->ic_curnum - 1) *
sizeof(invt_fstab_t));
rval = PUT_COUNTERS(fd, cnt);
if (rval > 0) {
rval = PUT_REC_NOLOCK(fd, &ent, sizeof(ent), hoff);
}
}
INVLOCK(fd, LOCK_UN);
free (cnt);
close (fd);
return rval;
}
int
fstab_get_fname(void *pred,
char *fname,
inv_predicate_t bywhat,
inv_oflag_t forwhat)
{
uuid_t *uuidp = 0;
char uuidstr[UUID_STR_LEN + 1];
invt_fstab_t *arr;
if (bywhat != INV_BY_UUID) {
int numfs, i, fd;
invt_counter_t *cnt;
/* on sucessful return fd is locked */
fd = fstab_getall(&arr, &cnt, &numfs, forwhat);
if (fd < 0)
return -1;
if (numfs <= 0) {
mlog(MLOG_NORMAL | MLOG_INV, _(
"INV: No recorded filesystems in"
" inventory's fstab.\n"));
return -1;
}
INVLOCK(fd, LOCK_UN);
close (fd);
free (cnt); /* we dont need it */
/* first get hold of the uuid for this mount point/device */
for (i = 0; i < numfs; i++) {
if ((bywhat == INV_BY_MOUNTPT &&
(STREQL(arr[i].ft_mountpt, pred))) ||
(bywhat == INV_BY_DEVPATH &&
(STREQL(arr[i].ft_devpath, pred)))) {
uuidp = &arr[i].ft_uuid;
break;
}
}
#ifdef INVT_DEBUG
if (!uuidp)
mlog(MLOG_DEBUG | MLOG_INV,"INV: get_fname: unable to find %s"
" in the inventory\n", (char *)pred);
#endif
} else {
uuidp = (uuid_t *)pred;
}
if (!uuidp)
return -1;
uuid_unparse(*uuidp, uuidstr);
strncpy (fname, INV_DIRPATH, INV_STRLEN);
strcat (fname, "/");
strcat (fname, uuidstr);
if (bywhat != INV_BY_UUID)
free (arr);
assert((int) strlen(fname) < INV_STRLEN);
return 1;
}
void
fstab_DEBUG_print(invt_fstab_t *arr, int num)
{
int i;
char str[UUID_STR_LEN + 1];
mlog(MLOG_NORMAL | MLOG_INV, _("\n\n--------- fstab ------------\n"));
for (i = 0; i < num; i++) {
printf(_("Mount\t%s\n"), arr[i].ft_mountpt);
printf(_("Dev\t%s\n"), arr[i].ft_devpath);
uuid_unparse(arr[i].ft_uuid, str);
printf(_("FSid\t%s\n\n"), str);
}
mlog(MLOG_NORMAL | MLOG_INV, "\n---------========------------\n");
}