Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

Mapping Global Section return SS$_NOPRIV

 
SOLVED
Go to solution
JimsanTsai
Advisor

Mapping Global Section return SS$_NOPRIV

Dear Sirs~
I use global section for process data exchange. As follows, create and mapping global section code~

Create Global Section:
unsigned long int prot = 0xFFFF;
sec_flag = SEC$M_EXPREG|SEC$M_WRT|SEC$M_GBL|SEC$M_PERM;
status = sys$crmpsc( &inadr, &retadr,
0, sec_flag,&sec_name,
0, 0,chan,pagcnt, 0, prot, 0 );

Mapping Global Section:
status=sys$mgblsc(&inadr, &retadr, 0, SEC$M_EXPREG|SEC$M_WRT, sec_name, 0, 0);
......
sys$deltva(&retadr, 0, 0);

My Question:
In general, mapping global section return SS$_NORMAL, but when I use multithread or n process to map the same global section, I received SS$_NOPRIV, but not every time have received, is irregular.
Thanks for your help ~
13 REPLIES 13
Hein van den Heuvel
Honored Contributor

Re: Mapping Global Section return SS$_NOPRIV

Well, your protection mask is -1, so has all bits sets. This DENIES access to other processes. According to the doc: "Cleared bits indicate that read, write, execute, and delete access, in that order, are granted to the particular category of user."
So you will get a NOPRIV message whenever an other process has 'the same' section created already. (same = same gsdnam, same UIC group)

hth,
Hein.

Hoff
Honored Contributor

Re: Mapping Global Section return SS$_NOPRIV

Once you get the protections sorted, you'll be dealing with memory barriers and interlocked bitlocks; with coordinating the shared memory and the memory caches. (If you don't know from bitlocks and barriers and caches, well, you're going to learn.) These cases tend to be subtle, tend to be more likely on SMP and multicore boxes, and usually arise only under load.

Using RMS files is easier in these respects and (with global buffers enabled) is also very fast. It's also far easier to maintain.

JimsanTsai
Advisor

Re: Mapping Global Section return SS$_NOPRIV

Dear Hein~
Thanks for your reply~I've change my code as followsï¼ but I got the same return code(SS$_NOPRIV),I would like to ask what need to pay attention to it.I have this problem a long time, thank for your help~
----------------------------------------
Create Global Section:
unsigned long int prot = 0x0000;
sec_flag = SEC$M_EXPREG|SEC$M_WRT|SEC$M_GBL|SEC$M_PERM;
status = sys$crmpsc( &inadr, &retadr,
PSL$C_USER, sec_flag,&sec_name,
0, 0,chan,pagcnt, 0, prot, 0 );
----------------------------------------
Mapping Global Section:
status=sys$mgblsc(&inadr, &retadr, PSL$C_USER, SEC$M_EXPREG|SEC$M_WRT, sec_name, 0, 0);
......
sys$deltva(&retadr, 0, 0);
Hein van den Heuvel
Honored Contributor

Re: Mapping Global Section return SS$_NOPRIV

On the $mgblsc call the example suggests that the name argument sec_name is not passed as address, contrary to the $crmpsc example.
Different definitions or an error?

Which of the two calls returns the NPRIV some times?
Does the $crmpsc return SS$_CREATED? (Succes)
Are the two calls happening from the same program or it there some sort of client/server notion? Do all programs have the same privilige, or does the one calling $crmpsc have more?

Like Hoff indicates, if you are already having trouble at this level then the prospect for the more subttle problems are worrysome.

Please review the communication requirements and consider the various alternatives such as sockets, OpenVMS mailboxes, SYS$ICC services,

Regards,
Hein.

JimsanTsai
Advisor

Re: Mapping Global Section return SS$_NOPRIV

Dear Hein~
Thanks for your reply again~
&sec_name is right!!-> I correct it.
Let me explain the logic of the program,I have the AP1ã AP2 &AP3.
AP1 create global section and return SS$_CREATED(1561).
AP2 and AP3 mapping global section with while loop as follows, and sometimes I get return code=SS$_NOPRIV(36).(AP2&AP3 running at the same time)
Before I execute 3 APs, I set proc/priv=all, and AP1&AP2&AP3 have the same privilige.

----------------------------------------
1.Create Global Section(AP1):
va_range inadr,retadr;
unsigned long int prot = 0x0000;
sec_flag = SEC$M_EXPREG|SEC$M_WRT|SEC$M_GBL|SEC$M_PERM;
$DESCRIPTOR (sec_name, szSectionName);
status = sys$crmpsc( &inadr, &retadr,
PSL$C_USER, sec_flag,&sec_name,
0, 0,chan,pagcnt, 0, prot, 0 );
----------------------------------------
2.Mapping Global Section(AP2&AP3):
va_range inadr,retadr;
$DESCRIPTOR (sec_name, szSectionName);
while(1)
{
status=sys$mgblsc(&inadr, &retadr, PSL$C_USER, SEC$M_EXPREG|SEC$M_WRT, &sec_name, 0, 0);
if(status==SS$_NOPRIV)
write log;

.....
sys$deltva(&retadr, 0, 0);
}
----------------------------------------
I would like to ask what advice do you have??
Thanks~
Hoff
Honored Contributor
Solution

Re: Mapping Global Section return SS$_NOPRIV

I'd suggest not using global sections here.

I'd suggest the use of a shared RMS file. With global buffers enabled. (That's basically what you're writing for yourself here, too. But the RMS support is already designed, debugged and working, and it is cluster-aware.)

An RMS file will deal (correctly and consistently) with aspects of this that you've not yet seen (but will see), and that are orders of magnitude more difficult to code and debug than the simple synchronization issues you are seeing here.

Start simple. Get it working with a file. Then find out if you need to tune or to code for yet higher performance.

As for your error, the file or section is protected against access here. When combined with the reference to SET PROCESS /PRIVILEGE=ALL implies that these are created processes, and are not being created with the privileges enabled. Or the sections are (as is typical) protected against access.

The while loop mentioned is a form of polling, and that style of programming (in its simplest form) rarely works reliably within the memory mapped by a section file; basic polling both consumes resources and can encounter stale data from in the caches. It's entirely possible for a bit to never be seen as set within a processor cache, while another of your processes has set that same bit out in main memory "behind" the while loop; the application will remain stalled while loop spinning on the bit.

Here are some details and links to shared memory and memory barrier discussions.

http://labs.hoffmanlabs.com/node/407
http://labs.hoffmanlabs.com/node/1198
http://h71000.www7.hp.com/wizard/wiz_6984.html
JimsanTsai
Advisor

Re: Mapping Global Section return SS$_NOPRIV

Dear Hoff~
Thanks for your suggestion~

I would like to ask several questions:
(1)In this program behavior, I received SS$_NOPRIV sometimes. It's normal? or it's OpenVMS protected itself?

(2)I tried RMS File before, when I rapidly access the same RMS File, it consumes system I/O and CPU% raised. So I used permanent global section to avoid this issue. Any solutions in this case?

(3)I'm a beginner of OpenVMS, I used Share Memory Lib (shmget,shmat,shmdt) before. Memory barrier & bitlocks are new words for me. If I understanding them, so I can avoid get SS$_NOPRIV(In while loop ase)?
Jur van der Burg
Respected Contributor

Re: Mapping Global Section return SS$_NOPRIV

"(1)In this program behavior, I received SS$_NOPRIV sometimes. It's normal? or it's OpenVMS protected itself?"

It's 99.99% sure a programming bug from your side. $mgblsc can return this if the INADR argument is in system space. How do you initialize that location?

"(2)I tried RMS File before, when I rapidly access the same RMS File, it consumes system I/O and CPU% raised. So I used permanent global section to avoid this issue. Any solutions in this case?"

There's way too little info to propose a fix. It may very well that you did it wrong, and without any code sample it's hard to guess.


"(3)I'm a beginner of OpenVMS, I used Share Memory Lib (shmget,shmat,shmdt) before. Memory barrier & bitlocks are new words for me. If I understanding them, so I can avoid get SS$_NOPRIV(In while loop ase)?"

If you are not famliar with these terms them reconsider that you want to use sections. This has nothing to do with the nopriv error, but it takes care of proper synchroniszation between multiple accessors. See Hoff's comments above.

Jur.
Hoff
Honored Contributor

Re: Mapping Global Section return SS$_NOPRIV


>(1)In this program behavior, I received SS$_NOPRIV sometimes. It's normal? or it's OpenVMS protected itself?

It is almost certain that your code contains one or more coding bugs. This particular OpenVMS code and these APIs have seen years of broad use, both within the operating system and across many application programs. Bugs do happen here, but they are very rare.

>(2)I tried RMS File before, when I rapidly access the same RMS File, it consumes system I/O and CPU% raised. So I used permanent global section to avoid this issue. Any solutions in this case?

I suspect your assumptions are wrong. Use an RMS file, and enable and use larger caches. Tune your file accesses in your application. We can help make your RMS code faster here, too, but we'll need to know what sort of information you're storing, and what access patterns are present.

RMS and other hierarchical databases, and relational databases, all has to do exactly what you need to do to implement shared storage as part of implementing RMS caching or database caching. Which means that RMS or the database has to deal with all of what you need to deal with. And RMS has had some very experienced authors and maintainers and thirty years of testing. Which means that you're rewriting RMS or database caching.

>(3)I'm a beginner of OpenVMS,

Experienced folks can almost always spot newbies. We were all newbies once, after all.

> I used Share Memory Lib (shmget,shmat,shmdt) before. Memory barrier & bitlocks are new words for me.

These C library calls are among the most hazardous around, and the least portable. Sure, the basic functions are portable, but you're right in the middle of an area of processor architecture and processor memory management design that is extremely architecture-specific.

Older and slower and simpler systems and processor architectures have different requirements around shared memory than do some of the more aggressively-cached multiprocessors.

The processors you will be dealing with are aggressively cached.

You WILL need to learn what I am referencing with interlocked primitives, or your code WILL fail. If not properly and entirely designed and implemented, there WILL be weird run-time bugs. Really weird.

I wrote various parts of the relevant memory management chapter in the Programming Concepts manual. That's the "Synchronizing Data Access and Program Operations" and that chapter is available here:

http://h71000.www7.hp.com/doc/82final/5841/5841pro_017.html#synch_access_data

Whether you use the various mem* calls available in the OpenVMS C library or the system services, you will still typically have to deal with this synchronization stuff with shared memory. (For the real details, you'll need to read the processor architecture manuals.)

> If I understanding them, so I can avoid get SS$_NOPRIV(In while loop ase)?

SS$_NOPRIV is almost certainly a bug in your code.

The synchronization design requirements and (when not correctly implemented) the problems that can arise here are orders of magnitude more difficult to find and debug than is a synchronous SS$_NOPRIV error. Massively more difficult than the SS$_NOPRIV.

I would strongly recommend using a file here. Or tuning and using a file. Or use a database. I usually discourage folks from using shared memory outside of extreme edge cases, as you're re-implementing what the existing constructs and interfaces and libraries provide (which has I/O and CPU costs, and development and support costs) with and little benefit over the existing APIs and mechanisms.

JimsanTsai
Advisor

Re: Mapping Global Section return SS$_NOPRIV

Dear Sirs ~
Thank for your help~
I got a pdf file from google today, and modify previous code (sys$mgblsc's inadr) as follows, then SS$_NOPRIV never received.
---------------------------------
long inaddr[2];
char _align(page) buffer[1024];
inaddr[0]=&buffer[0];
inaddr[1]=&buffer[0];

status=sys$mgblsc(inaddr, &retadr, 0, SEC$M_EXPREG|SEC$M_WRT, sec_name, 0, 0);
---------------------------------
I would like to appreciate for everyone to help me. Thanks~
Jur van der Burg
Respected Contributor

Re: Mapping Global Section return SS$_NOPRIV

So, it was just as I expected, you passed uninitialized data to sys$mgblsc. If bit 31 is set in either of the 2 addresses that inadr points at you will get this error.

Jur.
Hoff
Honored Contributor

Re: Mapping Global Section return SS$_NOPRIV

A bit shorter:

inaddr[0] = inaddr[1] = buffer;

JimsanTsai
Advisor

Re: Mapping Global Section return SS$_NOPRIV

Thanks for help~