Thanks Arjen, I hadn't previously looked into libusb, but is there a reason why the filename member of usb_device is't matched on? On linux, they may not be unique or deterministic in theory --- but in practice they are, particularly for servers where you're not constantly plugging in and out devices.
Am I missing something in the logic, or do I just have an unusual case? I've written up a patch that works for me -- it pulls out the filename from the usb_device, and matches it with a file= parameter for ups.conf. I'd guess that a better long-term solution would be to have upsdrv listen to hal for ups's that are connecting -- but that would obviously be a lot more work, and it requires mucking up the server with hal stuff. Regards, Alex Peyser On Thursday 05 June 2008 08:01:32 am [EMAIL PROTECTED] wrote: > Message: 1 > Date: Wed, 4 Jun 2008 19:22:56 -0400 > From: Alex Peyser <[EMAIL PROTECTED]> > Subject: [Nut-upsuser] Multiple ups/Belkin 1500VA no serial number > To: [email protected] > Message-ID: <[EMAIL PROTECTED]> > Content-Type: text/plain; charset="us-ascii" > > I'm setting up a cluster with multiple ups's using nut 2.2. The ups's are > Belkin 1500 (ID 050d:0751) which don't appear to report a serial number. Is > there any other way I can setup ups.conf with multiple of these ups over > usb on Linux? > > If I just setup the vendor and product id's, every definition in ups.conf > appears to match the first one, and therefore all of them but the first one > fails. Is there some undocumented matcher I can use to distinguish them, or > some flag to tell the ups to simple skip ups that have already been > matched? > > Regards, > Alex Peyser > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: not available > Type: application/pgp-signature > Size: 189 bytes > Desc: This is a digitally signed message part. > Url : > http://lists.alioth.debian.org/pipermail/nut-upsuser/attachments/20080604/8 >597976d/attachment-0001.pgp > > ------------------------------ > > Message: 2 > Date: Thu, 5 Jun 2008 08:45:11 +0200 (CEST) > From: "Arjen de Korte" <[EMAIL PROTECTED]> > Subject: Re: [Nut-upsuser] Multiple ups/Belkin 1500VA no serial number > To: "Alex Peyser" <[EMAIL PROTECTED]> > Cc: [email protected] > Message-ID: > <[EMAIL PROTECTED]> > Content-Type: text/plain;charset=iso-8859-1 > > > I'm setting up a cluster with multiple ups's using nut 2.2. The ups's are > > Belkin 1500 (ID 050d:0751) which don't appear to report a serial number. > > Is there any other way I can setup ups.conf with multiple of these ups > > over usb on Linux? > > > > If I just setup the vendor and product id's, every definition in ups.conf > > appears to match the first one, and therefore all of them but the first > > one fails. Is there some undocumented matcher I can use to distinguish > > them, or some flag to tell the ups to simple skip ups that have already > > been matched? > > The 'libusb' library doesn't provide the physical port number these > devices are connected to, so if you can't tell them apart through the > regular expressions, this isn't possible. Which in your case means, that > each UPS must have its own USB *root* device, as the only difference will > be the USB bus they're connected to. You can't monitor two devices that > are looking identical from the same USB bus. > > Best regards, Arjen
diff -Naur nut-2.2.2/drivers/libshut.c nut-2.2.2-new/drivers/libshut.c
--- nut-2.2.2/drivers/libshut.c 2007-12-16 14:46:35.000000000 -0500
+++ nut-2.2.2-new/drivers/libshut.c 2008-06-05 11:14:12.000000000 -0400
@@ -347,12 +347,14 @@
free(curDevice->Product);
free(curDevice->Serial);
free(curDevice->Bus);
+ free(curDevice->File);
memset(curDevice, '\0', sizeof(*curDevice));
curDevice->VendorID = dev_descriptor->idVendor;
curDevice->ProductID = dev_descriptor->idProduct;
curDevice->Vendor = strdup("MGE UPS SYSTEMS");
curDevice->Bus = strdup("serial");
+ curDevice->File = strdup("serial");
if (dev_descriptor->iProduct) {
ret = shut_get_string_simple(*upsfd, dev_descriptor->iProduct, string, 0x25);
@@ -384,6 +386,7 @@
upsdebugx(2, "- Product: %s", curDevice->Product);
upsdebugx(2, "- Serial Number: %s", curDevice->Serial);
upsdebugx(2, "- Bus: %s", curDevice->Bus);
+ upsdebugx(2, "- File: %s", curDevice->File);
upsdebugx(2, "Device matches");
/* Get HID descriptor */
diff -Naur nut-2.2.2/drivers/libshut.h nut-2.2.2-new/drivers/libshut.h
--- nut-2.2.2/drivers/libshut.h 2007-12-16 14:46:35.000000000 -0500
+++ nut-2.2.2-new/drivers/libshut.h 2008-06-05 11:19:20.000000000 -0400
@@ -31,7 +31,7 @@
/*!
* SHUTDevice_t: Describe a SHUT device. This structure contains exactly
- * the 5 pieces of information by which a SHUT device identifies
+ * the 6 pieces of information by which a SHUT device identifies
* itself, so it serves as a kind of "fingerprint" of the device. This
* information must be matched exactly when reopening a device, and
* therefore must not be "improved" or updated by a client
@@ -45,6 +45,7 @@
char* Product; /*!< Device's Product Name */
char* Serial; /* Product serial number */
char* Bus; /* Bus name, e.g. "003" */
+ char* File; /* File name, e.g. "003" */
} SHUTDevice_t;
/*!
diff -Naur nut-2.2.2/drivers/libusb.c nut-2.2.2-new/drivers/libusb.c
--- nut-2.2.2/drivers/libusb.c 2007-12-11 15:15:47.000000000 -0500
+++ nut-2.2.2-new/drivers/libusb.c 2008-06-05 11:12:56.000000000 -0400
@@ -131,11 +131,13 @@
free(curDevice->Product);
free(curDevice->Serial);
free(curDevice->Bus);
+ free(curDevice->File);
memset(curDevice, '\0', sizeof(*curDevice));
curDevice->VendorID = dev->descriptor.idVendor;
curDevice->ProductID = dev->descriptor.idProduct;
curDevice->Bus = strdup(bus->dirname);
+ curDevice->File = strdup(dev->filename);
if (dev->descriptor.iManufacturer) {
ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer,
@@ -167,6 +169,8 @@
upsdebugx(2, "- Product: %s", curDevice->Product ? curDevice->Product : "unknown");
upsdebugx(2, "- Serial Number: %s", curDevice->Serial ? curDevice->Serial : "unknown");
upsdebugx(2, "- Bus: %s", curDevice->Bus ? curDevice->Bus : "unknown");
+ upsdebugx(2, "- File: %s", curDevice->File ? curDevice->File : "unknown");
+
upsdebugx(2, "Trying to match device");
for (m = matcher; m; m=m->next) {
@@ -482,6 +486,10 @@
return 0;
}
#endif
+ if (strcmp_null(hd->File, data->File) != 0) {
+ return 0;
+ }
+
return 1;
}
@@ -517,6 +525,7 @@
#ifdef DEBUG_EXACT_MATCH_BUS
data->Bus = hd->Bus ? strdup(hd->Bus) : NULL;
#endif
+ data->File = hd->File ? strdup(hd->File) : NULL;
*matcher = m;
return 0;
@@ -539,6 +548,7 @@
#ifdef DEBUG_EXACT_MATCH_BUS
free(data->Bus);
#endif
+ free(data->File);
free(data);
free(matcher);
}
@@ -691,13 +701,18 @@
if (r != 1) {
return r;
}
+
+ r = match_regex(data->regex[6], hd->File);
+ if (r != 1) {
+ return r;
+ }
return 1;
}
/* constructor: create a regular expression matcher. This matcher is
- * based on six regular expression strings in regex_array[0..5],
+ * based on seven regular expression strings in regex_array[0..6],
* corresponding to: vendorid, productid, vendor, product, serial,
- * bus. Any of these strings can be NULL, which matches
+ * bus, file. Any of these strings can be NULL, which matches
* everything. Cflags are as in regcomp(3). Typical values for cflags
* are REG_ICASE (case insensitive matching) and REG_EXTENDED (use
* extended regular expressions). On success, return 0 and store the
@@ -727,7 +742,7 @@
m->privdata = (void *)data;
m->next = NULL;
- for (i=0; i<6; i++) {
+ for (i=0; i<7; i++) {
r = compile_regex(&data->regex[i], regex[i], cflags);
if (r == -2) {
r = i+1;
diff -Naur nut-2.2.2/drivers/libusb.h nut-2.2.2-new/drivers/libusb.h
--- nut-2.2.2/drivers/libusb.h 2007-12-16 14:46:35.000000000 -0500
+++ nut-2.2.2-new/drivers/libusb.h 2008-06-05 11:18:22.000000000 -0400
@@ -52,6 +52,7 @@
char* Product; /*!< Device's Product Name */
char* Serial; /* Product serial number */
char* Bus; /* Bus name, e.g. "003" */
+ char* File; /* File name, e.g. "003" */
} USBDevice_t;
/*!
diff -Naur nut-2.2.2/drivers/usbhid-ups.c nut-2.2.2-new/drivers/usbhid-ups.c
--- nut-2.2.2/drivers/usbhid-ups.c 2008-04-22 14:04:43.000000000 -0400
+++ nut-2.2.2-new/drivers/usbhid-ups.c 2008-06-05 11:15:41.000000000 -0400
@@ -73,7 +73,7 @@
/* Global vars */
static HIDDevice_t *hd = NULL;
-static HIDDevice_t curDevice = { 0x0000, 0x0000, NULL, NULL, NULL, NULL };
+static HIDDevice_t curDevice = { 0x0000, 0x0000, NULL, NULL, NULL, NULL, NULL};
static HIDDeviceMatcher_t *subdriver_matcher = NULL;
#ifndef SHUT_MODE
static HIDDeviceMatcher_t *exact_matcher = NULL;
@@ -699,6 +699,7 @@
addvar(VAR_VALUE, "vendorid", "Regular expression to match UPS Manufacturer numerical ID (4 digits hexadecimal)");
addvar(VAR_VALUE, "productid", "Regular expression to match UPS Product numerical ID (4 digits hexadecimal)");
addvar(VAR_VALUE, "bus", "Regular expression to match USB bus name");
+ addvar(VAR_VALUE, "file", "Regular expression to match USB file name");
addvar(VAR_VALUE, "matching", "Use 'normal' or 'delayed' matching");
addvar(VAR_FLAG, "explore", "Diagnostic matching of unsupported UPS");
#endif
@@ -864,7 +865,7 @@
subdriver_matcher = device_path;
#else
- char *regex_array[6];
+ char *regex_array[7];
matching_lkp_t *key;
upsdebugx(1, "upsdrv_initups...");
@@ -883,6 +884,7 @@
regex_array[3] = getval("product");
regex_array[4] = getval("serial");
regex_array[5] = getval("bus");
+ regex_array[6] = getval("file");
ret = USBNewRegexMatcher(®ex_matcher, regex_array, REG_ICASE | REG_EXTENDED);
switch(ret)
@@ -955,6 +957,7 @@
free(curDevice.Product);
free(curDevice.Serial);
free(curDevice.Bus);
+ free(curDevice.File);
#endif
}
@@ -1096,6 +1099,7 @@
upsdebugx(2, "- Product: %s", hd->Product ? hd->Product : "unknown");
upsdebugx(2, "- Serial Number: %s", hd->Serial ? hd->Serial : "unknown");
upsdebugx(2, "- Bus: %s", hd->Bus ? hd->Bus : "unknown");
+ upsdebugx(2, "- File: %s", hd->File ? hd->File : "unknown");
for (m = regex_matcher; m; m = m->next) {
ret = matches(m, hd);
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Nut-upsuser mailing list [email protected] http://lists.alioth.debian.org/mailman/listinfo/nut-upsuser

