⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfggsc.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
字号:
/* * $Id: cfggsc.c,v 1.1 2001/04/15 11:12:37 ant Exp $ * Copyright (c) 1997 by Matthew Jacob * *	This software is free software; you can redistribute it and/or *	modify it under the terms of the GNU Library General Public *	License as published by the Free Software Foundation; version 2. * *	This software is distributed in the hope that it will be useful, *	but WITHOUT ANY WARRANTY; without even the implied warranty of *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *	Library General Public License for more details. * *	You should have received a copy of the GNU Library General Public *	License along with this software; if not, write to the Free *	Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *	The author may be reached via electronic communications at * *		mjacob@feral.com * *	or, via United States Postal Address * *		Matthew Jacob *		1831 Castro Street *		San Francisco, CA, 94131 */#include <stdio.h>#include <sys/scsi.h>#include <sys/types.h>#include <sys/errno.h>#include <sys/ioctl.h>#include <sys/devinfo.h>#include <sys/device.h>#include <sys/cfgodm.h>#include <cf.h>#include <sys/cfgdb.h>#include <fcntl.h>#include <sys/sysconfig.h>#include <sys/errno.h>#include <sys/device.h>#include <sys/mode.h>#include "gscdds.h"extern mid_t loadext(char *, int, int);static int verbose;static struct gsc_ddsinfo ddsinfo;int main(int a, char **v);static void check_add_sockets(dev_t, int, char *, char *);static int has_driver_get_vpd(char *, int, char *);#define MKNOD_MODE S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH#define	vprintf	if (verbose) printfstatic voiderr_exit(char exitcode){    odm_close_class(CuDv_CLASS);    odm_close_class(PdDv_CLASS);    odm_terminate();    exit(exitcode);}intmain(int a, char **v){    extern char *optarg;    char sstring[256], bufname[256], conns[NAMESIZE], *ptr, *lname;    struct Class *cprp, *cusdev, *predev;    struct CuDvDr dpr, *dprp;    struct CuDv parobj, cusobj, hdobj, *xprp;    struct PdDv preobj;    struct CuAt *attrobj;    int rc, c, errflg, ipl_phase, unit, munit, howmany, lun, domake;    dev_t ctl;    long major;    int *mlist;    mid_t kmid;    struct cfg_dd dd;    lname = NULL;    errflg = 0;    ipl_phase = RUNTIME_CFG;    (void) memset((void *) &ddsinfo, 0, sizeof ddsinfo);    while ((c = getopt(a, v, "l:12v")) != EOF) {	switch (c) {	case 'l':	    if (lname != NULL)		errflg++;	    lname = optarg;	    break;	case 'v':	    verbose++;	    break;	case '1':	    if (ipl_phase != RUNTIME_CFG)		errflg++;	    ipl_phase = PHASE1;	    break;	case '2':	    if (ipl_phase != RUNTIME_CFG)		errflg++;	    ipl_phase = PHASE2;	    break;	default:	    errflg++;	}    }    if (errflg)	exit (E_ARGS);    if (lname == NULL)	exit(E_LNAME);    if (odm_initialize() == -1) {	return (E_ODMINIT);    }    /* lock the database */    if (odm_lock("/etc/objrepos/config_lock",0) == -1)	err_exit(E_ODMLOCK);    /* open customized devices object class */    if ((int)(cusdev = odm_open_class(CuDv_CLASS)) == -1)	err_exit(E_ODMOPEN);    /* search for customized object with this logical name */    sprintf(sstring, "name = '%s'", lname);    rc = (int) odm_get_first(cusdev, sstring, &cusobj);    if (rc == 0) {	/* No CuDv object with this name */	err_exit(E_NOCuDv);    } else if (rc == -1) {	/* ODM failure */	err_exit(E_ODMGET);    }    /* open predefined devices object class */    if ((int)(predev = odm_open_class(PdDv_CLASS)) == -1)	err_exit(E_ODMOPEN);    /* get predefined device object for this logical name */    sprintf(sstring, "uniquetype = '%s'", cusobj.PdDvLn_Lvalue);    rc = (int)odm_get_first(predev, sstring, &preobj);    if (rc == 0) {	/* No PdDv object for this device */	err_exit(E_NOPdDv);    } else if (rc == -1) {	/* ODM failure */	err_exit(E_ODMGET);    }    /* close predefined device object class */    if (odm_close_class(predev) == -1)	err_exit(E_ODMCLOSE);    if (ipl_phase != RUNTIME_CFG)	setleds(preobj.led);    /*     * Now, if the device is already configured, we're     * pretty much done.     */    if (cusobj.status == AVAILABLE) {	/* close customized device object class */	if (odm_close_class(cusdev) == -1)		err_exit(E_ODMCLOSE);	odm_terminate();	return(E_OK);    }    if (cusobj.status != DEFINED) {	vprintf("bad state: %d\n", cusobj.status);	err_exit(E_DEVSTATE);    }    /* get the device's parent object */    sprintf(sstring, "name = '%s'", cusobj.parent);    rc = (int) odm_get_first(cusdev, sstring, &parobj);    if (rc == 0) {	/* Parent device not in CuDv */	err_exit(E_NOCuDvPARENT);    } else if (rc == -1) {	/* ODM failure */	err_exit(E_ODMGET);    }    /* Parent MUST be available to continue */    if (parobj.status != AVAILABLE)	err_exit(E_PARENTSTATE);    /* make sure that no other devices are configured     */    /* at this location                                   */    sprintf(sstring, "parent = '%s' AND location='%s' AND status=%d",	    cusobj.parent, cusobj.location, AVAILABLE);    rc = (int) odm_get_first(cusdev, sstring, &cusobj);    if (rc == -1) {	/* odm failure */	err_exit(E_ODMGET);    } else if (rc) {	/* Error: device config'd at this location */	err_exit(E_AVAILCONNECT);    }    memcpy(conns, cusobj.location, NAMESIZE);    vprintf("now fool with luns: location is %s\n", conns);    ptr = conns;    while (*ptr && ptr < &conns[NAMESIZE])	ptr++;    ptr--;    if (ptr < &conns[1]) {	err_exit(E_BADATTR);    }    lun = *ptr - '0';    vprintf("I see lun %d\n", lun);    if (lun < 0 || lun >= 8)	err_exit(E_INVCONNECT);    ddsinfo.lun = lun;    /*     * Generate Target     */    if (ptr[-1] == ',') {	*(--ptr) = 0;    } else {	*ptr = 0;    }    while (ptr > conns && *ptr != '-')	ptr--;    if (*ptr == '-')	ptr++;    ddsinfo.target = strtol(ptr, (char **) NULL, 0);    vprintf("I see tgt %d ptr = %d\n", ddsinfo.target, ptr - conns);    /*     * Generate dev_t for adapter     */    cprp = odm_open_class(CuDvDr_CLASS) ;    sprintf(sstring, "value3 = %s", cusobj.parent);    rc = (int) odm_get_obj(cprp, sstring, &dpr, TRUE);    if (rc == 0) {	err_exit(E_NOCuDvPARENT);    } else if (rc == -1) {	err_exit(E_ODMGET);    }    ddsinfo.busid = (dev_t) makedev(atoi(dpr.value1), atoi(dpr.value2));    vprintf("I see %d.%d for connecting adapter\n",	major(ddsinfo.busid), minor(ddsinfo.busid));    /*     * Get unit number out of logical name     */    ptr = lname;    ptr += strlen(preobj.prefix);    unit = atoi(ptr);    vprintf("I see %d as unit\n", unit);    /*     * Okay, now that we have the pertinent information that we'll     * need (adapter dev_t, device type, target, lbits, shareable,     * unit number), we can look into actually loading/configuring the     * current driver.     */    (void) sprintf(bufname, "/dev/%s", lname);    /*     * Get or generate major number..     */    if ((major = (long) genmajor(preobj.DvDr)) == -1) {	odm_terminate();	return (E_MAJORNO);    }    vprintf("major is %d\n", major);    /*     * Let's see if this is the first time through. If it's     * the first time through, getminor will return NULL     * or won't have any minors in the list.     */    mlist = getminor(major, &howmany, preobj.DvDr);    vprintf("getminor: %x and howmany %d for %s\n", mlist, howmany,		preobj.DvDr);    domake = 1;    if (mlist != NULL && howmany != 0) {	/*	 * We have a list of minors already.	 * See if we already have the minor	 * we want defined.	 */	for (c = 0; c < howmany; c++) {	    if (mlist[c] == unit) {		vprintf("unit %d already has minor\n", unit);		domake = 0;		break;	    }	}    }    if (domake) {	(void) unlink(bufname);	/*	 * Now create the minor number that will match the unit number.	 * We really don't care whether genminor succeeds, since	 * we've alreay unlinked the device node.	 */	mlist = genminor(preobj.DvDr, major, unit, 1, 1, 1);	if (mlist == (long *) NULL) {	    err_exit(E_MINORNO);	}	vprintf("making %s as %d.%d with minor returned as %d\n",		bufname, major, unit, *mlist);	if (mknod(bufname, MKNOD_MODE, makedev(major, unit))) {	    err_exit(E_MKSPECIAL);	}    } else {	(void) mknod(bufname, MKNOD_MODE, makedev(major, unit));    }    /*     * Load the driver....     */    kmid = loadext(preobj.DvDr, TRUE, FALSE);    if (!kmid) {	err_exit(E_LOADEXT);    }    /*     * And configure the driver...     */    dd.kmid = kmid;    dd.devno = makedev(major, unit);    dd.cmd = CFG_INIT;    dd.ddsptr = (caddr_t) &ddsinfo;    dd.ddslen = sizeof (ddsinfo);    if (sysconfig(SYS_CFGDD, &dd, sizeof (dd)) == CONF_FAIL) {	int saverr = errno;	/*	 * Unload driver...	 */	(void) loadext(preobj.DvDr, FALSE, FALSE);	switch(saverr) {	case ENODEV:		err_exit(E_WRONGDEVICE);		/* NOTREACHED */		break;	case EBUSY:		err_exit(E_AVAILCONNECT);		/* NOTREACHED */		break;	case EINVAL:	default:		err_exit(E_CFGINIT);		/* NOTREACHED */		break;	}    }    /* now mark the device as available */    cusobj.status = AVAILABLE;    if (odm_change_obj(CuDv_CLASS, &cusobj) == -1) {	/*	 * Unconfigure driver (for this instance)...	 */	dd.kmid = 0;	dd.ddsptr = (caddr_t) NULL;	dd.ddslen = (int ) 0;	dd.cmd = CFG_TERM;	(void) sysconfig(SYS_CFGDD, &dd, sizeof (dd));	/*	 * Unload driver...	 */	(void) loadext(preobj.DvDr, FALSE, FALSE);	err_exit (E_ODMUPDATE);    }    (void) odm_terminate();    return (E_OK);}/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -